bug#81411: 31.0.90; Selecting completion for completing-read-multiple does not respect completion boundaries

Aaron Zeng via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <[email protected]> Mon, 03 Aug 2026 17:35:53 -0400
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
--=-=-=
Content-Type: text/plain

Tags: patch

I spent some time staring at this and ended up coming up with a patch.
I noticed a separate issue where the existing code was not finding the
boundaries of the element correctly (if crm-separator matches more
than one character), so the first patch changes it to use the
crm--completion-command helper to come up with the boundaries.

The second patch fixes the initial reported bug.  Within the
boundaries of the element, it now calls completion-boundaries to get
the new boundaries of the part of that element to be completed.

On my machine, I tested that it fixes my initial reproduction example
as well as the downstream issue I noticed in my site's extensions, but
would appreciate any additional feedback and testing.

Thanks,
Aaron

In GNU Emacs 31.0.91 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.15.12, Xaw scroll bars) of 2026-07-29 built on
 vdc-qws-i40813a
Repository revision: 112645541ac2e8781080e722ba6756227606160c
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: Rocky Linux 8.10 (Green Obsidian)

Configured using:
 'configure --with-x-toolkit=lucid --without-gpm --without-gconf
 --without-selinux --without-imagemagick --with-modules --with-gif=no
 --with-cairo --with-rsvg --without-compress-install
 --with-tree-sitter --with-native-compilation=aot
 --prefix=/usr/local/home/garnish/raw-emacs/31-20260729_110947'


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0001-Fix-completing-read-multiple-when-separators-are-lon.patch

From 5f5213e17da34760da735397f0ff3dcf7ae6f4c1 Mon Sep 17 00:00:00 2001
From: "Aaron L. Zeng" <[email protected]>
Date: Tue, 21 Jul 2026 13:56:50 -0400
Subject: [PATCH 1/2] Fix completing-read-multiple when separators are longer
 than 1 char

* lisp/emacs-lisp/crm.el (completing-read-multiple): Use
crm--completion-command to determine element boundaries.
---
 lisp/emacs-lisp/crm.el | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index b68d3d55525..9be7913a954 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -263,16 +263,7 @@ completing-read-multiple
                     'crm--choose-completion-string nil 'local)
           (setq-local completion-list-insert-choice-function
                       (lambda (_start _end choice)
-                        (let* ((beg (save-excursion
-                                      (if (search-backward-regexp crm-separator
-                                                                  (field-beginning)
-                                                                  t)
-                                          (1+ (point))
-                                        (minibuffer-prompt-end))))
-                               (end (save-excursion
-                                      (if (search-forward-regexp crm-separator nil t)
-                                          (1- (point))
-                                        (point-max)))))
+                        (crm--completion-command beg end
                           (completion--replace beg end choice))))
           (setq-local crm-completion-table table)
           (use-local-map map))
-- 
2.43.7


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0002-Fix-choose-completion-in-CRM-with-boundaries.patch

From 16ae3cd8b28015e5baa8c8d0774e134c2ae4aaaf Mon Sep 17 00:00:00 2001
From: "Aaron L. Zeng" <[email protected]>
Date: Tue, 21 Jul 2026 14:02:33 -0400
Subject: [PATCH 2/2] Fix choose-completion in CRM with boundaries

* lisp/emacs-lisp/crm.el (completing-read-multiple): Respect
completion boundaries when inserting a choice.
---
 lisp/emacs-lisp/crm.el | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index 9be7913a954..e46570d1a47 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -263,8 +263,19 @@ completing-read-multiple
                     'crm--choose-completion-string nil 'local)
           (setq-local completion-list-insert-choice-function
                       (lambda (_start _end choice)
+                        ;; Respect the boundaries of the current
+                        ;; element, and within that, any boundaries
+                        ;; specified by the completion table
+                        ;; (bug#81411).
                         (crm--completion-command beg end
-                          (completion--replace beg end choice))))
+                          (let ((bounds (completion-boundaries
+                                         (buffer-substring beg (point))
+                                         crm-completion-table
+                                         minibuffer-completion-predicate
+                                         (buffer-substring (point) end))))
+                            (completion--replace (+ beg (car bounds))
+                                                 (+ (point) (cdr bounds))
+                                                 choice)))))
           (setq-local crm-completion-table table)
           (use-local-map map))
       (setq input (completing-read
-- 
2.43.7


--=-=-=--