[转帖]终端下如何让Emacs用上Ctrl+F1, Shift+Up等组合键_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 1727 | 回复: 0   主题: [转帖]终端下如何让Emacs用上Ctrl+F1, Shift+Up等组合键        上一篇   下一篇 
没有名字002
注册用户
等级:新兵
经验:66
发帖:8
精华:0
注册:2016-9-26
状态:离线
发送短消息息给没有名字002 加好友    发送短消息息给没有名字002 发消息
发表于: IP:您无权察看 2019-9-3 16:37:02 | [全部帖] [楼主帖] 楼主

最近常用Putty访问Linux,在上面用Emacs修改代码、运行shell、进行SQL交互,最大的问题是很多组合键(比如我常用的Shift+Up/Down/Left/Right, Ctrl+F1..F12, Ctrl+Home/End)不能使用,春节前两天有些时间,研究了一下这个问题,算是基本找到了一些解决办法。

问题分析
首先需要了解Xterm control sequences这个概念,这个链接中的说明很晦涩,我简单地说明一下:对于有对应 ASCII字符的组合健,就发送对应的ASCII字符,否则用一个特殊序列来表示,比 如 F1 就用 ^[OP (也就是先按Ctrl+[, 然后按O,然后再按P),或者用 ^[[11~ 来表示, C-F7 就用 ^[[18;5~ 表示 。这个序列一般都是以 ESC(也即ASCII码中的27,对应实际按键 ESC 或者 Ctrl+[ ,常写为 \e 或者 ^[ )开始,所以也常常叫做Escape sequences(除了表达按键之外,它还用来表达终端颜色控制)。

当在终端里运行应用程序时,按下一个组合键之后的事情是这样:

终端模拟器将其翻译为对应的Xterm control sequences,发送给对端主机;
对端主机根据 TERM 在terminfo中查找翻译表,翻译为对应的按键信息,传递给应用程序(如果某些组合键在翻译表中找不到,则透传)
应用程序对组合健做出响应。
所以可能存在的问题是:

终端模拟器不能将某些组合键翻译为Xterm control sequences
终端模拟器与terminfo中的翻译表不一致
对于第一个问题
可以用AutoHotKey拦截组合键,自行翻译到control sequences发送出去:

#if WinActive("ahk_class PuTTY") or WinActive("ahk_class mintty")
;;** Ctrl+Fn
^F1::SendInput {ESC}[1;5P
^F2::SendInput {ESC}[1;5Q
^F3::SendInput {ESC}[1;5R
^F4::SendInput {ESC}[1;5S
^F5::SendInput {Esc}[15;5~
^F6::SendInput {Esc}[17;5~
(完整的代码见这里: bamanzi / dotemacs-elite / source / term / putty-ctlseqs.ahk — Bitbucket)


备注一下,我的办公用机是Windows,我用的终端模拟器是putty及其变种 (包括mintty, putty-nd以及MobaXterm)。至于Linux桌面,GNOME Terminal和XFCE Terminal兼容vt102和vt220的组合键,Ctrl+Up, Alt+F1这些大都是支持的(但有少数不支持,但我目前不知道什么工具可以完成类似AutoHotKey这样的功能)

对于第二个问题
对于Emacs而言,我们并不需要直接去解决第二个问题,因为Emacs可以自己将control sequences翻译为其它按键:

(define-key input-decode-map "\eO5P" [C-f1])
(define-key input-decode-map "\eO5Q" [C-f2])
(define-key input-decode-map "\eO5R" [C-f3])
(define-key input-decode-map "\eO5S" [C-f4])
(define-key input-decode-map "\e[15;5~" [C-f5])
(define-key input-decode-map "\e[17;5~" [C-f6])


这里有一个比较完整的包,包含了很多control sequences: http://www.dur.ac.uk/p.j.heslin/Software/Emacs/Download/xterm-extras.el )

补充说明
对于同一个键,可能有多种control sequences,比如F1有^[11~ , ^[[1P和^[OP 这三种序列,但每种终端模拟器只发送其中一种。上面的xterm-extra.el 对光标键提供了CSI和SS3序列的映射,这意味着在多种终端上按这些键都可以正确翻译; 但对于F1..F4只提供了CSI的序列映射,没有提供SS3序列映射(而Putty/Mintty对于F1..F4恰好使用的是CSI序列)。不过反过来比较好的是,不会一个序列对应多种按键。

获取你的终端上某个键的control sequences的简单方法是用cat命令(不过对于少数特殊键和application keypad不好使)

上面的xterm-extra.el里面对keypad序列似乎不是标准的,我没有查到^[z开头的序列,似乎是作者利用了一个尚未使用的序列。不过SS3序列中是有keypad序列的(vim wiki中有一篇相关的贴士: PuTTY numeric keypad mappings - Vim Tips Wiki;
Putty本身对于F1, Shift+F1, Alt+F1, Alt+Shift+F1, 支持挺好,但不支持带Ctrl修饰键的(比如Ctrl+F1, Ctrl+Shift+F1, Ctrl+Alt+F1),如果是Windows平台,可以用AutoHotKey来解决;
对于Ctrl+标点这个列表,部分(比如Ctrl+*, Ctrl+.等)是有control sequences定义的,还有一些(比如Ctrl+!, Ctrl+#, Ctrl+; )则没有正式的control sequences。详细说明可以参考我的配置文件里面的说明: init.d / 80-ports.el。如果要使用,也只能用AutoHotKey来解决 。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论