(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
(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.
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.