在终端机中,Emacs无法识别Shift + Up,我解释了终端机如何将大多数功能键转换为转义序列,因为应用程序和终端机之间的接口传输的是字符(或字节),而不是键。只有几个修饰符+字符组合具有自己的特征:
- Ctrl再加上一个字母或一个字母
@[\]^_
变成0-31个字节(ASCII 控制字符)。
- 通常Ctrl+ ?变成字节127,而Ctrl+ Space等效于Ctrl+ @(字节0)。
- 一些功能键等效于控制字符:Tab= Ctrl+ I,Return= Ctrl+ M,Esc= Ctrl+ [。
- 和Backspace= Ctrl+ H或Ctrl+ ?取决于配置。Ctrl+ ?对Emacs更方便,因为Ctrl+ H是帮助。
- Meta+ character发送,Esc后跟字符。
那么其他组合(例如Ctrl+ ;或Ctrl+ Shift+)letter呢?由于没有对应的字符,终端必须重用一个字符或发送一个转义序列。当没有相应的字符时,许多终端会忽略修饰符,因此最终会出现Ctrl+ ;发送;
,Ctrl+ Shift+ letter等价于Ctrl+ letter等的情况。
终端供应商长期以来一直在做简单的事情。没有转义序列的标准,它是永续的-终端供应商不实施它,应用程序不支持它,用户不期望它。可以将某些终端仿真器配置为发送任意转义序列,因此,如果可以的话,可以对其进行配置,然后将转义序列声明给Emacs(稍后将对此进行详细介绍)。
最近,情况正在发生变化,因为已经有两个建议对转义序列进行标准化。一个是LeoNerd的libtermkey,其语法为。另一个是Thomas Dickey的xterm语法。通过设置资源,可以为两种语法配置当前版本的xterm(≥216)。必须通过将设置为非零值来激活该功能。ESC [ codepoint ; modifier u
ESC [ 2 7 ; modifier ; codepoint ~
formatOtherKeys
modifyOtherKeys
如果您的终端仿真器不支持这些语法,但是可以配置,请选择其中一个。
从Emacs 24.4开始,当Emacs modifyOtherKeys
检测到终端为xterm版本≥216时,它将自动打开该功能。Emacs对转义序列进行检测以对密钥进行编码的过程通过变量完成local-function-key-map
。从Emacs 24.4开始,并非所有转义序列都受支持。您可以在init文件中使用以下代码来完成作业。
;; xterm with the resource ?.VT100.modifyOtherKeys: 1
;; GNU Emacs >=24.4 sets xterm in this mode and define
;; some of the escape sequences but not all of them.
(defun character-apply-modifiers (c &rest modifiers)
"Apply modifiers to the character C.
MODIFIERS must be a list of symbols amongst (meta control shift).
Return an event vector."
(if (memq 'control modifiers) (setq c (if (or (and (<= ?@ c) (<= c ?_))
(and (<= ?a c) (<= c ?z)))
(logand c ?\x1f)
(logior (lsh 1 26) c))))
(if (memq 'meta modifiers) (setq c (logior (lsh 1 27) c)))
(if (memq 'shift modifiers) (setq c (logior (lsh 1 25) c)))
(vector c))
(defun my-eval-after-load-xterm ()
(when (and (boundp 'xterm-extra-capabilities) (boundp 'xterm-function-map))
(let ((c 32))
(while (<= c 126)
(mapc (lambda (x)
(define-key xterm-function-map (format (car x) c)
(apply 'character-apply-modifiers c (cdr x))))
'(;; with ?.VT100.formatOtherKeys: 0
("\e\[27;3;%d~" meta)
("\e\[27;5;%d~" control)
("\e\[27;6;%d~" control shift)
("\e\[27;7;%d~" control meta)
("\e\[27;8;%d~" control meta shift)
;; with ?.VT100.formatOtherKeys: 1
("\e\[%d;3u" meta)
("\e\[%d;5u" control)
("\e\[%d;6u" control shift)
("\e\[%d;7u" control meta)
("\e\[%d;8u" control meta shift)))
(setq c (1+ c))))))
(eval-after-load "xterm" '(my-eval-after-load-xterm))
如果TERM
环境变量未设置为xterm
或诸如的变体xterm-256color
,则Emacs不会激活这些序列。如果Emacs已经支持您的值TERM
,则可以通过定义与上述功能相似的功能来添加支持,该功能将在加载名称为的Lisp文件TERM
后执行。如果Emacs有没有这样的支持,您可以通过创建一个名为的子目录添加它term
某处你load-path
,并创建一个名为Lisp的文件term/$TERM.el
,其中$TERM
的价值TERM
,定义调用的函数terminal-init-$TERM
。
在我撰写本文时,似乎除了xterm之外,几乎没有其他终端仿真器采用了这些转义序列。在OSX上,可以通过为每个组合键一个接一个地选择转义序列来配置iTerm2。
C-;
组合,然后使用M-x view-lossage
它来查看Emacs。