aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2024-05-09 05:30:32 +0300
committerDmitry Gutov2024-05-09 05:31:10 +0300
commitff3f17ca3cdd9e82355942f577e7807acc76ddcd (patch)
tree1dd7a56ee654ff6b5bdb3a266e9bf9c0a2ea627f
parent8bc4292673dfc04ce781e242596779809f1a3634 (diff)
downloademacs-ff3f17ca3cdd9e82355942f577e7807acc76ddcd.tar.gz
emacs-ff3f17ca3cdd9e82355942f577e7807acc76ddcd.zip
choose-completion: Retain the suffix after completion boundary
* lisp/minibuffer.el (completion-base-suffix): Remove as not optimal after all (bug#48356). (completion--replace): Use insert-before-markers-and-inherit. (minibuffer-completion-help): Don't set completion-base-affixes, implement the same logic more optimally by local search and querying for field boundaries. Also fix the problem with completion table, predicate and extra-props being looked up in the wrong buffer. (minibuffer-next-completion, minibuffer-choose-completion): Don't bind completion-use-base-affixes anymore. * lisp/simple.el (completion-base-affixes) (completion-use-base-affixes): Remove. (completion-list-insert-choice-function): Don't pass them through anymore.
-rw-r--r--lisp/minibuffer.el99
-rw-r--r--lisp/simple.el21
2 files changed, 42 insertions, 78 deletions
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index ad6a0928cda..61395577035 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -112,20 +112,6 @@ the closest directory separators."
112 (cons (or (cadr boundaries) 0) 112 (cons (or (cadr boundaries) 0)
113 (or (cddr boundaries) (length suffix))))) 113 (or (cddr boundaries) (length suffix)))))
114 114
115(defun completion-base-suffix (start end collection predicate)
116 "Return suffix of completion of buffer text between START and END.
117COLLECTION and PREDICATE are, respectively, the completion's
118completion table and predicate, as in `completion-boundaries' (which see).
119Value is a substring of buffer text between point and END. It is
120the completion suffix that follows the completion boundary."
121 (let ((suffix (buffer-substring (point) end)))
122 (substring
123 suffix
124 (cdr (completion-boundaries (buffer-substring start (point))
125 collection
126 predicate
127 suffix)))))
128
129(defun completion-metadata (string table pred) 115(defun completion-metadata (string table pred)
130 "Return the metadata of elements to complete at the end of STRING. 116 "Return the metadata of elements to complete at the end of STRING.
131This metadata is an alist. Currently understood keys are: 117This metadata is an alist. Currently understood keys are:
@@ -1377,7 +1363,7 @@ Moves point to the end of the new text."
1377 (setq newtext (substring newtext 0 (- suffix-len)))) 1363 (setq newtext (substring newtext 0 (- suffix-len))))
1378 (goto-char beg) 1364 (goto-char beg)
1379 (let ((length (- end beg))) ;Read `end' before we insert the text. 1365 (let ((length (- end beg))) ;Read `end' before we insert the text.
1380 (insert-and-inherit newtext) 1366 (insert-before-markers-and-inherit newtext)
1381 (delete-region (point) (+ (point) length))) 1367 (delete-region (point) (+ (point) length)))
1382 (forward-char suffix-len))) 1368 (forward-char suffix-len)))
1383 1369
@@ -2598,17 +2584,23 @@ The candidate will still be chosen by `choose-completion' unless
2598 (base-size (or (cdr last) 0)) 2584 (base-size (or (cdr last) 0))
2599 (prefix (unless (zerop base-size) (substring string 0 base-size))) 2585 (prefix (unless (zerop base-size) (substring string 0 base-size)))
2600 (minibuffer-completion-base (substring string 0 base-size)) 2586 (minibuffer-completion-base (substring string 0 base-size))
2601 (base-prefix (buffer-substring (minibuffer--completion-prompt-end) 2587 (ctable minibuffer-completion-table)
2602 (+ start base-size))) 2588 (cpred minibuffer-completion-predicate)
2603 (base-suffix (concat (completion-base-suffix start end 2589 (cprops completion-extra-properties)
2604 minibuffer-completion-table 2590 (field-end
2605 minibuffer-completion-predicate) 2591 (save-excursion
2606 (buffer-substring end (point-max)))) 2592 (forward-char
2593 (cdr (completion-boundaries (buffer-substring start (point))
2594 ctable
2595 cpred
2596 (buffer-substring (point) end))))
2597 (point-marker)))
2598 (field-char (and (< field-end end) (char-after field-end)))
2607 (all-md (completion--metadata (buffer-substring-no-properties 2599 (all-md (completion--metadata (buffer-substring-no-properties
2608 start (point)) 2600 start (point))
2609 base-size md 2601 base-size md
2610 minibuffer-completion-table 2602 ctable
2611 minibuffer-completion-predicate)) 2603 cpred))
2612 (ann-fun (completion-metadata-get all-md 'annotation-function)) 2604 (ann-fun (completion-metadata-get all-md 'annotation-function))
2613 (aff-fun (completion-metadata-get all-md 'affixation-function)) 2605 (aff-fun (completion-metadata-get all-md 'affixation-function))
2614 (sort-fun (completion-metadata-get all-md 'display-sort-function)) 2606 (sort-fun (completion-metadata-get all-md 'display-sort-function))
@@ -2687,38 +2679,31 @@ The candidate will still be chosen by `choose-completion' unless
2687 2679
2688 (with-current-buffer standard-output 2680 (with-current-buffer standard-output
2689 (setq-local completion-base-position 2681 (setq-local completion-base-position
2690 (list (+ start base-size) 2682 (list (+ start base-size) field-end))
2691 ;; FIXME: We should pay attention to completion
2692 ;; boundaries here, but currently
2693 ;; completion-all-completions does not give us the
2694 ;; necessary information.
2695 end))
2696 (setq-local completion-base-affixes
2697 (list base-prefix base-suffix))
2698 (setq-local completion-list-insert-choice-function 2683 (setq-local completion-list-insert-choice-function
2699 (let ((ctable minibuffer-completion-table)
2700 (cpred minibuffer-completion-predicate)
2701 (cprops completion-extra-properties))
2702 (lambda (start end choice) 2684 (lambda (start end choice)
2703 (if (and (stringp start) (stringp end)) 2685 (unless (or (zerop (length prefix))
2704 (progn 2686 (equal prefix
2705 (delete-minibuffer-contents) 2687 (buffer-substring-no-properties
2706 (insert start choice) 2688 (max (point-min)
2707 ;; Keep point after completion before suffix 2689 (- start (length prefix)))
2708 (save-excursion (insert 2690 start)))
2709 (completion--merge-suffix 2691 (message "*Completions* out of date"))
2710 choice 2692 (when (> (point) end)
2711 (1- (length choice)) 2693 ;; Completion suffix has changed, have to adapt.
2712 end)))) 2694 (setq end (+ end
2713 (unless (or (zerop (length prefix)) 2695 (cdr (completion-boundaries
2714 (equal prefix 2696 (concat prefix choice) ctable cpred
2715 (buffer-substring-no-properties 2697 (buffer-substring end (point))))))
2716 (max (point-min) 2698 ;; Stopped before some field boundary.
2717 (- start (length prefix))) 2699 (when (> (point) end)
2718 start))) 2700 (setq field-char (char-after end))))
2719 (message "*Completions* out of date")) 2701 (when (and field-char
2720 ;; FIXME: Use `md' to do quoting&terminator here. 2702 (= (aref choice (1- (length choice)))
2721 (completion--replace start end choice)) 2703 field-char))
2704 (setq end (1+ end)))
2705 ;; FIXME: Use `md' to do quoting&terminator here.
2706 (completion--replace start end choice)
2722 (let* ((minibuffer-completion-table ctable) 2707 (let* ((minibuffer-completion-table ctable)
2723 (minibuffer-completion-predicate cpred) 2708 (minibuffer-completion-predicate cpred)
2724 (completion-extra-properties cprops) 2709 (completion-extra-properties cprops)
@@ -2729,7 +2714,7 @@ The candidate will still be chosen by `choose-completion' unless
2729 ;; completion is not finished. 2714 ;; completion is not finished.
2730 (completion--done result 2715 (completion--done result
2731 (if (eq (car bounds) (length result)) 2716 (if (eq (car bounds) (length result))
2732 'exact 'finished))))))) 2717 'exact 'finished))))))
2733 2718
2734 (display-completion-list completions nil group-fun))))) 2719 (display-completion-list completions nil group-fun)))))
2735 nil))) 2720 nil)))
@@ -4877,8 +4862,7 @@ insert the selected completion candidate to the minibuffer."
4877 (next-line-completion (or n 1)) 4862 (next-line-completion (or n 1))
4878 (next-completion (or n 1))) 4863 (next-completion (or n 1)))
4879 (when auto-choose 4864 (when auto-choose
4880 (let ((completion-use-base-affixes t) 4865 (let ((completion-auto-deselect nil))
4881 (completion-auto-deselect nil))
4882 (choose-completion nil t t)))))) 4866 (choose-completion nil t t))))))
4883 4867
4884(defun minibuffer-previous-completion (&optional n) 4868(defun minibuffer-previous-completion (&optional n)
@@ -4916,8 +4900,7 @@ If NO-QUIT is non-nil, insert the completion candidate at point to the
4916minibuffer, but don't quit the completions window." 4900minibuffer, but don't quit the completions window."
4917 (interactive "P") 4901 (interactive "P")
4918 (with-minibuffer-completions-window 4902 (with-minibuffer-completions-window
4919 (let ((completion-use-base-affixes t)) 4903 (choose-completion nil no-exit no-quit)))
4920 (choose-completion nil no-exit no-quit))))
4921 4904
4922(defun minibuffer-choose-completion-or-exit (&optional no-exit no-quit) 4905(defun minibuffer-choose-completion-or-exit (&optional no-exit no-quit)
4923 "Choose the completion from the minibuffer or exit the minibuffer. 4906 "Choose the completion from the minibuffer or exit the minibuffer.
diff --git a/lisp/simple.el b/lisp/simple.el
index a459f6ecfd2..deab52c4201 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9858,16 +9858,6 @@ Its value is a list of the form (START END) where START is the place
9858where the completion should be inserted and END (if non-nil) is the end 9858where the completion should be inserted and END (if non-nil) is the end
9859of the text to replace. If END is nil, point is used instead.") 9859of the text to replace. If END is nil, point is used instead.")
9860 9860
9861(defvar completion-base-affixes nil
9862 "Base context of the text corresponding to the shown completions.
9863This variable is used in the *Completions* buffer.
9864Its value is a list of the form (PREFIX SUFFIX) where PREFIX is the text
9865before the place where completion should be inserted, and SUFFIX is the text
9866after the completion.")
9867
9868(defvar completion-use-base-affixes nil
9869 "Non-nil means to restore original prefix and suffix in the minibuffer.")
9870
9871(defvar completion-list-insert-choice-function #'completion--replace 9861(defvar completion-list-insert-choice-function #'completion--replace
9872 "Function to use to insert the text chosen in *Completions*. 9862 "Function to use to insert the text chosen in *Completions*.
9873Called with three arguments (BEG END TEXT), it should replace the text 9863Called with three arguments (BEG END TEXT), it should replace the text
@@ -10128,7 +10118,6 @@ minibuffer, but don't quit the completions window."
10128 (with-current-buffer (window-buffer (posn-window (event-start event))) 10118 (with-current-buffer (window-buffer (posn-window (event-start event)))
10129 (let ((buffer completion-reference-buffer) 10119 (let ((buffer completion-reference-buffer)
10130 (base-position completion-base-position) 10120 (base-position completion-base-position)
10131 (base-affixes completion-base-affixes)
10132 (insert-function completion-list-insert-choice-function) 10121 (insert-function completion-list-insert-choice-function)
10133 (completion-no-auto-exit (if no-exit t completion-no-auto-exit)) 10122 (completion-no-auto-exit (if no-exit t completion-no-auto-exit))
10134 (choice 10123 (choice
@@ -10161,13 +10150,7 @@ minibuffer, but don't quit the completions window."
10161 (with-current-buffer buffer 10150 (with-current-buffer buffer
10162 (choose-completion-string 10151 (choose-completion-string
10163 choice buffer 10152 choice buffer
10164 ;; Don't allow affixes to replace the whole buffer when not 10153 (or base-position
10165 ;; in the minibuffer. Thus check for `completion-in-region-mode'
10166 ;; to ignore non-nil value of `completion-use-base-affixes' set by
10167 ;; `minibuffer-choose-completion'.
10168 (or (and (not completion-in-region-mode)
10169 completion-use-base-affixes base-affixes)
10170 base-position
10171 ;; If all else fails, just guess. 10154 ;; If all else fails, just guess.
10172 (list (choose-completion-guess-base-position choice))) 10155 (list (choose-completion-guess-base-position choice)))
10173 insert-function))))) 10156 insert-function)))))
@@ -10323,11 +10306,9 @@ Called from `temp-buffer-show-hook'."
10323 (buffer-substring (minibuffer-prompt-end) (point))))))) 10306 (buffer-substring (minibuffer-prompt-end) (point)))))))
10324 (with-current-buffer standard-output 10307 (with-current-buffer standard-output
10325 (let ((base-position completion-base-position) 10308 (let ((base-position completion-base-position)
10326 (base-affixes completion-base-affixes)
10327 (insert-fun completion-list-insert-choice-function)) 10309 (insert-fun completion-list-insert-choice-function))
10328 (completion-list-mode) 10310 (completion-list-mode)
10329 (setq-local completion-base-position base-position) 10311 (setq-local completion-base-position base-position)
10330 (setq-local completion-base-affixes base-affixes)
10331 (setq-local completion-list-insert-choice-function insert-fun)) 10312 (setq-local completion-list-insert-choice-function insert-fun))
10332 (setq-local completion-reference-buffer mainbuf) 10313 (setq-local completion-reference-buffer mainbuf)
10333 (if base-dir (setq default-directory base-dir)) 10314 (if base-dir (setq default-directory base-dir))