You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Emacs中筛选特定前缀的已绑定快捷键命令(兼容ivy-mode)

在 Emacs + Ivy 中实现 M-x 仅展示带快捷键绑定的命令

核心思路

要实现输入命令前缀时仅显示有快捷键绑定的命令,我们需要:

  1. 从当前全局/局部 keymap 中提取所有绑定了快捷键的命令(与describe-keymap实现原理一致)
  2. 修改counsel-M-x的候选列表,仅保留这些命令
  3. 兼容 Ivy 的前缀过滤逻辑,确保输入前缀时能精准筛选目标命令

实现代码

1. 编写命令提取函数

这个函数会遍历当前全局和局部 keymap,收集所有绑定了快捷键的命令:

(defun get-bound-commands ()
  "获取当前全局与局部 keymap 中绑定了快捷键的命令列表"
  (let ((commands ())
        (keymaps (list (current-global-map) (current-local-map))))
    (dolist (km keymaps)
      (when km
        (map-keymap
         (lambda (_key def)
           (when (commandp def)
             (push def commands)))
         km)))
    (delete-dups commands)))

2. 实现带过滤的 counsel-M-x 变体

直接定义一个新命令,调用它时仅展示绑定了快捷键的命令:

(defun counsel-M-x-bound-only ()
  "仅显示有快捷键绑定命令的 counsel-M-x 版本"
  (interactive)
  (let ((counsel-M-x-candidates (get-bound-commands)))
    (counsel-M-x)))

之后可以把这个命令绑定到常用快捷键,比如:

(global-set-key (kbd "M-X") #'counsel-M-x-bound-only)

3. 可选:添加开关功能(不替换原命令)

如果想保留默认counsel-M-x的功能,可通过开关控制是否仅显示绑定命令:

(defvar my-counsel-M-x-show-only-bound nil
  "控制 counsel-M-x 是否仅展示带快捷键绑定的命令")

(defun toggle-counsel-M-x-bound-only ()
  "切换 counsel-M-x 的绑定命令过滤状态"
  (interactive)
  (setq my-counsel-M-x-show-only-bound (not my-counsel-M-x-show-only-bound))
  (message "counsel-M-x 仅显示绑定命令: %s" my-counsel-M-x-show-only-bound))

(advice-add 'counsel-M-x-candidates :filter-return
            (lambda (candidates)
              (if my-counsel-M-x-show-only-bound
                  (intersection candidates (get-bound-commands) :test #'eq)
                candidates)))

使用时调用M-x toggle-counsel-M-x-bound-only即可开启/关闭过滤功能。

使用示例

比如在 Org Mode 中调用M-X(或开启开关后的M-x),输入org-table,此时只会列出带有快捷键绑定的 Org 表格相关命令,而非所有包含该前缀的命令。

内容的提问来源于stack exchange,提问作者aartist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:20:17