diff options
| author | Dmitry Gutov | 2024-05-09 05:30:32 +0300 |
|---|---|---|
| committer | Dmitry Gutov | 2024-05-09 05:31:10 +0300 |
| commit | ff3f17ca3cdd9e82355942f577e7807acc76ddcd (patch) | |
| tree | 1dd7a56ee654ff6b5bdb3a266e9bf9c0a2ea627f | |
| parent | 8bc4292673dfc04ce781e242596779809f1a3634 (diff) | |
| download | emacs-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.el | 99 | ||||
| -rw-r--r-- | lisp/simple.el | 21 |
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. | ||
| 117 | COLLECTION and PREDICATE are, respectively, the completion's | ||
| 118 | completion table and predicate, as in `completion-boundaries' (which see). | ||
| 119 | Value is a substring of buffer text between point and END. It is | ||
| 120 | the 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. |
| 131 | This metadata is an alist. Currently understood keys are: | 117 | This 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 | |||
| 4916 | minibuffer, but don't quit the completions window." | 4900 | minibuffer, 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 | |||
| 9858 | where the completion should be inserted and END (if non-nil) is the end | 9858 | where the completion should be inserted and END (if non-nil) is the end |
| 9859 | of the text to replace. If END is nil, point is used instead.") | 9859 | of 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. | ||
| 9863 | This variable is used in the *Completions* buffer. | ||
| 9864 | Its value is a list of the form (PREFIX SUFFIX) where PREFIX is the text | ||
| 9865 | before the place where completion should be inserted, and SUFFIX is the text | ||
| 9866 | after 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*. |
| 9873 | Called with three arguments (BEG END TEXT), it should replace the text | 9863 | Called 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)) |