mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2026-09-10 07:46:51 -04:00
Fix navigating *Completions* with TAB in vertical format
* lisp/simple.el (next-line-completion): Make using TAB to navigate in vertical format cycle through the minibuffer (bug#81631). * test/lisp/minibuffer-tests.el (completion-auto-select-test-bug81635): Run tests for all values of 'completions-format'.
This commit is contained in:
parent
9c9a26e60b
commit
e8936794ad
|
|
@ -10357,29 +10357,31 @@ of completions.
|
|||
|
||||
Also see the `completion-auto-wrap' variable."
|
||||
(interactive "p")
|
||||
(let (line column pos found last first)
|
||||
(when (and (bobp)
|
||||
(> n 0)
|
||||
(get-text-property (point) 'mouse-face)
|
||||
(not (get-text-property (point) 'first-completion)))
|
||||
(let ((inhibit-read-only t))
|
||||
(add-text-properties (point) (1+ (point)) '(first-completion t)))
|
||||
(setq n (1- n)))
|
||||
(let ((tabcommand (member (this-command-keys) '("\t" [backtab])))
|
||||
line column pos found last first)
|
||||
(catch 'bound
|
||||
(when (and (bobp)
|
||||
(> n 0)
|
||||
(get-text-property (point) 'mouse-face)
|
||||
(not (get-text-property (point) 'first-completion)))
|
||||
(let ((inhibit-read-only t))
|
||||
(add-text-properties (point) (1+ (point)) '(first-completion t)))
|
||||
(setq n (1- n)))
|
||||
|
||||
(if (get-text-property (point) 'mouse-face)
|
||||
;; If in a completion, move to the start of it.
|
||||
(completion--move-to-candidate-start)
|
||||
;; Try to move to the previous completion.
|
||||
(setq pos (previous-single-property-change (point) 'mouse-face))
|
||||
(if pos
|
||||
;; Move to the start of the previous completion.
|
||||
(progn
|
||||
(goto-char pos)
|
||||
(unless (get-text-property (point) 'mouse-face)
|
||||
(goto-char (previous-single-property-change
|
||||
(point) 'mouse-face nil (point-min)))))
|
||||
(cond ((> n 0) (setq n (1- n)) (first-completion))
|
||||
((< n 0) (first-completion)))))
|
||||
(if (get-text-property (point) 'mouse-face)
|
||||
;; If in a completion, move to the start of it.
|
||||
(completion--move-to-candidate-start)
|
||||
;; Try to move to the previous completion.
|
||||
(setq pos (previous-single-property-change (point) 'mouse-face))
|
||||
(if pos
|
||||
;; Move to the start of the previous completion.
|
||||
(progn
|
||||
(goto-char pos)
|
||||
(unless (get-text-property (point) 'mouse-face)
|
||||
(goto-char (previous-single-property-change
|
||||
(point) 'mouse-face nil (point-min)))))
|
||||
(cond ((> n 0) (setq n (1- n)) (first-completion))
|
||||
((< n 0) (first-completion)))))
|
||||
|
||||
(while (> n 0)
|
||||
(setq found nil pos (point) column (current-column)
|
||||
|
|
@ -10387,7 +10389,12 @@ Also see the `completion-auto-wrap' variable."
|
|||
last (= (point) (save-excursion (last-completion) (point))))
|
||||
(if (and (eq completions-format 'vertical)
|
||||
completion-auto-wrap last)
|
||||
(first-completion) ; Wrap from last to first item.
|
||||
(if (and (eq completion-auto-select t) tabcommand
|
||||
(minibufferp completion-reference-buffer))
|
||||
(progn
|
||||
(completions--clear-selection)
|
||||
(throw 'bound nil)) ; Skip to minibuffer.
|
||||
(first-completion)) ; Wrap from last to first item.
|
||||
(completion--move-to-candidate-end)
|
||||
(while (and (not found)
|
||||
(eq (forward-line 1) 0)
|
||||
|
|
@ -10424,7 +10431,12 @@ Also see the `completion-auto-wrap' variable."
|
|||
first (= (point) (save-excursion (first-completion) (point))))
|
||||
(if (and (eq completions-format 'vertical)
|
||||
completion-auto-wrap first)
|
||||
(last-completion) ; Wrap from first to last item.
|
||||
(if (and (eq completion-auto-select t) tabcommand
|
||||
(minibufferp completion-reference-buffer))
|
||||
(progn
|
||||
(completions--clear-selection)
|
||||
(throw 'bound nil)) ; Skip to minibuffer.
|
||||
(last-completion)) ; Wrap from first to last item.
|
||||
(completion--move-to-candidate-start)
|
||||
(while (and (not found)
|
||||
(eq (forward-line -1) 0)
|
||||
|
|
@ -10461,7 +10473,10 @@ Also see the `completion-auto-wrap' variable."
|
|||
(setq pos (point))
|
||||
(forward-line))
|
||||
(goto-char pos)))))
|
||||
(setq n (1+ n)))))
|
||||
(setq n (1+ n))))
|
||||
|
||||
(when (/= 0 n)
|
||||
(switch-to-minibuffer))))
|
||||
|
||||
(defun next-completion (&optional n)
|
||||
"Move according to `completions-format' to next completion item.
|
||||
|
|
|
|||
|
|
@ -640,37 +640,39 @@
|
|||
(should (eq (current-buffer) (get-buffer "*Completions*"))))))
|
||||
|
||||
(ert-deftest completion-auto-select-test-bug81635 ()
|
||||
(let ((completion-auto-select t)
|
||||
(completion-auto-wrap t))
|
||||
(completing-read-with-minibuffer-setup
|
||||
'("aa" "ab" "ac")
|
||||
(cl-flet ((selected ()
|
||||
(and (eq (current-buffer) (get-buffer "*Completions*"))
|
||||
(get-text-property (point) 'completion--string))))
|
||||
;; TAB cycles forward through all candidates, then to the
|
||||
;; minibuffer, then back to the first candidate.
|
||||
(execute-kbd-macro (kbd "a TAB"))
|
||||
(should (equal (selected) "aa"))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (equal (selected) "ab"))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (equal (selected) "ac"))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (minibufferp))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (equal (selected) "aa"))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (equal (selected) "ab"))
|
||||
;; S-TAB cycles backward, then to the minibuffer, then to the
|
||||
;; last candidate.
|
||||
(execute-kbd-macro (kbd "<backtab>"))
|
||||
(should (equal (selected) "aa"))
|
||||
(execute-kbd-macro (kbd "<backtab>"))
|
||||
(should (minibufferp))
|
||||
(execute-kbd-macro (kbd "<backtab>"))
|
||||
(should (equal (selected) "ac"))
|
||||
(execute-kbd-macro (kbd "<backtab>"))
|
||||
(should (equal (selected) "ab"))))))
|
||||
(dolist (format '(horizontal vertical one-column))
|
||||
(let ((completion-auto-select t)
|
||||
(completion-auto-wrap t)
|
||||
(completions-format format))
|
||||
(completing-read-with-minibuffer-setup
|
||||
'("aa" "ab" "ac")
|
||||
(cl-flet ((selected ()
|
||||
(and (eq (current-buffer) (get-buffer "*Completions*"))
|
||||
(get-text-property (point) 'completion--string))))
|
||||
;; TAB cycles forward through all candidates, then to the
|
||||
;; minibuffer, then back to the first candidate.
|
||||
(execute-kbd-macro (kbd "a TAB"))
|
||||
(should (equal (selected) "aa"))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (equal (selected) "ab"))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (equal (selected) "ac"))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (minibufferp))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (equal (selected) "aa"))
|
||||
(execute-kbd-macro (kbd "TAB"))
|
||||
(should (equal (selected) "ab"))
|
||||
;; S-TAB cycles backward, then to the minibuffer, then to the
|
||||
;; last candidate.
|
||||
(execute-kbd-macro (kbd "<backtab>"))
|
||||
(should (equal (selected) "aa"))
|
||||
(execute-kbd-macro (kbd "<backtab>"))
|
||||
(should (minibufferp))
|
||||
(execute-kbd-macro (kbd "<backtab>"))
|
||||
(should (equal (selected) "ac"))
|
||||
(execute-kbd-macro (kbd "<backtab>"))
|
||||
(should (equal (selected) "ab")))))))
|
||||
|
||||
(ert-deftest completion-auto-wrap-test ()
|
||||
(let ((completion-auto-wrap nil))
|
||||
|
|
|
|||
Loading…
Reference in a new issue