任何人都知道如何在转到Normal时从python触发光标定位和选择?
这是the script,我必须注释掉 ESC 映射in this commit。
相关的插件源代码如下:
# -*- coding: utf-8 -*-
import re
import vim
#How can we fetch the first param on going to normal Mode without problems?!
vim.command( "inoremap <silent> <buffer> <esc> <c-\><c-n>:py clang_complete.firstParam()<cr>" )
r = re.compile( "@[^@]+\$" )
def firstParam():
line = vim.current.line
row, col = vim.current.window.cursor
result = r.search(line)
if result is None:
vim.command('call feedkeys("\<esc>", "n")')
return
selectParams( *result.span() )
def selectParams( start, end ):
row, _ = vim.current.window.cursor
vim.current.window.cursor = row, start
isInclusive = vim.options["selection"] == "inclusive"
vim.command( 'call feedkeys("\<c-\>\<c-n>v%dl\<c-g>", "n")' %
( end - start - isInclusive ) )
ESC 映射在插入模式下终端中的箭头键出现问题,并且提供simple InsertLeave自动命令并不能正常工作,它的运行速度比映射慢得多并且没有正确设置光标定位来进行选择,因此选择位置错误。
我也考虑采用另一种方法来做同样的事情。
答案 0 :(得分:2)
TL; DR,set ttimeout=100
(或更少)和InsertLeave自动命令将更快地处理(具体地说,在那么多毫秒内)。
:imap
<Esc>
会导致光标键和功能键在插入模式下停止工作,所以不要这样做。使用改进的超时,使用InsertLeave自动命令应该是要走的路。我试着帮助解决你提到的光标定位问题,但是没有足够的解释来解决这个问题。
vim中有很多与响应按 Esc 相关的设置。 Vim可能会因为两个主要原因而逃脱:
当它在插入模式下看到转义时,vim不能立即离开插入模式但必须等待查明是否
为了实现快速逃脱处理,您可以设置 noesckeys 选项,以关闭对特殊键<Left>
,<Right>
,<F1>
的识别,插入模式等。当vim处于兼容模式时(没有vimrc时你得到的)这是默认行为,并解释了为什么你的InsertLeave自动命令被立即处理。该文档指出 esckeys 设置不会影响导致第二个主题的映射处理。
Vim允许您为一系列键创建映射,即使该序列的某些前缀已经映射到某个其他操作(通过另一个用户映射或默认操作)。当vim看到一个键时,它会查看是否有以该键开头的映射。如果只有一个并且它本身就是密钥,则可以立即处理映射。如果有多个以键开头的映射,那么vim必须等待,看看你是否完成了其中一个映射。
除了上面讨论的 esckeys 之外,Vim还有几个选项来控制它是否等待以及持续多长时间。这些是
当超时关闭( notimeout )时,vim将无限期地等待映射完成。例如,如果设置了 notimeout 并且您有一个映射:inoremap teh\ the\
来修复此常见类型(实际上您实际上会使用iabbrev
),并且您输入了 t e h 在您按 Space 之前,不会向缓冲区添加任何内容,在这种情况下,映射会发生并且the
被添加到缓冲区;或者按其他键,导致添加原始teh
,然后处理下一个键。
仅当 notimeout 设置时才会查看 ttimeout 选项(只要设置了 timeout ,vim就会使用超时)。设置 nottimeout 后,vim会在获得转义后无限期地等待,看它是否是转义序列的一部分。如果您设置 notimeout , nottimeout 和 showmode ,您可以看到在插入模式下按 Esc 时vim保持插入模式,直到某个其他键被按下,它不是转义序列的一部分。一个愚蠢的技巧是使用这些设置键入 Esc O * D (确保您在xterm中)并观察光标向左移动。
最后,当它使用超时时,vim使用 timeoutlen 和 ttimeoutlen 来决定等待的时间。默认设置为timeoutlen=1000
,表示暂停一秒,ttimeoutlen=-1
表示使用超时的值。现在,对于映射,一秒钟可能没问题但是比识别转义序列所需的时间长。 Vim并没有真正离开插入模式,直到它看到逃脱并且相关的超时已经过期。奇怪的是,vim会在看到转义后立即删除 showmode 插入模式指示符但不会在超时过后直接触发InsertLeave(如果在超时之前看到映射/转义序列,它会添加指示符到期)。 vim文档建议尝试ttimeoutlen=100
,但我认为你可以更短,例如50,没有任何问题搞乱特殊键。
现在我已经研究了这个,我会四处走动,确保我设置ttimeoutlen=50
我使用vim的所有地方,甚至可能更低 timeoutlen 。< / p>