之前在emacs执行了这段代码:
(add-hook 'org-mode-hook (lambda ()
(define-key org-mode-map (kbd "RET") 'org-mac-grab-link)))
但这样很不方便, 因为grab-link用的不多, 但是回车键就用不了了. 现在想disable, 除了重启还有什么办法么?
我试了好多种做法, 没一种可以. 下面是我试过的.
(global-unset-key (kbd "RET")) ; 不起作用
(global-set-key (kbd "RET") nil) ; 不起作用
(add-hook 'org-mode-hook (lambda ()
(define-key org-mode-map (kbd "RET") nil))) ; 不起作用
(define-key (kbd "RET") nil) ; 不起作用
; (unset-key (kbd "RET")) ; 没这个命令
(eval-after-load "org" (global-unset-key (kbd "RET"))) ; 不起作用
顺便想问问, 它们为什么不起作用呢? 是不是global-unset-key对于某一个mode下的keybinding是无效的? 但是我根据某个链接, 按了<C-e>
, 据说这样就会把major mode key转为global key, 但就算这样, global-unset-key还是不行.
define-key怎么也不行呢?
1 个赞
本质是 (define-key keymap key nil)
Emacs 的按键绑定本质上都是用的 define-key,通过在各个 keymap 里建立相应的映射来完成绑定,不同的 keymap 代表着不同的优先级。
移除的是全局映射表里的 RET,你想要移除 org-mode-map 下的,但是又不想要重启 Emacs 的话,(define-key org-mode-map (kbd "RET") nil)
C-x C-e 就可以了。
把文件关闭在重新打开就可以生效了。
2 个赞
是的, 执行了org-reload
就可以了, 感谢! 不过还有个问题, 为什么直接(define-key org-mode-map (kbd "RET") nil))
不行, 而要
(add-hook 'org-mode-hook (lambda ()
(define-key org-mode-map (kbd "RET") nil)))
才可以呢?
我的理解是, add-hook是条件触发, 类似vim中的autocmd, 如果没有add-hook, 那就是无条件触发, 那不就应该起作用么?
add-hook 是你打开 org 文件的时候触发,因为你打开 org 文件的时候会启动 org-mode,org-mode 会执行 org-mode-hook 里的东西。
(define-key org-mode-map (kbd "RET") nil)
直接扔文件里无法生效的话,应该是 1. 找不到 org-mode-map,应该直接报错才对,是可以通过
(with-eval-after-load 'info
(define-key org-mode-map (kbd "RET") nil))
进行按键设置的,2. 至于你的问题为什么没有成功,我猜测是因为你配置里
的存在,打开文件后他会继续进行重新绑定 'org-mac-grab-link 到 org-mode-map 的 RET 上。
最后,你能碰巧成功,估计是先执行了 (define-key org-mode-map (kbd “RET”) 'org-mac-grab-link)), 再执行 (define-key org-mode-map (kbd “RET”) nil) 的结果。
1 个赞
补充: (define-key org-mode-map (kbd “RET”) 'newline)
比较好, 否则回车换行都不行.
我也安利一下我自己写的一个宏,绑定按键比较多的话会比较方便,名字不喜欢的话可以改成自己喜欢的:
宏名: zerolee-set-key,接受任意数量参数,参数可以为: keymap 或 按键绑定
keymap: 符号 或者 长度为 1 的列表
按键绑定:长度大于等于二的列表,形式为(字符串或者数组 ... command)
比如 (zerolee-set-key ("C-s" #'isearch-forward-regexp))
绑定全局快捷键 C-s 到 #'isearch-forward-regexp
上述快捷键也可以如下这样定义:
(zerolee-set-key
(current-global-map)
("C-s" #'isearch-forward-regexp))
连续的 keymap 表示接下来的按键绑定依次在这些 keymap 下进行绑定:
(zerolee-set-key
lisp-interaction-mode-map
emacs-lisp-mode-map
("C-c <return>" #'emacs-lisp-macroexpand)
("C-s" #'isearch-forward-regexp))
在 lisp-interaction-mode-map 下绑定 "C-c <return>" 到 emacs-lisp-macroexpand, "C-s" 到 isearch-forward-regexp
再在 emacs-lisp-mode-map 绑定 绑定 "C-c <return>" 到 emacs-lisp-macroexpand, "C-s" 到 isearch-forward-regexp
按键绑定列表的长度大于二,除最后一个元素为 command 外,其余皆为 key,
整个列表则表示所有的 key 都绑定为 command
(zerolee-set-key
paredit-mode-map
("M-s" "M-r" nil))
将 paredit-mode-map 下的 "M-s", "M-r" 绑定为 nil
keymap, 按键绑定之间的次序,出现次数没有限制
(zerolee-set-key
("C-s" #'isearch-forward-regexp)
lisp-interaction-mode-map
emacs-lisp-mode-map
("C-c <return>" #'emacs-lisp-macroexpand)
paredit-mode-map
("M-s" "M-r" nil))
表示绑定 #'isearch-forward-regexp 到全局 C-s, 在 lisp-interaction-mode-map 和 emacs-lisp-mode-map 下绑定 "C-c <return>" 到 #'emacs-lisp-macroexpand,取消 paredit-mode-map 下的 M-s,M-r
源码:
(defun zerolee-slots->set-key (keymaps slot)
(cl-loop for keymap in keymaps
append
(cl-loop with command = (car (last slot))
for key in (butlast slot)
if (stringp key)
collect `(define-key ,keymap (kbd ,key) ,command)
else
collect `(define-key ,keymap ,key ,command))))
(defmacro zerolee-set-key (&rest slots)
`(progn
,@(cl-loop with keymaps = '((current-global-map))
with last-is-keymap = nil
for slot in slots
if (or (atom slot) (and (consp slot) (= (length slot) 1)))
do (if last-is-keymap
(push slot keymaps)
(setq keymaps (list slot)
last-is-keymap t))
else
append (progn
(setq last-is-keymap nil)
(zerolee-slots->set-key keymaps slot)))))
3 个赞
用 use-package
的话,还可以用 unbind-key
直接用 elisp 的话,还可以参考 Purcell 设置 paredit
的配置:
1 个赞