From 03b780e387e54c23ac9322e329aca6e5ab4f18e6 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Tue, 31 May 2022 20:52:37 +0300 Subject: [PATCH] Fix handling of windows/buffers for non-nil completion-auto-select (bug#55712) * lisp/minibuffer.el (completion--in-region-1): When completion-auto-select is `second-tab', call switch-to-completions outside of `with-current-buffer'. For the case of completion-auto-select customized to t, move switch-to-completions from completion-setup-function where it was called inside of with-current-buffer-window. * lisp/simple.el (completion-setup-function): Move switch-to-completions for completion-auto-select=t to completion--in-region-1 where it's handled together with the case of `second-tab'. (next-completion): Add check for the minibuffer to support in-buffer inline completions. --- lisp/minibuffer.el | 24 ++++++++++++++++-------- lisp/simple.el | 17 ++++++++--------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 6ae25b8def3..cdbde2d3405 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1422,9 +1422,10 @@ scroll the window of possible completions." (let ((window minibuffer-scroll-window)) (with-current-buffer (window-buffer window) (cond - ;; Here this is possible only when second-tab, so jump now. - (completion-auto-select - (switch-to-completions)) + ;; Here this is possible only when second-tab, but instead of + ;; scrolling the completion list window, switch to it below, + ;; outside of `with-current-buffer'. + ((eq completion-auto-select 'second-tab)) ;; Reverse tab ((equal (this-command-keys) [backtab]) (if (pos-visible-in-window-p (point-min) window) @@ -1438,15 +1439,22 @@ scroll the window of possible completions." ;; If end is in view, scroll up to the end. (set-window-start window (point-min) nil) ;; Else scroll down one screen. - (with-selected-window window (scroll-up))))) - nil))) + (with-selected-window window (scroll-up)))))) + (when (eq completion-auto-select 'second-tab) + (switch-to-completions)) + nil)) ;; If we're cycling, keep on cycling. ((and completion-cycling completion-all-sorted-completions) (minibuffer-force-complete beg end) t) - (t (pcase (completion--do-completion beg end) - (#b000 nil) - (_ t))))) + (t (prog1 (pcase (completion--do-completion beg end) + (#b000 nil) + (_ t)) + (when (and (eq completion-auto-select t) + (window-live-p minibuffer-scroll-window) + (eq t (frame-visible-p (window-frame minibuffer-scroll-window)))) + ;; When the completion list window was displayed, select it. + (switch-to-completions)))))) (defun completion--cache-all-sorted-completions (beg end comps) (add-hook 'after-change-functions diff --git a/lisp/simple.el b/lisp/simple.el index d6b70454324..29c4ba07be5 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -9513,14 +9513,14 @@ This affects the commands `next-completion' and When the value is t, pressing TAB will switch to the completion list buffer when Emacs pops up a window showing that buffer. If the value is `second-tab', then the first TAB will pop up the -window shwoing the completions list buffer, and the next TAB will +window showing the completions list buffer, and the next TAB will switch to that window. See `completion-auto-help' for controlling when the window showing the completions is popped up and down." :type '(choice (const :tag "Don't auto-select completions window" nil) (const :tag "Select completions window on first TAB" t) - (const :tag - "Select completions window on second TAB" second-tab)) + (const :tag "Select completions window on second TAB" + second-tab)) :version "29.1" :group 'completion) @@ -9573,7 +9573,8 @@ Also see the `completion-wrap-movement' variable." ;; If at the last completion option, wrap or skip ;; to the minibuffer, if requested. (when completion-wrap-movement - (if (and (eq completion-auto-select t) tabcommand) + (if (and (eq completion-auto-select t) tabcommand + (minibufferp completion-reference-buffer)) (throw 'bound nil) (first-completion)))) (setq n (1- n))) @@ -9596,9 +9597,9 @@ Also see the `completion-wrap-movement' variable." ;; If at the first completion option, wrap or skip ;; to the minibuffer, if requested. (when completion-wrap-movement - (if (and (eq completion-auto-select t) tabcommand) + (if (and (eq completion-auto-select t) tabcommand + (minibufferp completion-reference-buffer)) (progn - ;; (goto-char (next-single-property-change (point) 'mouse-face)) (throw 'bound nil)) (last-completion)))) (setq n (1+ n)))) @@ -9826,9 +9827,7 @@ Called from `temp-buffer-show-hook'." (insert "Click on a completion to select it.\n")) (insert (substitute-command-keys "In this buffer, type \\[choose-completion] to \ -select the completion near point.\n\n"))))) - (when (eq completion-auto-select t) - (switch-to-completions))) +select the completion near point.\n\n")))))) (add-hook 'completion-setup-hook #'completion-setup-function) -- 2.39.2