Add a new command for mode-specific commands
* doc/lispref/commands.texi (Interactive Call): Document it. * lisp/simple.el (command-completion-using-modes-p): Refactored out into its own function for reuse... (command-completion-default-include-p): ... from here. (execute-extended-command-for-buffer): New command and keystroke (`M-S-x').
This commit is contained in:
parent
12578d6aca
commit
e3e3133f80
4 changed files with 71 additions and 18 deletions
|
@ -851,6 +851,15 @@ non-@code{nil} if the command is to be included when completing in
|
|||
that buffer.
|
||||
@end deffn
|
||||
|
||||
@deffn Command execute-extended-command-for-buffer prefix-argument
|
||||
This is like @code{execute-extended-command}, but limits the commands
|
||||
offered for completion to those commands that are of particular
|
||||
relevance to the current major mode (and enabled minor modes). This
|
||||
includes commands that are tagged with the modes (@pxref{Using
|
||||
Interactive}), and also commands that are bound to locally active
|
||||
keymaps.
|
||||
@end deffn
|
||||
|
||||
@node Distinguish Interactive
|
||||
@section Distinguish Interactive Calls
|
||||
@cindex distinguish interactive calls
|
||||
|
|
7
etc/NEWS
7
etc/NEWS
|
@ -251,6 +251,13 @@ commands. The new keystrokes are 'C-x x g' ('revert-buffer'),
|
|||
|
||||
* Editing Changes in Emacs 28.1
|
||||
|
||||
+++
|
||||
** New command 'execute-extended-command-for-buffer'.
|
||||
This new command, bound to 'M-S-x', works like
|
||||
'execute-extended-command', but limits the set of commands to the
|
||||
commands that have been determined to be particularly of use to the
|
||||
current mode.
|
||||
|
||||
+++
|
||||
** New user option 'read-extended-command-predicate'.
|
||||
This option controls how 'M-x' performs completion of commands when
|
||||
|
|
|
@ -1994,6 +1994,26 @@ This function uses the `read-extended-command-predicate' user option."
|
|||
(funcall read-extended-command-predicate sym buffer)))))
|
||||
t nil 'extended-command-history))))
|
||||
|
||||
(define-inline command-completion-using-modes-p (symbol buffer)
|
||||
"Say whether SYMBOL has been marked as a mode-specific command in BUFFER."
|
||||
;; Check the modes.
|
||||
(let ((modes (command-modes symbol)))
|
||||
;; Common case: Just a single mode.
|
||||
(if (null (cdr modes))
|
||||
(or (provided-mode-derived-p
|
||||
(buffer-local-value 'major-mode buffer) (car modes))
|
||||
(memq (car modes)
|
||||
(buffer-local-value 'local-minor-modes buffer))
|
||||
(memq (car modes) global-minor-modes))
|
||||
;; Uncommon case: Multiple modes.
|
||||
(apply #'provided-mode-derived-p
|
||||
(buffer-local-value 'major-mode buffer)
|
||||
modes)
|
||||
(seq-intersection modes
|
||||
(buffer-local-value 'local-minor-modes buffer)
|
||||
#'eq)
|
||||
(seq-intersection modes global-minor-modes #'eq))))
|
||||
|
||||
(defun command-completion-default-include-p (symbol buffer)
|
||||
"Say whether SYMBOL should be offered as a completion.
|
||||
If there's a `completion-predicate' for SYMBOL, the result from
|
||||
|
@ -2004,24 +2024,8 @@ BUFFER."
|
|||
(if (get symbol 'completion-predicate)
|
||||
;; An explicit completion predicate takes precedence.
|
||||
(funcall (get symbol 'completion-predicate) symbol buffer)
|
||||
;; Check the modes.
|
||||
(let ((modes (command-modes symbol)))
|
||||
(or (null modes)
|
||||
;; Common case: Just a single mode.
|
||||
(if (null (cdr modes))
|
||||
(or (provided-mode-derived-p
|
||||
(buffer-local-value 'major-mode buffer) (car modes))
|
||||
(memq (car modes)
|
||||
(buffer-local-value 'local-minor-modes buffer))
|
||||
(memq (car modes) global-minor-modes))
|
||||
;; Uncommon case: Multiple modes.
|
||||
(apply #'provided-mode-derived-p
|
||||
(buffer-local-value 'major-mode buffer)
|
||||
modes)
|
||||
(seq-intersection modes
|
||||
(buffer-local-value 'local-minor-modes buffer)
|
||||
#'eq)
|
||||
(seq-intersection modes global-minor-modes #'eq))))))
|
||||
(or (null (command-modes symbol))
|
||||
(command-completion-using-modes-p symbol buffer))))
|
||||
|
||||
(defun command-completion-with-modes-p (modes buffer)
|
||||
"Say whether MODES are in action in BUFFER.
|
||||
|
@ -2189,6 +2193,38 @@ invoking, give a prefix argument to `execute-extended-command'."
|
|||
suggest-key-bindings
|
||||
2))))))))
|
||||
|
||||
(defun execute-extended-command-for-buffer (prefixarg &optional
|
||||
command-name typed)
|
||||
"Query usert for a command relevant for the current mode and then execute it.
|
||||
This is like `execute-extended-command', but limits the
|
||||
completions to commands that are particularly relevant to the
|
||||
current buffer. This includes commands that have been marked as
|
||||
being specially designed for the current major mode (and enabled
|
||||
minor modes), as well as commands bound in the active local key
|
||||
maps."
|
||||
(declare (interactive-only command-execute))
|
||||
(interactive
|
||||
(let* ((execute-extended-command--last-typed nil)
|
||||
(keymaps
|
||||
;; The major mode's keymap and any active minor modes.
|
||||
(cons
|
||||
(current-local-map)
|
||||
(mapcar
|
||||
#'cdr
|
||||
(seq-filter
|
||||
(lambda (elem)
|
||||
(symbol-value (car elem)))
|
||||
minor-mode-map-alist))))
|
||||
(read-extended-command-predicate
|
||||
(lambda (symbol buffer)
|
||||
(or (command-completion-using-modes-p symbol buffer)
|
||||
(where-is-internal symbol keymaps)))))
|
||||
(list current-prefix-arg
|
||||
(read-extended-command)
|
||||
execute-extended-command--last-typed)))
|
||||
(with-suppressed-warnings ((interactive-only execute-extended-command))
|
||||
(execute-extended-command prefixarg command-name typed)))
|
||||
|
||||
(defun command-execute (cmd &optional record-flag keys special)
|
||||
;; BEWARE: Called directly from the C code.
|
||||
"Execute CMD as an editor command.
|
||||
|
|
|
@ -1305,6 +1305,7 @@ in a cleaner way with command remapping, like this:
|
|||
(define-key map "l" #'downcase-word)
|
||||
(define-key map "c" #'capitalize-word)
|
||||
(define-key map "x" #'execute-extended-command)
|
||||
(define-key map "X" #'execute-extended-command-for-buffer)
|
||||
map)
|
||||
"Default keymap for ESC (meta) commands.
|
||||
The normal global definition of the character ESC indirects to this keymap.")
|
||||
|
|
Loading…
Add table
Reference in a new issue