Allow for next-completion to wrap around the completion buffer
* lisp/simple.el (completion-wrap-movement): Add new option. (previous-completion): Update docstring. (next-completion): Respect completion-wrap-movement. (switch-to-completions): Handle backwards completion by jumping to the end of the buffer. * lisp/minibuffer.el: (minibuffer-local-completion-map): Bind minibuffer-complete to backtab (completion--in-region-1): Handle backtab to scroll backwards
This commit is contained in:
parent
f6967d2f66
commit
15693c8116
2 changed files with 74 additions and 33 deletions
|
@ -1379,14 +1379,18 @@ scroll the window of possible completions."
|
|||
;; and this command is repeated, scroll that window.
|
||||
((and (window-live-p minibuffer-scroll-window)
|
||||
(eq t (frame-visible-p (window-frame minibuffer-scroll-window))))
|
||||
(let ((window minibuffer-scroll-window))
|
||||
(let ((window minibuffer-scroll-window)
|
||||
(reverse (equal (this-command-keys) [backtab])))
|
||||
(with-current-buffer (window-buffer window)
|
||||
(if (pos-visible-in-window-p (point-max) window)
|
||||
;; If end is in view, scroll up to the beginning.
|
||||
(set-window-start window (point-min) nil)
|
||||
(if (pos-visible-in-window-p (if reverse (point-min) (point-max)) window)
|
||||
;; If end or beginning is in view, scroll up to the
|
||||
;; beginning or end respectively.
|
||||
(if reverse
|
||||
(set-window-point window (point-max))
|
||||
(set-window-start window (point-min) nil))
|
||||
;; Else scroll down one screen.
|
||||
(with-selected-window window
|
||||
(scroll-up)))
|
||||
(if reverse (scroll-down) (scroll-up))))
|
||||
nil)))
|
||||
;; If we're cycling, keep on cycling.
|
||||
((and completion-cycling completion-all-sorted-completions)
|
||||
|
@ -2651,6 +2655,7 @@ The completion method is determined by `completion-at-point-functions'."
|
|||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent map minibuffer-local-map)
|
||||
(define-key map "\t" 'minibuffer-complete)
|
||||
(define-key map [backtab] 'minibuffer-complete)
|
||||
;; M-TAB is already abused for many other purposes, so we should find
|
||||
;; another binding for it.
|
||||
;; (define-key map "\e\t" 'minibuffer-force-complete)
|
||||
|
|
|
@ -9029,38 +9029,68 @@ Go to the window from which completion was requested."
|
|||
(if (get-buffer-window buf)
|
||||
(select-window (get-buffer-window buf))))))
|
||||
|
||||
(defcustom completion-wrap-movement t
|
||||
"Non-nil means to wrap around when selecting completion options.
|
||||
This affects the commands `next-completion' and
|
||||
`previous-completion'."
|
||||
:type 'boolean
|
||||
:version "29.1"
|
||||
:group 'completion)
|
||||
|
||||
(defun previous-completion (n)
|
||||
"Move to the previous item in the completion list."
|
||||
"Move to the previous item in the completion list.
|
||||
With prefix argument N, move back N items (negative N means move
|
||||
forward)."
|
||||
(interactive "p")
|
||||
(next-completion (- n)))
|
||||
|
||||
(defun next-completion (n)
|
||||
"Move to the next item in the completion list.
|
||||
With prefix argument N, move N items (negative N means move backward)."
|
||||
With prefix argument N, move N items (negative N means move
|
||||
backward)."
|
||||
(interactive "p")
|
||||
(let ((beg (point-min)) (end (point-max)))
|
||||
(while (and (> n 0) (not (eobp)))
|
||||
;; If in a completion, move to the end of it.
|
||||
(when (get-text-property (point) 'mouse-face)
|
||||
(goto-char (next-single-property-change (point) 'mouse-face nil end)))
|
||||
;; Move to start of next one.
|
||||
(unless (get-text-property (point) 'mouse-face)
|
||||
(goto-char (next-single-property-change (point) 'mouse-face nil end)))
|
||||
(setq n (1- n)))
|
||||
(while (and (< n 0) (not (bobp)))
|
||||
(let ((prop (get-text-property (1- (point)) 'mouse-face)))
|
||||
;; If in a completion, move to the start of it.
|
||||
(when (and prop (eq prop (get-text-property (point) 'mouse-face)))
|
||||
(goto-char (previous-single-property-change
|
||||
(point) 'mouse-face nil beg)))
|
||||
;; Move to end of the previous completion.
|
||||
(unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
|
||||
(goto-char (previous-single-property-change
|
||||
(point) 'mouse-face nil beg)))
|
||||
;; Move to the start of that one.
|
||||
(goto-char (previous-single-property-change
|
||||
(point) 'mouse-face nil beg))
|
||||
(setq n (1+ n))))))
|
||||
(catch 'bound
|
||||
(while (> n 0)
|
||||
;; If in a completion, move to the end of it.
|
||||
(when (get-text-property (point) 'mouse-face)
|
||||
(goto-char (next-single-property-change (point) 'mouse-face nil end)))
|
||||
;; If at the last completion option, wrap or skip to the
|
||||
;; minibuffer, if requested.
|
||||
(when (and completion-wrap-movement (eobp))
|
||||
(if (and (member (this-command-keys) '("\t" [backtab]))
|
||||
completion-auto-select)
|
||||
(throw 'bound nil)
|
||||
(goto-char (point-min))))
|
||||
;; Move to start of next one.
|
||||
(unless (get-text-property (point) 'mouse-face)
|
||||
(goto-char (next-single-property-change (point) 'mouse-face nil end)))
|
||||
(setq n (1- n)))
|
||||
(while (< n 0)
|
||||
(let ((prop (get-text-property (1- (point)) 'mouse-face)))
|
||||
;; If in a completion, move to the start of it.
|
||||
(when (and prop (eq prop (get-text-property (point) 'mouse-face)))
|
||||
(goto-char (previous-single-property-change
|
||||
(point) 'mouse-face nil beg)))
|
||||
;; Move to end of the previous completion.
|
||||
(unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
|
||||
(goto-char (previous-single-property-change
|
||||
(point) 'mouse-face nil beg)))
|
||||
;; If at the first completion option, wrap or skip to the
|
||||
;; minibuffer, if requested.
|
||||
(when (and completion-wrap-movement (bobp))
|
||||
(if (and (member (this-command-keys) '("\t" [backtab]))
|
||||
completion-auto-select)
|
||||
(progn
|
||||
(goto-char (next-single-property-change (point) 'mouse-face nil end))
|
||||
(throw 'bound nil))
|
||||
(goto-char (point-max))))
|
||||
;; Move to the start of that one.
|
||||
(goto-char (previous-single-property-change
|
||||
(point) 'mouse-face nil beg))
|
||||
(setq n (1+ n)))))
|
||||
(when (/= 0 n)
|
||||
(switch-to-minibuffer))))
|
||||
|
||||
(defun choose-completion (&optional event)
|
||||
"Choose the completion at point.
|
||||
|
@ -9285,10 +9315,16 @@ select the completion near point.\n\n")))))
|
|||
(get-buffer-window "*Completions*" 0)))))
|
||||
(when window
|
||||
(select-window window)
|
||||
;; In the new buffer, go to the first completion.
|
||||
;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
|
||||
(when (bobp)
|
||||
(next-completion 1)))))
|
||||
(cond
|
||||
((and (memq this-command '(completion-at-point minibuffer-complete))
|
||||
(equal (this-command-keys) [backtab])
|
||||
(bobp))
|
||||
(goto-char (point-max))
|
||||
(previous-completion 1))
|
||||
;; In the new buffer, go to the first completion.
|
||||
;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
|
||||
((bobp)
|
||||
(next-completion 1))))))
|
||||
|
||||
(defun read-expression-switch-to-completions ()
|
||||
"Select the completion list window while reading an expression."
|
||||
|
|
Loading…
Add table
Reference in a new issue