diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index cfea336a9e5..a9d6e83cf85 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -333,6 +333,9 @@ default, it makes the following bindings: @item @key{RET} @code{exit-minibuffer} +@item @key{M-<} +@code{minibuffer-beginning-of-buffer} + @item @kbd{C-g} @code{abort-recursive-edit} @@ -1248,6 +1251,14 @@ combines this keymap with either @code{minibuffer-local-completion-map} or @code{minibuffer-local-must-match-map}. @end defvar +@defvar minibuffer-beginning-of-buffer-movement +If non-@code{nil}, the @kbd{M-<} command will move to the end of the +prompt if point is after the end of the prompt. If point is at or +before the end of the prompt, move to the start of the buffer. If +this variable is @code{nil}, the command behaves like +@code{beginning-of-buffer}. +@end defvar + @node High-Level Completion @subsection High-Level Completion Functions diff --git a/etc/NEWS b/etc/NEWS index 9a9e25bea90..ec40e5e2abe 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -617,6 +617,12 @@ list the contents of such directories when completing file names. ** Minibuffer ++++ +*** A new variable, 'minibuffer-beginning-of-buffer-movement', has +been introduced to allow controlling how the 'M-<' command works in +the minibuffer. If non-nil, point will move to the end of the prompt +(if point is after the end of the prompt). + --- *** Minibuffer now uses 'minibuffer-message' to display error messages at the end of the active minibuffer. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 3fa637f2acd..7227e83f878 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -2233,6 +2233,7 @@ The completion method is determined by `completion-at-point-functions'." (let ((map minibuffer-local-map)) (define-key map "\C-g" 'abort-recursive-edit) + (define-key map "\M-<" 'minibuffer-beginning-of-buffer) (define-key map "\r" 'exit-minibuffer) (define-key map "\n" 'exit-minibuffer)) @@ -2529,6 +2530,14 @@ such as making the current buffer visit no file in the case of `set-visited-file-name'." :type 'boolean) +(defcustom minibuffer-beginning-of-buffer-movement nil + "Control how the `M-<' command in the minibuffer behaves. +If non-nil, the command will go to the end of the prompt (if +point is after the end of the prompt). If nil, it will behave +like the `beginning-of-buffer' command." + :version "27.1" + :type 'boolean) + ;; Not always defined, but only called if next-read-file-uses-dialog-p says so. (declare-function x-file-dialog "xfns.c" (prompt dir &optional default-filename mustmatch only-dir-p)) @@ -3589,6 +3598,33 @@ See `completing-read' for the meaning of the arguments." (when file-name-at-point (insert file-name-at-point)))) +(defun minibuffer-beginning-of-buffer (&optional arg) + "Move to the logical beginning of the minibuffer. +This command behaves like `beginning-of-buffer', but if point is +after the end of the prompt, move to the end of the prompt. +Otherwise move to the start of the buffer." + (declare (interactive-only "use `(goto-char (point-min))' instead.")) + (interactive "^P") + (when (or (consp arg) + (region-active-p)) + (push-mark)) + (goto-char (cond + ;; We want to go N/10th of the way from the beginning. + ((and arg (not (consp arg))) + (+ (point-min) 1 + (/ (* (- (point-max) (point-min)) + (prefix-numeric-value arg)) + 10))) + ;; Go to the start of the buffer. + ((or (null minibuffer-beginning-of-buffer-movement) + (<= (point) (minibuffer-prompt-end))) + (point-min)) + ;; Go to the end of the minibuffer. + (t + (minibuffer-prompt-end)))) + (when (and arg (not (consp arg))) + (forward-line 1))) + (provide 'minibuffer) ;;; minibuffer.el ends here