问题阐述
配置nvim快捷键时遇到了如下问题。动机是设置<C-`>作为唤起终端(ToggleTerm)的快捷键。最初的设置如下:
1 | require("toggleterm").setup({ |
这个设置在Debian系统中工作良好,无论是本地还是远程连接。但是用windows终端(无论是自带的cmd窗口终端,windows terminal还是wezterm)远程连接linux服务器时,这个快捷键永远是失效的。
原因说明
排查后发现原因是控制键(Ctrl)的组合键在Windows和UNIX系统下遵守的协议是不同的。区别可以参考Wikipedia。其区别体现在<C-Key>的组合键输入给系统的字符是不一样的。可以在终端输入<C-v><C-Key>来测试<C-Key>输入的对应字符。
幸运的是,windows terminal可以设置Ctrl组合键的行为,其中包含输入特定字符的接口。因此绝大部分UNIX的Ctrl组合键可以通过绑定来实现。Emac的快捷键和Ctrl控制键绑定很深,因此社区中有对该设置的讨论,例如issue。
不幸的是,UNIX系统中的<C-`>打出的字符是^@,对应的是NULL(\u0000)。因此通过windows terminal的设置来绑定是无效的(fuck me)。
解决方案
将windows中输入的<C-`>在UNIX终端中输出的字符也绑定为ToggleTerm的快捷键。测试得到输出的字符串是<C-Space>,因此以下设置可以实现目标:
1 | require("toggleterm").setup({ |
这个设置的代价是<C-Space>不能再绑定其他动作。注意'<C-\\><C-n>:ToggleTerm<CR>'的设置,在终端模式下需要先退出让nvim接管输入再调用命令。
Final
除非vscode中毒,用windows终端时推荐不要配置<C-`>作为快捷键,<C-b>之类都是更好的选择。