递归地取消定义空前缀键

时间:2013-10-17 21:16:33

标签: emacs key-bindings

有一个emacs扩展,可以将密钥构建到非常不方便的位置,我在加载扩展后立即在我的.emacs文件中重新分配密钥绑定。我偷看了扩展代码,它没有使用可能在加载之前传递的变量或defcustoms。

我首先使用(define-key ... nil)禁用现有绑定,然后重新绑定它们。

问题是所有前缀绑定链仍然存在并污染我的键盘设置。

如何递归删除所有空(没有注册子项)前缀键?


使用示例更新

假设map是一个空的稀疏键映射。

(define-key map (kbd "C-c M-p b") 'do-first)
(define-key map (kbd "C-c M-p b f g") 'do-second)
(define-key map (kbd "C-c M-p b r s") 'do-third)
(define-key map (kbd "C-c M-p b r s") nil)
(define-key map (kbd "C-c M-p b f g") nil)
(define-key map (kbd "C-c M-p b") nil)

之后,我想使用(clean-map map)等某种功能让map再次为空。

2 个答案:

答案 0 :(得分:1)

不幸的是,没有简单的解决方案。

(defun eab/delete-sublist (sublst lst)
  (read (replace-regexp-in-string
     (prin1-to-string sublst)
     ""
     (prin1-to-string lst))))

(defun clean-map (target-map)
  (let ((map target-map))
    (cl-flet ((clean-keymaps
        (event def)
        (if (keymapp def)
        (if (keymap-emptyp def)
            (progn
              (setq map
                (eab/delete-sublist (cons event def) map))
              (map-keymap 'clean-keymaps map))
          (map-keymap 'clean-keymaps def)))))
      (map-keymap 'clean-keymaps map)
      map)))

(defun keymap-emptyp (keymap)
  (if (keymapp keymap)
      (if (or (and
           (eq 2 (length keymap))
           (not (cdr (cadr keymap))))
          (equal keymap '(keymap)))
      't
    nil)
    nil))

(keymap-emptyp '(keymap (110))) => t
(keymap-emptyp '(keymap)) => t
(keymap-emptyp '(keymap (110) (103 . do-second))) => nil

(setq test-map (make-sparse-keymap))

(define-key test-map (kbd "C-c M-p b f k") 'do-first)
(define-key test-map (kbd "C-c M-p b f g") 'do-second)
(define-key test-map (kbd "C-c M-p b r s n") 'do-third)
(define-key test-map (kbd "C-c M-p b r s n") nil)

之前:有两个递归前缀绑定,“r”和“r s”。

C-c M-p b f前缀命令

C-c M-p b r前缀命令

C-c M-p b r s前缀命令

C-c M-p b f g do-second

C-c M-p b f k do-first

(setq test-map (clean-map test-map))

之后:它被清理干净了。

C-c M-p b f前缀命令

C-c M-p b f g do-second

C-c M-p b f k do-first

答案 1 :(得分:0)

如果@phils让你正确,并使用他的例子,你可以这样做:

(global-set-key (kbd "C-c b") nil)

这样就清除了空前缀。