python - 在进入普通模式或ESC map 时触发光标定位和选择

标签 python vim vim-plugin

有人知道在转到“普通”时如何从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自动命令的效果不佳,它的运行速度比映射慢得多,并且没有正确设置光标位置来进行选择,所以选择的地方不对。

我还考虑了另一种方法来做完全相同的事情。

最佳答案

TL; DR,set ttimeout=100(或更少)和InsertLeave自动命令将更快地处理(特别是在几毫秒内)。

:imap ing <Esc>将导致光标键和功能键在插入模式下停止工作,因此请不要这样做。随着改进的超时,应该使用InsertLeave自动命令。我会尽力帮助您提到的光标定位问题,但是对此的解释不足。

vim中有许多与响应按Esc有关的设置。 Vim可能会因以下两个原因而逃脱:


用户自行按下逃逸键,或者
用户按下箭头键或功能键会产生一个转义序列。


当在插入模式下看到转义符时,vim无法立即退出插入模式,而必须等待找出是否已退出。


由功能键生成的转义序列的一部分,或者
多键映射的一部分。


要获得最终的快速转义处理,您可以设置选项noesckeys,以在插入模式下关闭对特殊键<Left><Right><F1>等的识别。当vim处于兼容模式时(没有vimrc时得到的信息),这是默认行为,并说明了为什么立即处理InsertLeave自动命令。该文档指出esckeys设置不会影响映射的处理,这导致了第二个主题。

Vim允许您为键序列创建映射,即使该序列的某个前缀已经映射到其他操作(通过另一个用户映射或默认操作)。当vim看到一个密钥时,它将查看是否存在以该密钥开头的映射。如果只有一个,并且它本身就是密钥,则可以立即处理映射。如果有多个以键开头的映射,那么vim必须等待以查看是否完成了其中一个映射。

除了上面讨论的esckey之外,Vim还有几个选项可以控制是否等待以及等待多长时间。这些是


超时,它控制vim是否使用超时来决定映射是否完成;
ttimeout,控制vim是否使用超时来确定转义序列是否完成;
timeoutlen,它控制vim等待多长时间以查看映射是否完成;和
ttimeoutlen,它控制vim等待多长时间以查看转义序列是否完成。


当超时关闭(notimeout)时,vim将无限期地等待映射完成。例如,如果设置了notimeout,并且您有一个映射:inoremap teh\ the\来解决此常见类型(您实际上在现实生活中实际上会使用iabbrev),并且键入teh,则不会有任何内容添加到缓冲区中按空格键,在这种情况下,将发生映射,并且将the添加到缓冲区中;或按其他某个键,导致添加原始teh,然后处理下一个键。

仅当设置了notimeout时才使用ttimeout选项(只要设置了超时,vim都会使用超时)。设置nottimeout时,vim在获得转义后将无限期等待,看它是否属于转义序列的一部分。如果设置了notimeout,nottimeout和showmode,则可以看到在插入模式下按Esc时,vim会保持在插入模式下,直到按下不属于转义序列的其他键为止。一个愚蠢的技巧是使用这些设置键入EscO * D(确保您使用的是xterm),然后观察光标向左移动。

最后,当使用超时时,vim使用timeoutlen和ttimeoutlen来决定等待多长时间。默认设置为timeoutlen=1000(表示一秒超时)和ttimeoutlen=-1(表示使用超时值)。现在,一秒钟的映射可能还可以,但是比识别转义序列所需的时间更长。 Vim不会真正退出插入模式,直到看到转义并且相关的超时时间已到。奇怪的是,vim会在看到转义后立即删除showmode插入模式指示符,但直到超时结束后才触发InsertLeave(如果在超时到期之前看到了映射/转义序列,它将把指示符增加回来)。 vim文档建议尝试ttimeoutlen=100,但我认为您可以更短一些,例如50,没有任何麻烦,弄乱了特殊键。

现在,我已经研究了这一点,我将继续研究并确保在使用vim的每个地方都设置ttimeoutlen=50,甚至可能减少timeoutlen。

关于python - 在进入普通模式或ESC map 时触发光标定位和选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22425596/

相关文章:

线程脚本中的 Python 脚本 open_sftp_client 错误

python - 将Elasticsearch查询结果划分成大块?

python - Django:将 key 放入 crontab 文件

regex - 替换模式并在数字周围添加方括号

python - Vim 语法显示 Python VirtualEnv 库的导入错误

vim - 当我使用 Janus vim 处理 golang 文件时,如何在 Vim 中删除此消息?

python - Tkinter - 在 TextWidget 中设置当前选择

perl - 在 Vim 中,如何避免将 "/*"视为注释

regex - Vim 正则表达式捕获组 [bau -> byau : ceu -> cyeu]

java - 在 Vim 中编码 java 时,如何在编辑时直接在 vim 中显示代码输出