summaryrefslogtreecommitdiff
path: root/lisp/simple.el
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2023-01-08 12:23:26 +0200
committerEli Zaretskii <eliz@gnu.org>2023-01-08 12:23:26 +0200
commit53e64cfb852e8c953e90448970f7d48b3872bc1e (patch)
tree5ee8657720b7ad7fc825cbb96b860742ab41ca5f /lisp/simple.el
parentfef4f18cc33754c1c06be3100563e2b0b690c067 (diff)
downloademacs-53e64cfb852e8c953e90448970f7d48b3872bc1e.tar.gz
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)
Diffstat (limited to 'lisp/simple.el')
-rw-r--r--lisp/simple.el67
1 files changed, 62 insertions, 5 deletions
diff --git a/lisp/simple.el b/lisp/simple.el
index 63479e9ce0a..24df86c80c2 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -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.