我使用某款编辑器很多年了,习惯了用 Alt+Return 来选择单词。我无法改变这个习惯,仍然经常在 Vim 中这样做,但总是失败。
所以我尝试这些:
noremap <M-Return> viw
noremap <C-Return> viw
你看,我尝试了 Alt+Return 和 Ctrl+Return。但都没有用。
这有效:
noremap <C-M> viw
我按下 Ctrl+m,单词就被选中了。但这带来了一个奇怪的副作用:单按 Return/Enter 也会选中单词!我不想要那样。
所以这是一个双重问题:
1) 如何让 Alt+Enter 选择当前单词(光标下)?
2)为什么 Return/Enter 的作用与 Ctrl+m 相同?
答案1
由于键盘输入的内部处理方式,遗憾的是,即使在 GVIM 中,这在今天也普遍无法实现。某些组合键(如Ctrl+ 非字母)无法映射,并且无法区分Ctrl+ 字母和Ctrl+ Shift+ 字母。(除非您的终端发送不同的术语表代码,大多数人没有。)在插入或命令行模式下,尝试输入组合键。如果没有任何反应 / 插入,则无法使用该组合键。这也适用于<Tab>
/ <C-I>
、<CR>
/ <C-M>
/ <Esc>
/<C-[>
等。(唯一的例外是<BS>
/ <C-H>
。)这是一个已知的痛点,也是 vim_dev 和 #vim IRC 频道上各种讨论的主题。
有些人(首先是 Paul LeoNerd Evans)想要修复这个问题(即使对于支持该功能的终端中的控制台 Vim),并提出了各种建议,cp。http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8
但截至今天,还没有任何补丁或志愿者提出,尽管许多人表示希望在未来的 Vim 8 主要版本中拥有这一点。
答案2
解决方案取决于你的终端及其设置方式。Unix 终端通常会发送元按住Alt并按下另一个键时,将生成一个字符或序列。向终端程序发送元字符有两种传统方法:
取按下的另一个键(即不是 的键Alt)的 ASCII 值,并将
OR
其与 128 相加(将第 7 位设置为高)。现在不建议这样做,因为生成的 8 位字符代码与 UTF-8 甚至 Latin-1 等 8 位编码不兼容。发送转义字符 ASCII 27,然后发送另一个键的 ASCII 代码。这适用于各种编码,但它会使处理您实际上想要发送显式转义字符的情况变得复杂,例如当您Esc在 Vim 中按下时。
如果您的终端设置为使用 #2,您可能会想这样做noremap <Esc><CR> viw
。但是,这会使 Vim 在收到转义时暂停。为了避免这种情况,您set
可以<A-CR>
关键代码并在 中使用它map
;这使得 Vim 可以将该序列视为不同于转义+字符序列(特别是,该序列的超时时间可以比其他映射使用的超时时间短得多;因为终端几乎同时发送转义字符和以下字符,所以这可以防止在您不尝试时意外触发键代码)。
该set
命令本身会按<Esc>
字面意思解释字符串(即不会将其转换为 ASCII 27),因此您必须将其包装在exec
:
exec "set <A-CR>=\<Esc>\<CR>"
此后,您最终可以进行映射:
noremap <A-CR> viw
您可能还想设置一个非常短的时间ttimeoutlen
,这样您就不会意外触发这个新的映射EscReturn,例如
:set timeout timeoutlen=3000 ttimeoutlen=100
将使“正常”映射在按键之间等待整整 3 秒,但键码映射仅等待十分之一秒。
参考:
:h :set-termcap
:h :map-alt-keys
:h 'ttimeout'
答案3
打开一个终端或者在 vim 中进入插入模式,然后按下<c-v>Return
,你就会看到你的<C-M>
绑定为什么会有这样的效果。
这也应该可以解释为什么您无法绑定<C-Return>
或<M-Return>
在控制台 vim 中(您可能可以在 gvim 中,但我不确定)。