Improve options and docs of M-x command completion

* lisp/simple.el (read-extended-command-predicate): Expand the
doc string.  Add 2 more selectable values.
(command-completion-using-modes-and-keymaps-p): New function.
(execute-extended-command): Mention
'read-extended-command-predicate' in the doc string.  (Bug#60645)
This commit is contained in:
Eli Zaretskii 2023-01-08 12:23:26 +02:00
parent fef4f18cc3
commit 53e64cfb85

View file

@ -2207,15 +2207,39 @@ to get different commands to edit and resubmit."
"Predicate to use to determine which commands to include when completing.
If it's nil, include all the commands.
If it's a function, it will be called with two parameters: the
symbol of the command and a buffer. The predicate should return
non-nil if the command should be present when doing \\`M-x TAB'
in that buffer."
symbol of the command and the current buffer. The predicate should
return non-nil if the command should be considered as a completion
candidate for \\`M-x' in that buffer.
Several predicate functions suitable for various optional behaviors
are available:
`command-completion-default-include-p'
This excludes from completion candidates those commands
which have been marked specific to modes other than the
current buffer's mode. Commands that are not specific
to any mode are included.
`command-completion-using-modes-p'
This includes in completion candidates only commands
marked as specific to the current buffer's mode.
`command-completion-using-modes-and-keymaps-p'
This includes commands marked as specific to the current
buffer's modes and commands that have keybindings in the
current buffer's active local keymaps. It also includes
several commands, like Cuztomize commands, which should
always be avaliable."
:version "28.1"
:group 'completion
:type '(choice (const :tag "Don't exclude any commands" nil)
(const :tag "Exclude commands irrelevant to current buffer's mode"
command-completion-default-include-p)
(function :tag "Other function")))
(const :tag "Include only commands relevant to current buffer's mode"
command-completion-using-modes-p)
(const :tag "Commands relevant to current buffer's mode or bound in its keymaps"
command-completion-using-modes-and-keymaps-p)
(function :tag "Other predicate function")))
(defun execute-extended-command-cycle ()
"Choose the next version of the extended command predicates.
@ -2401,6 +2425,35 @@ or (if one of MODES is a minor mode), if it is switched on in BUFFER."
#'eq)
(seq-intersection modes global-minor-modes #'eq)))
(defun command-completion-using-modes-and-keymaps-p (symbol buffer)
"Return non-nil if SYMBOL is marked for BUFFER's mode or bound in its keymaps."
(with-current-buffer buffer
(let ((keymaps
;; The major mode's keymap and any active minor modes.
(nconc
(and (current-local-map) (list (current-local-map)))
(mapcar
#'cdr
(seq-filter
(lambda (elem)
(symbol-value (car elem)))
minor-mode-map-alist)))))
(or (command-completion-using-modes-p symbol buffer)
;; Include commands that are bound in a keymap in the
;; current buffer.
(and (where-is-internal symbol keymaps)
;; But not if they have a command predicate that
;; says that they shouldn't. (This is the case
;; for `ignore' and `undefined' and similar
;; commands commonly found in keymaps.)
(or (null (get symbol 'completion-predicate))
(funcall (get symbol 'completion-predicate)
symbol buffer)))
;; Include customize-* commands (do we need a list of such
;; "always available" commands? customizable?)
(string-match-p "customize-" (symbol-name symbol))))))
(defun command-completion-button-p (category buffer)
"Return non-nil if there's a button of CATEGORY at point in BUFFER."
(with-current-buffer buffer
@ -2502,7 +2555,11 @@ Also see `suggest-key-bindings'."
(defun execute-extended-command (prefixarg &optional command-name typed)
"Read a command name, then read the arguments and call the command.
To pass a prefix argument to the command you are
invoking, give a prefix argument to `execute-extended-command'."
invoking, give a prefix argument to `execute-extended-command'.
This command provides completion when reading the command name.
Which completion candidates are shown can be controlled by
customizing `read-extended-command-predicate'."
(declare (interactive-only command-execute))
;; FIXME: Remember the actual text typed by the user before completion,
;; so that we don't later on suggest the same shortening.