【问题标题】:emacs keybinding doesn't work in terminalemacs 键绑定在终端中不起作用
【发布时间】:2016-12-08 12:22:50
【问题描述】:

我在 .emacs 文件中设置了以下键绑定:

(global-set-key (kbd "C-S-M-w") 'windmove-up)
(global-set-key (kbd "C-S-M-s") 'windmove-down)
(global-set-key (kbd "C-S-M-d") 'windmove-right)
(global-set-key (kbd "C-S-M-a") 'windmove-left)

(global-set-key (kbd "C-S-a") 'shrink-window-horizontally)
(global-set-key (kbd "C-S-d") 'enlarge-window-horizontally)
(global-set-key (kbd "C-S-s") 'shrink-window)
(global-set-key (kbd "C-S-w") 'enlarge-window)

当它们在自己的窗口中时,它们工作得很好。但是,如果我在终端(emacs -nw)中运行它,则不会加载键绑定。即使在加载 .emacs 文件后,我仍然没有键绑定。

当我使用 emacs 守护程序并在客户端和终端中打开时,情况也是如此。如果这很重要,我在一台 linux 机器上。

【问题讨论】:

    标签: emacs terminal key-bindings


    【解决方案1】:

    问题不在于 emacs,问题在于修饰键(Control、Shift 和 Alt)的组合在大多数终端程序中表现不佳。类似的问题不断出现在这里和许多其他地方,包括超级用户,例如:emacs - [control shift up] doesn't workhttps://superuser.com/q/230852。您需要在您的特定终端中对其进行测试 - 但例如检查 Gnome 终端表明 C-S-C- 无法区分,因此您的大多数绑定甚至都无法正确使用 emacs

    如果您需要说服自己,请使用C-h k,然后使用您缺少的组合。您会看到,当您在终端中运行时,这些组合会去掉一些修饰符。

    我也经历过类似的经历,得出的结论是与终端战斗不值得。当您在终端中时,我建议您将需要多个修饰符的组合键重新映射到其他内容。 (例如,我最终将 windmove 命令重新映射到 F 键。)或者,我可以推荐使用 evil leader 键(如果您使用 evil),或者 God mode 否则。这大大减少了对多个修饰符的需求。

    【讨论】:

      【解决方案2】:

      xterm 可以做到这一点;其他终端不能。

      如果您将目标更改为使用功能键,您可以走得更远,因为在不更改配置的情况下,xterm 会为修饰符 shift的各种组合发送不同的转义序列>、controlaltmeta 应用于功能键和光标键。

      “终端”的嫌疑人可能是基于 VTE 的终端仿真器之一,例如 gnome-terminal。这复制了 xterm 这部分行为的相当大的一部分,因此您可以试验 function-keys 的配置,决定什么是有意义的并使用这些设置。

      VTE 的行为未记录在案。不过你可以在XTerm Control Sequences阅读原文。

      【讨论】:

        【解决方案3】:

        第一步是让您的终端发送转义码,您可以稍后在 emacs 中为其指定含义。编辑您的 .Xdefaults 文件以根据需要添加任意数量的这些文件。这是一个使用 xterm 的示例(可能有错别字,因为我无法从我的工作 PC 上剪切和粘贴):

        *VT100*translations: #override \n\
            ~Ctrl ~Shift <KeyPress> BackSpace: string(0x7F)\n\
            Ctrl ~Shift <KeyPress> BackSpace: string("\033[27;5;8~")\n\
            Ctrl Shift <KeyPress> BackSpace: string("\033[27;6;8~")\n
        
            Ctrl Shift ~Meta <KeyPress> A: string("\033[27;6;65~")\n\
            ...
            Ctrl Shift ~Meta <KeyPress> Z: string("\033[27;6;90~")\n\
        
            Ctrl Shift Meta <KeyPress> A: string("\033[27;8;65~")\n\
            ...
            Ctrl Shift Meta <KeyPress> Z: string("\033[27;8;90~")\n\
        
        XTerm*vt100.modifyOtherKeys: 1
        XTerm*vt100.formatOtherKeys: 0
        

        键序列可以是任何东西(我见过很多未记录的键序列),但可以在这里找到最接近“标准”的东西:http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

        第二步是让 emacs 将这些新的转义序列分配给它理解的键序列:

        ; xterm-specific options
        (unless window-system
            (define-key key-translation-map "\C-[[27;6;65~" (kbd "C-S-a"))
            ...
            (define-key key-translation-map "\C-[[27;6;90~" (kbd "C-S-z"))
        
            (define-key key-translation-map "\C-[[27;8;65~" (kbd "C-M-S-a"))
            ...
            (define-key key-translation-map "\C-[[27;8;90~" (kbd "C-M-S-z"))
        
            ; other xterm-specific options here
        )
        

        ... 内,将~ 之前的最后一个数字加一,因此 A=65, B=66, ..., Z=90。

        【讨论】:

        • 类似的东西。但它仅适用于 xterm,并且 OP 可能认为“终端”是一个不同的程序。
        • @ThomasDickey 正如您在回答中提到的那样,许多终端仿真器在某种程度上复制了 xterm 的行为,尽管它们经常为自己的目的捕获组合键。很可能 OP 没有意识到终端的局限性,可能想尝试其他终端(如 xterm),看看它们是否更合适。
        • 这就是我回答的原因(比制作 cmets 更好)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-07
        • 1970-01-01
        • 1970-01-01
        • 2012-06-02
        相关资源
        最近更新 更多