使用终端时的绑定问题


30

我在以下行中init.el

(global-set-key [(control \;)] 'comment-region)

它在GUI窗口中效果很好,但是如果emacs使用该-nw选项调用,C-;则不注释区域,仅插入;字符。M-x comment-region RET工作正常。

我尝试按照类似的问题回答此问题,但C-q C-;只返回了,;而我显然不想裸露;

如何达到理想的效果?


4
您的终端(顺便说一句,您正在使用什么?)可能无法识别该命令序列。尝试使用C-;组合,然后使用M-x view-lossage它来查看Emacs。

我正在使用gnome-terminal,并M-x view-lossage返回:ESC [ > 1 ; 2 8 0 2 ; 0 c ; ESC x v i e w - l o s s a g e RET
WeSenseASoulInSearchOfAnswers 2014年

3
看起来像是一个终端问题:如果该组合键到达了Emacs,它将看起来像C-;而不是c ;(或者,至少我知道C-;)。

@丹:你能回答这个问题吗?这样可以将问题标记为已回答,并使查看解决方案变得更容易,这对其他遇到相同问题的人也很有帮助。谢谢!
Tikhon Jelvis,2014年

总结并发布了附加链接,以供更多阅读。还编辑问题标题以使其更通用。

Answers:


17

首先,更普遍的问题是:终端仿真器通常在它们可以发送的控制和转义序列中受到限制。因此:终端可能会在您的特殊字符到达Emacs之前吞下它们。作为一般诊断,您可以按C-h l(或M-x view-lossage)查看您的按键组合是否进入了Emacs。

有关此问题的更多讨论,请查看此Stack Overflow线程及其中的链接。

总而言之,您的特定问题表明问题是终端而不是Emacs。当您尝试C-;然后M-x view-lossage,您得到了blah blah blah c ; ESC v i e w - l o s s a g e RET。这似乎是一个终端问题:如果组合键已到达Emacs,则该c ;部分将看起来像C-;


33

终端机中,Emacs无法识别Shift + Up,我解释了终端机如何将大多数功能键转换为转义序列,因为应用程序和终端机之间的接口传输的是字符(或字节),而不是键。只有几个修饰符+字符组合具有自己的特征:

  • Ctrl再加上一个字母或一个字母@[\]^_变成0-31个字节(ASCII 控制字符)。
  • 通常Ctrl+ ?变成字节127,而Ctrl+ Space等效于Ctrl+ @(字节0)。
  • 一些功能键等效于控制字符:Tab= Ctrl+ IReturn= Ctrl+ MEsc= Ctrl+ [
  • Backspace= Ctrl+ HCtrl+ ?取决于配置。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 uESC [ 2 7 ; modifier ; codepoint ~formatOtherKeysmodifyOtherKeys

如果您的终端仿真器不支持这些语法,但是可以配置,请选择其中一个。

从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


2
Gilles,您在这个问题上的回答总是很棒。非常感激。
2015年

大!。尽管我很难找到如何使urxvt发送这些序列的方法。你能帮我一下吗:)
Amos

@Amos我不使用rxvt。您应该在Unix和Linux上询问如何使urxvt使用ModifyOtherKeys发送与xterm相同的转义序列。
吉尔(Gilles)'所以

不适用于macOS xterm-256color。M-C-%认识到ESC 5
LoranceChen

@LoranceChen如果该modifyOtherKeys功能未激活,这是预期的行为。请注意,它仅在最新版本的xterm中受支持,并且仅从Emacs 24.4起才自动激活。我不知道OSX是否附带最新版本。如果不行,并且对您不起作用,建议您提出一个新问题。提及您使用的版本。
吉尔斯(Gillles)“所以-别再作恶了”

2

吉尔斯的回答说:On OSX, you can configure iTerm2 by selecting an escape sequence for each key combination, one by one. 我到那里有点麻烦,所以这里有一个详细的解释,以防你像我一样困惑。

如果在终端(例如Mac的默认Terminal.app)中运行Emacs时C-x C-;没有运行comment-line,而您想要该功能,则必须切换到iTerm2(Terminal.app不具备此功能)并创建密钥映射在个人资料...键下,如下所示:

^;     ^[[59;5u

这是通过单击+按钮来完成的,该按钮会弹出一个称为“键盘快捷键”的小窗口。此窗口最初有两个字段;顶部的值为“单击以设置”,底部的值为“忽略”。单击顶部按钮,然后键入C-;。这将设置将运行操作和代码的组合键。单击底部字段“动作”,然后找到并单击“发送转义序列”,该过程略微超过一半。单击该按钮后,将出现第三个字段,称为“ Esc +”。在此字段中,键入:

[59;5u

59是逗号十进制ASCII码,而5对于代码Ctrl。然后按“确定”完成。现在,iTerm2的首选项中将包含正确的组合键序列。现在,在iTerm中启动Emacs时,您将可以使用C-x C-;功能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.