Alt键快捷键不适用于带有Vim的gnome终端

Jes*_*sse 46 mapping vim terminal gnome alt

我在一个gnome终端上运行Vim.但alt键映射不起作用.
例如(这只是一个例子):

:imap <A-i> <Esc>
Run Code Online (Sandbox Code Playgroud)

它在GVim中工作正常.但是当我在gnome终端中运行与Vim相同的命令时,它就无法工作.
所以我认为问题在于终端,对吗?
我该如何解决?

谢谢

编辑:我在同一台机器上安装了Windows 7,并且使用Windows终端也可以正常工作.

jpn*_*pnp 87

问题

终端仿真器有两种方式发送Alt密钥(通常称为Meta密钥,因为实际终端没有Alt).它可以发送8位字符并在使用Alt时设置高位,或者它可以使用转义序列,发送Alt-a<Esc>a.Vim希望看到8位编码而不是转义序列.

某些终端仿真器(如xterm)可以设置为使用任一模式,但Gnome终端不提供任何此类设置.老实说,在Unicode编辑的这些日子里,8位编码无论如何都不是一个好主意.但转义序列也没有问题; 它们并没有区分的方式<Esc>j含义Alt-jVS压制Esc之后j.

在早期的终端使用中,键入Escj是在没有Meta键的情况下在键盘上发送Meta的另一种方式,但是这不适合vi使用Esc离开插入模式.

解决方案

可以通过配置vim将转义序列映射到其Alt组合来解决此问题.

将其添加到.vimrc:

let c='a'
while c <= 'z'
  exec "set <A-".c.">=\e".c
  exec "imap \e".c." <A-".c.">"
  let c = nr2char(1+char2nr(c))
endw

set timeout ttimeoutlen=50
Run Code Online (Sandbox Code Playgroud)

现在,终端以及gvim中的vi将识别Alt-letter.这些timeout设置用于解决转义序列的歧义. Esc并且j在50ms内发送将被映射到<A-j>,大于50ms将被视为单独的密钥.这应该足以区分Meta编码和击中两个键.

如果您不喜欢设置timout,其他映射键序列超时(默认情况下一秒后),则可以ttimeout改为使用.ttimeout仅适用于键代码而不适用于其他映射.

set ttimeout ttimeoutlen=50
Run Code Online (Sandbox Code Playgroud)

  • 我已经找到了这个设置,如果我处于Cmdline模式或可视模式,如果我按下escape它将执行映射或插入多字节字符.我通过允许自己通过使用以下设置按两次转义离开这些模式来解决这个问题:`vnoremap <Esc> <Cv> <Esc>`和`cnoremap <Esc> <Cc>` (4认同)
  • 如果你在tmux中使用vim并且无法弄清楚为什么上面不能正常工作,那是因为tmux在ESC之后插入一个等待并且它本身会解释密钥代码.在.tmux.conf中放置`set -sg escape-time 0`来禁用此行为. (4认同)
  • 将let更改为'A',将while条件更改为'Z'以映射大写键.如果你愿意,两者都做. (3认同)

yin*_*7zi 6

对于Gnome-terminal,请使用以下代码:

imap ^[i <Esc>
Run Code Online (Sandbox Code Playgroud)

^[i 应该按下键入 Ctrl-v Alt-i

注意:您需要yankputVim当你想在其他地方复制.如果您只是在编辑器中复制映射gedit,那么映射可能会被破坏.

这里编辑是一个例子,它Alt-k在光标上方添加一个空行,并Alt-j在当前行后面添加一个空行.

" Alt-j/k to add a blank line
if has('gui_running')
    " the following two lines do not work in vim, but work in Gvim
    nnoremap <silent><A-j> :set paste<CR>m`o<Esc>``:set nopaste<CR>
    nnoremap <silent><A-k> :set paste<CR>m`O<Esc>``:set nopaste<CR>
else
    " these two work in vim
    " shrtcut with alt key: press Ctrl-v then Alt-k
    " ATTENTION: the following two lines should not be 
    " edited under other editors like gedit. ^[k and ^[j will be broken!
    nnoremap ^[k :set paste<CR>m`O<Esc>``:set nopaste<CR>
    nnoremap ^[j :set paste<CR>m`o<Esc>``:set nopaste<CR>
endif
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢 'imap &lt;esc&gt;i ...' 拼写,这样我的 .vimrc 中就没有控制字符 (2认同)