在进入普通模式或 ESC 地图时触发光标定位和选择 [英] Trigger cursor positioning and selection on going to Normal mode or ESC map

查看:41
本文介绍了在进入普通模式或 ESC 地图时触发光标定位和选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道在进入 Normal 时如何从 python 触发光标定位和选择?

Anyone knows how can I trigger cursor positioning and selection from python when going to Normal?

这是脚本我不得不在此提交中注释掉 ESC 映射.

This is the script and I had to comment out the ESC mapping 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 映射在插入模式下在终端中出现箭头键问题,并提供 简单的 InsertLeave 自动命令效果不佳,它的运行速度比映射慢得多,并且未正确设置光标定位以进行选择,因此选择位于错误的位置.

An ESC mapping gives issues with arrows keys in terminal on insert mode, and providing a simple InsertLeave auto command didn't work well, it was operating much slower than the mapping and it wasn't correctly setting cursor positioning to make the selection, so the selection was over the wrong place.

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

I also consider an alternative approach for doing the exact same thing.

推荐答案

TL;DR、set ttimeout=100(或更少)和 InsertLeave 自动命令将被处理得更快(特别是在那么多毫秒).

TL;DR, set ttimeout=100 (or less) and InsertLeave auto-commands will be processed much sooner (specifically, in that many milliseconds).

:imaping 会导致光标键和功能键在插入模式下停止工作,所以不要这样做.随着超时的改进,使用 InsertLeave 自动命令应该是可行的方法.我会尝试帮助解决您提到的光标定位问题,但没有足够的解释来解决它.

:imaping <Esc> will cause cursor keys and function keys to stop working in insert mode, so don't do that. With the improved timeout, using the InsertLeave autocommand should be the way to go. I'd try and help with the cursor positioning problem you mention, but there isn't enough explanation of that to address it.

vim 中有很多与响应按 Esc 相关的设置.Vim 可能会因为两个主要原因而获得转义:

There are a lot of settings in vim that are related to responding to pressing Esc. Vim might receive an escape for two main reasons:

  1. 用户自行按下退出键,或
  2. 用户按下了产生转义序列的箭头键或功能键.

当它在插入模式下看到转义时,vim 不能立即离开插入模式,而是必须等待确定是否存在

When it sees an escape in insert mode, vim cannot leave insert mode immediately but has to wait to find out if it is

  1. 由功能键生成的转义序列的一部分,或
  2. 多键映射的一部分.

为了获得终极的快速转义处理,您可以设置选项 noesckeys 以关闭特殊键 的识别;, 等插入模式.当 vim 处于兼容模式时(你没有 vimrc 时得到的)这是默认行为,并解释了为什么你的 InsertLeave 自动命令被立即处理.该文档指出,esckeys 设置不会影响导致第二个主题的映射的处理.

For the ultimate in fast escape handling you can set the option noesckeys which turns off the recognition of the special keys <Left>, <Right>, <F1>, etc. in insert mode. When vim is in compatible mode (what you got when you had no vimrc) this is the default behavior and explains why your InsertLeave autocommand was processed immediately. The documentation notes that the esckeys settings does not affect the processing of mappings which leads to the second topic.

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

Vim allows you to create a mapping for a sequence of keys, even when some prefix of that sequence is already mapped to some other action (either by another user mapping or a default action). When vim sees a key it will look to see if there is mapping that starts with that key. If there is only one and it is the key on its own, the mapping can be processed immediately. If there are multiple mappings beginning with the key then vim must wait to see if you complete one of the mappings.

除了上面讨论的 esckeys 之外,Vim 有几个选项来控制它是否等待以及等待多长时间.这些是

Besides esckeys discussed above, Vim has several options for controlling whether it waits and for how long. These are

  1. timeout,控制vim是否使用超时来决定映射是否完成;
  2. ttimeout,控制vim是否使用超时来决定转义序列是否完整;
  3. timeoutlen,它控制 vim 等待多久才能查看映射是否完成;和
  4. ttimeoutlen,控制 vim 等待转义序列是否完成的时间.
  1. timeout, which controls whether vim uses a timeout to decide if a mapping is complete;
  2. ttimeout, which controls whether vim uses a timeout to decide if an escape sequence is complete;
  3. timeoutlen, which controls how long vim waits to see if a mapping is complete; and
  4. ttimeoutlen, which control how long vim waits to see if an escape sequence is complete.

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

When timeout is off (notimeout) vim will wait indefinitely for a mapping to be completed. For instance, if notimeout is set and you have a mapping :inoremap teh\ the\ to fix this common type (you would actually use an iabbrev for this in real life), and you typed teh nothing will be added to the buffer until you either press Space, in which case the mapping occurs and the is added to the buffer; or you press some other key, causing the original teh to be added then processing the next key.

ttimeout 选项仅在设置了 notimeout 时才会被查询(每当设置 timeout 时,vim 都使用超时).设置 nottimeout 后,vim 将在获得转义后无限期等待,以查看它是否是转义序列的一部分.如果你设置了 notimeoutnottimeoutshowmode 你可以看到当你在插入模式下按 Esc 时,vim保持插入模式,直到按下某个其他键不是转义序列的一部分.一个愚蠢的技巧是使用这些设置键入 EscO*D(确保您在 xterm 中)并观察光标向左移动.

The ttimeout option is only consulted when notimeout is set (vim uses timeouts for both whenever timeout is set). With nottimeout set, vim will wait indefinitely after getting an escape to see if it is part of an escape sequence. If you set notimeout, nottimeout, and showmode you can see that when you press Esc in insert mode that vim remains in insert mode until some other key is pressed that isn't part of an escape sequence. A silly trick is to type EscO*D with these settings (make sure you are in an xterm) and watch the cursor move to the left.

最后,当它使用超时时,vim 使用 timeoutlenttimeoutlen 来决定等待多长时间.默认设置为 timeoutlen=1000,表示一秒超时,ttimeoutlen=-1 表示使用 timeout 的值.现在,对于映射来说,一秒钟可能没问题,但比识别转义序列所需的时间要长得多.Vim 不会真正离开插入模式,直到它看到转义并且相关的超时已经过期.奇怪的是,vim 会在看到转义后立即删除 showmode 插入模式指示符,但在超时过去之前不会触发 InsertLeave(如果在超时之前看到映射/转义序列,它将重新添加指示符过期).vim 文档建议尝试 ttimeoutlen=100 但我认为你可以更短,例如50,没有任何弄乱特殊键的问题.

Finally, when it is using timeouts, vim uses timeoutlen and ttimeoutlen to decide how long to wait. The defaults settings are timeoutlen=1000, which means a one second timeout, and ttimeoutlen=-1 which means use the value of timeout. Now, one second is probably ok for the mappings but is way longer than is needed for recognizing escape sequences. Vim doesn't truly leave insert mode until it sees the escape and the relevant timeouts have expired. Oddly, vim will remove the showmode insert mode indicator right away after seeing the escape but not fire InsertLeave until after the timeout has passed (it adds the indicator back if a mapping/escape sequence is seen before the timeout expires). The vim documentation suggests trying ttimeoutlen=100 but I think you could go even shorter, e.g. 50, without any problems with messed up special keys.

既然我已经研究了这个,我将四处走动,确保在我使用 vim 的每个地方都设置 ttimeoutlen=50,甚至可能设置更低的 timeoutlen.

Now that I've researched this I'm going to go around and make sure I set ttimeoutlen=50 everyplace I use vim and maybe even lower timeoutlen too.

这篇关于在进入普通模式或 ESC 地图时触发光标定位和选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆