From 2ab47b08bd80bcf67dd70ba413971efa8e4b82f1 Mon Sep 17 00:00:00 2001 From: Kien Nguyen Date: Fri, 5 Jul 2024 22:01:35 -0700 Subject: [PATCH] ivy-completion-in-region: correctly calculate the length of replacement for file category --- ivy-test.el | 8 +++++++- ivy.el | 23 ++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ivy-test.el b/ivy-test.el index 87dda185..1afc4d8f 100644 --- a/ivy-test.el +++ b/ivy-test.el @@ -1012,6 +1012,11 @@ Since `execute-kbd-macro' doesn't pick up a let-bound `default-directory'.") #("test/" 0 2 (face completions-common-part) 2 3 (face (completions-first-difference)))))) + (should (= 2 + (ivy-completion-common-length + #("test/" + 0 2 (face completions-common-part) + 2 3 (face completions-first-difference))))) (should (= 5 (ivy-completion-common-length #("Math/E" @@ -1020,7 +1025,8 @@ Since `execute-kbd-macro' doesn't pick up a let-bound `default-directory'.") (should (= 3 (ivy-completion-common-length #("vec" - 0 3 (face (completions-common-part))))))) + 0 3 (face (completions-common-part)))))) + ) (ert-deftest ivy--sort-function () "Test `ivy--sort-function' behavior." diff --git a/ivy.el b/ivy.el index 5056d4e4..3b91ed27 100644 --- a/ivy.el +++ b/ivy.el @@ -2649,12 +2649,19 @@ The first non-matching part is propertized: (i (1- (length str)))) (catch 'done (while (>= i 0) - (when (equal (get-text-property i 'face str) - '(completions-first-difference)) - (throw 'done i)) + (pcase (get-text-property i 'face str) + (`completions-first-difference (throw 'done i)) + ((and (pred listp) (pred (member 'completions-first-difference))) + (throw 'done i))) (cl-decf i)) (throw 'done (length str))))) +(defun ivy--completion-prefix-offset (str md) + "Return the offset of the completion prefix in STR with its metadata MD." + (pcase (cdr (assoc 'category md)) + (`file (length (file-name-directory str))) + (_ 0))) + (defun ivy-completion-in-region (start end collection &optional predicate) "An Ivy function suitable for `completion-in-region-function'. The function completes the text between START and END using COLLECTION. @@ -2680,14 +2687,16 @@ See `completion-in-region' for further information." (when (eq collection 'crm--collection-fn) (setq comps (delete-dups comps))) (let* ((len (ivy-completion-common-length (car comps))) + (prefix-offset (ivy--completion-prefix-offset str md)) + (target-str (substring str prefix-offset)) (initial (cond ((= len 0) "") - ((let ((str-len (length str))) + ((let ((str-len (length target-str))) (when (> len str-len) - (setq len str-len) - str))) + (setq len str-len))) + target-str) (t - (substring str (- len)))))) + (substring target-str (- len)))))) (delete-region (- end len) end) (setq ivy-completion-beg (- end len)) (setq ivy-completion-end ivy-completion-beg)