1

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

我首先禁用现有绑定(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清空。

4

2 回答 2

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”。

Cc Mp bf 前缀命令

Cc Mp br 前缀命令

Cc Mp brs 前缀命令

Cc Mp bfg do-second

Cc Mp bfk 先做

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

之后:它被清理了。

Cc Mp bf 前缀命令

Cc Mp bfg do-second

Cc Mp bfk 先做

于 2013-10-20T10:25:57.680 回答
0

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

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

这样空前缀就被清除了。

于 2013-10-18T07:05:03.057 回答