branch: externals/ivy
commit a0b2150dbe1872050b1886a94d167f1deacc5a61
Author: Basil L. Contovounesios <[email protected]>
Commit: Basil L. Contovounesios <[email protected]>
Prefer base-size over ivy-completion-common-length
The latter is very problematic: it is specific to a single
candidate, does not necessarily correspond to the string being
completed, complicates bounds calculations, relies on only partially
documented presentation details rather than the usual API, etc.
When completion-all-completions returns a base-size (which in
practice seems to be most if not all the time), it corresponds more
closely to the substring that is being completed and will be
replaced.
This should address most of the remaining issues in
reports #1361, #1755, #2643, #2879, #3051, #3056, and
https://bugs.gnu.org/76440.
* ivy.el (ivy-completion-common-length): Discourage use.
(ivy-completion-in-region): When completion-all-completions
returns a base-size, prefer that over the
completions-first-difference face to determine the completion
boundaries and initial-input.
Fixes #1755.
Fixes #2643.
Fixes #2879.
Closes #3051.
Fixes #3056.
---
ivy.el | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/ivy.el b/ivy.el
index fe3f58a6ca..5f8e608ace 100644
--- a/ivy.el
+++ b/ivy.el
@@ -2665,7 +2665,9 @@ That is, return the largest index into STR at which
either the
If no such index is found, return the length of STR.
Typically the completion-matching parts of STR have previously been
-propertized by `completion-all-completions'."
+propertized by `completion-all-completions', but then the base-size
+returned by that function should be preferred over
+`ivy-completion-common-length'."
(let* ((char-property-alias-alist '((face font-lock-face)))
(cmn (length str))
(i cmn))
@@ -2690,15 +2692,16 @@ See `completion-in-region' for further information."
(md (completion-metadata str collection predicate))
(try (completion-try-completion str collection predicate reg md))
(comps (completion-all-completions str collection predicate reg md))
+ (last (last comps))
+ (base-size (cdr last))
(ivy--minibuffer-table collection)
(ivy--minibuffer-pred predicate))
+ (when last (setcdr last ()))
(cond ((null comps)
(message "No matches")
nil)
- ((progn
- (nconc comps nil)
- (and (null (cdr comps))
- (string= str (car comps))))
+ ((and (null (cdr comps))
+ (string= str (car comps)))
(message "Sole match")
t)
(t
@@ -2709,15 +2712,20 @@ See `completion-in-region' for further information."
;; of fixing `ivy-completion-common-length') for backward
;; compatibility, since it's a potentially public function.
(cmn (if (= cmn (length (car comps))) 0 cmn))
- (initial (cond ((= cmn 0)
+ (initial (cond (base-size (substring str base-size))
+ ;; The remaining clauses should hopefully
never
+ ;; be taken, since they rely on
+ ;; `ivy-completion-common-length'.
+ ((= cmn 0)
"")
((>= cmn reg)
(setq cmn reg)
str)
(t
- (substring str (- cmn))))))
- (delete-region (- end cmn) end)
- (setq ivy-completion-beg (- end cmn))
+ (substring str (- cmn)))))
+ (base-pos (if base-size (+ start base-size) (- end cmn))))
+ (delete-region base-pos end)
+ (setq ivy-completion-beg base-pos)
(setq ivy-completion-end ivy-completion-beg)
(if (null (cdr comps))
(let ((ivy--minibuffer-try try))