emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Handle case where `beg` and `end` are strings instead of mar


From: James N . V . Cash
Subject: Re: [PATCH] Handle case where `beg` and `end` are strings instead of markers
Date: Mon, 02 May 2022 11:32:46 -0400

Juri Linkov <juri@linkov.net> writes:

>> Upon further inspection, I see that `minibuffer-completion-help` is setting
>> `completion-list-insert-choice-function` to a function that checks if the 
>> `beg`
>> and `end` arguments are strings, in which case it just replaces the
>> minibuffer contents with "beg" + "choice" + "end". Indeed, when doing
>> `completing-read` instead of `completing-read-multiple`,
>> `completion--replace` doesn't get called at all in this case.
>
> completing-read-multiple already overrides choose-completion-string-functions
> with own crm--choose-completion-string.  So it would also make sense to
> override completion-list-insert-choice-function as well.

I think there are a few ways this could be done. The simplest would be
to do the same thing that minibuffer.el does (if `start` and `end` are
strings, insert `start`, `choice`, `end`; otherwise call
`completion--replace` as usual).

The other approach, which the below patch implements, is try to find the
bounds based on the strings, but if the contents been edited, find the
nearest CRM separator. This is kind of nice in that it lets you edit
other selections but then still select a candidate, but I don't know how
useful/expected that really is. The logic could also be made somewhat
more complex (count the number of separators in `start` and `end`, try
to guess how many we should skip over in each direction) but I don't
know if that's really worthwhile.

---
 lisp/emacs-lisp/crm.el | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index f3e1981732..8a5c3d3730 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -254,6 +254,23 @@ completing-read-multiple
                     'crm--choose-completion-string nil 'local)
           (setq-local minibuffer-completion-table #'crm--collection-fn)
           (setq-local minibuffer-completion-predicate predicate)
+          (setq-local completion-list-insert-choice-function
+                      (lambda (start end choice)
+                        (if (and (stringp start) (stringp end))
+                            (let* ((beg (save-excursion
+                                          (goto-char (minibuffer-prompt-end))
+                                          (or (search-forward start nil t)
+                                              (search-forward-regexp 
crm-separator nil t)
+                                              (minibuffer-prompt-end))))
+                                   (end (save-excursion
+                                          (goto-char (point-max))
+                                          (or (search-backward end nil t)
+                                              (progn
+                                                (goto-char beg)
+                                                (search-forward-regexp 
crm-separator nil t))
+                                              (point-max)))))
+                              (completion--replace beg end choice))
+                          (completion--replace start end choice))))
           ;; see completing_read in src/minibuf.c
           (setq-local minibuffer-completion-confirm
                       (unless (eq require-match t) require-match))
-- 
2.25.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]