Subject: [PATCH] Give Completion Preview bindings higher precedence
From: Eshel Yaron <[email-masked]>
To: [email-masked]
Date: Sun, 17 Nov 2024 17:30:47 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

Whenever Completion Preview mode shows a completion preview, it also
activates keybindings for commands that interact with that preview, most
notably TAB is bound to completion-preview-insert, which inserts the
suggested completion.  This is implemented via a minor mode
completion-preview-active-mode whose keymap provides these bindings, and
which is enabled when the preview is displayed. 

This all works well, except for when another minor mode, foo-mode, is
enabled, whose keybindings conflict with these active preview bindings.
If foo-mode is defined after completion-preview-active-mode, i.e. if
foo.el is loaded after completion-preview.el, then foo-mode comes first
in minor-mode-map-alist and takes precedence over the bindings in
completion-preview-active-mode-map.

This happens, for example, with eshell-cmpl-mode, a minor mode that is
enabled by default in Eshell, which binds TAB to completion-at-point.
So currently Completion Preview mode doesn't work as expected in Eshell:
when you try to accept the suggested completion (with TAB), you get
completion-at-point instead of completion-preview-insert.

To fix this issue, we need to give the active completion preview
bindings higher precedence than keymaps of minor modes that where
defined after loading completion-preview.el.  The patch below does that
by using minor-mode-overriding-map-alist.  Any thoughts?

From 951df80d3749b2e82072f397dd7c7b5ce256f36d Mon Sep 17 00:00:00 2001
From: Eshel Yaron <[email-masked]>
Date: Sun, 17 Nov 2024 16:55:30 +0100
Subject: [PATCH] Give Completion Preview bindings higher precedence

* lisp/completion-preview.el
(completion-preview-active-mode): add keymap to
'minor-mode-overriding-map-alist' so it takes precedence
over other minor mode maps that bind TAB, such as
'eshell-cmpl-mode' in Eshell.
---
 lisp/completion-preview.el | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/lisp/completion-preview.el b/lisp/completion-preview.el
index 4564812e8a9..e5be3197032 100644
--- a/lisp/completion-preview.el
+++ b/lisp/completion-preview.el
@@ -322,8 +322,13 @@ completion-preview-active-mode
   "Mode for when the completion preview is shown."
   :interactive nil
   (if completion-preview-active-mode
-      (add-hook 'window-selection-change-functions
-                #'completion-preview--window-selection-change nil t)
+      (progn
+        (add-hook 'window-selection-change-functions
+                  #'completion-preview--window-selection-change nil t)
+        ;; Give keymap precedence over other minor mode maps.
+        (setf (alist-get 'completion-preview-active-mode
+                         minor-mode-overriding-map-alist)
+              completion-preview-active-mode-map))
     (remove-hook 'window-selection-change-functions
                  #'completion-preview--window-selection-change t)
     (completion-preview-hide)))
-- 
2.46.2