最近使用fzf.el插件,里面使用了term,想要映射ESC实现退出term的功能,发现C-g实现了该功能。所以想一下term-mode的keymap是啥,晚上搜到term-raw-keymap但是emacs 26.1说不存在这个符号,还有我该怎么查看C-g在term下对应的函数,C-h k不起作用啊
C-h l
能不能看到是什么命令?
可以看一下我的 multi-term.el 的代码
C-h b
可以看到当前的绑定键信息,也可以看下。
keymap 可以尝试看下他的源码,通过关键字应该比较快就能找到了(可以先查看他的某个函数信息,然后在 help buffer中点击跳转过去)
term 的按键是直接接到用户的事件, 直接把事件序列转换给 shell , 不像传统模式那样有很多 keymap 对应很多事件。
(defcustom term-bind-key-alist
'(
("C-c C-c" . term-interrupt-subjob)
("C-c C-e" . term-send-esc)
("C-p" . previous-line)
("C-n" . next-line)
("C-s" . isearch-forward)
("C-r" . isearch-backward)
("C-m" . term-send-return)
("C-y" . term-paste)
("M-f" . term-send-forward-word)
("M-b" . term-send-backward-word)
("M-o" . term-send-backspace)
("M-p" . term-send-up)
("M-n" . term-send-down)
("M-M" . term-send-forward-kill-word)
("M-N" . term-send-backward-kill-word)
("<C-backspace>" . term-send-backward-kill-word)
("M-r" . term-send-reverse-search-history)
("M-d" . term-send-delete-word)
("M-," . term-send-raw)
("M-." . comint-dynamic-complete))
"The key alist that will need to be bind.
If you do not like default setup, modify it, with (KEY . COMMAND) format."
:type 'alist
:group 'multi-term)
上面是 multi-term.el 定义按键的 keymap
(defun multi-term-keystroke-setup ()
"Keystroke setup of `term-char-mode'.
By default, the key bindings of `term-char-mode' conflict with user's keystroke.
So this function unbinds some keys with `term-raw-map',
and binds some keystroke with `term-raw-map'."
(let (bind-key bind-command)
;; Unbind base key that conflict with user's keys-tokes.
(cl-dolist (unbind-key term-unbind-key-list)
(cond
((stringp unbind-key) (setq unbind-key (read-kbd-macro unbind-key)))
((vectorp unbind-key) nil)
(t (signal 'wrong-type-argument (list 'array unbind-key))))
(define-key term-raw-map unbind-key nil))
;; Add some i use keys.
;; If you don't like my keystroke,
;; just modified `term-bind-key-alist'
(cl-dolist (element term-bind-key-alist)
(setq bind-key (car element))
(setq bind-command (cdr element))
(cond
((stringp bind-key) (setq bind-key (read-kbd-macro bind-key)))
((vectorp bind-key) nil)
(t (signal 'wrong-type-argument (list 'array bind-key))))
(define-key term-raw-map bind-key bind-command))))
这个函数是做按键绑定的, 要用 define-key 来 unbind 和 bind 按键到 term-raw-map 中, 关键是
(add-hook 'term-mode-hook 'multi-term-keystroke-setup)
你只能在 term-mode 运行的时候用 term-mode-hook 去挂在按键, 而不是像传统那样直接设置 term-raw-map , term 外面访问不到这个函数。
要自定义按键都需要像 mult-term.el 里面,
(defun term-send-M-x ()
"Type M-x in term-mode."
(interactive)
(term-send-raw-string "\ex"))
用 term-send-raw-string 去发送按键序列, 你是不可能直接指定 term 执行什么代码的, term 只接受按键序列。
3 个赞
我建议你直接基于 multi-term.el 来改进, 用 term-send-raw-string 来发送 Ctrl + D, 然后直接自定义 multi-term.el 的 term-bind-key-alist 这个按键变量, 把发送 Ctrl + D的函数绑定到 Esc 按键上, 比你自己折腾 term.el 要快很多。
1 个赞