【问题标题】:Using vim's f command over multiple lines多行使用 vim 的 f 命令
【发布时间】:2015-12-21 23:27:29
【问题描述】:

任何人都知道如何快速找到下一个字符(如 f 命令)但多行? IE。快速跳转到文件中某个字符的下一次出现?

【问题讨论】:

  • summarised some alternatives here,包括我帮助写了屏幕上的闪烁计数
  • 我也在为此苦苦挣扎。这是我在查看这篇文章后所处的位置:如果它在一条线上,它可能更便宜或相当于jk 然后f{char}。如果距离超过一条线,则使用/ 会更便宜。你也可以跳到该行然后f 到它(#Gf{char})。

标签: vim


【解决方案1】:

“/”不就是这样吗?

如果您正在寻找下一个“x”,那么在命令模式下执行 /x。

然后你可以按“n”前进到下一个 x,然后是下一个 x,等等。

有很多 vim cheat sheets 有各种提示。

【讨论】:

  • 谢谢!我实际上知道 / 并且想知道您是否知道更快的方法(对不起,我在最初的问题中没有这么说)。而不是输入 / 然后需要输入 是否有一个单一的关键方法来做到这一点?谢谢!
  • hmm...“fx”是两次击键。击中“/x”是三个击键。在第一场比赛之后,您可以在这两种情况下再一次击键进入后续击球。除了 vi(m) 用户之外,还有谁会对这种低效率感到不安 :) 您是否总是在寻找相同的字符或字符类型?如果是这样,可能会有适合您的解决方案,特别是如果它与编程相关,例如“移动到下一个花括号”
  • @Koko - 答案是,是的,有一个字符可以找到下一个匹配项,即字母“n”。这包含在答案中。
  • 您的答案中没有涵盖的显着差异,dfx 将删除直到并包括x。另一方面,d/x<enter> 将删除最多但不包括 x
【解决方案2】:

在“eval.txt”帮助文件中有一个重新定义f 以忽略大小写的示例。

:h eval.txt

(搜索“忽略大小写”几次)

我们可以修改它来做你想做的事。将以下函数添加到您的 ~/.vimrc 文件或更好的是,创建一个插件文件:~/.vim/plugin/find-char.vim(如果您还没有目录,请创建它们)。

function FindChar()
    let c = nr2char( getchar() )
    let match = search('\V' . c)
endfunction

然后,在您的 ~/.vimrc 中添加以下行:

nmap f :call FindChar()<CR>

现在,f 应该可以按照您的意愿工作了。

顺便说一句,这是在 Ubuntu 10.04 上使用 Vim 7.2 测试的。

【讨论】:

  • 如果您正在搜索 $`, ^` 或 / 等(也可能是星号、询问标记等),这将不起作用。您可以 let command = "normal! /\V" . c . "^M"。还是这样不适用于反斜杠。
  • @Benoit:啊,特殊字符,我应该知道的更好。我已经更新了回复。
  • 如果你只是在每个搜索模式前加上 '\V',你可以跳过 if 语句 -- function FindChar() let c = nr2char( getchar() ) let match = search('\V' .c) 结束函数
  • 如果要将“最后一次搜索”设置为字符,请将其添加到函数中: call setreg("/", c) -- 这样,"n" 和 "p " 此后命令很有用。
  • 您可能还想编写函数和映射,以便 F、t 和 T 命令受到类似影响。
【解决方案3】:

Christian Brabandt 的 ft_improved plugin 也扩展了内置的 f / t 命令以在以下行中进行搜索。

【讨论】:

  • 谢谢,我试过了。但我最终使用了github.com/dahu/vim-fanfingtastic(如果您还安装了github.com/tpope/vim-repeat,它可以与. 命令一起使用)。 9 个月无投诉!
  • 至少对我来说,improvedft 和 vim-fanfiningtastic 都无法处理像 2f, 这样的东西,人们可能希望在下一个之后将光标跳转到逗号。前一个插件在这个序列下什么都不做,而后者只会向前跳一个逗号,而不是两个。
【解决方案4】:

想知道完全相同的事情,我在这里查看了答案。都不是我想要的,所以我拼凑了一些。

q335 的答案是最接近的,因为它可以正确处理 omaps,这对于执行dt} 之类的操作是必要的(删除所有内容,但不包括下一个大括号),但 Curt 的答案处理特殊字符搜索并使用单个函数对我来说更可取,所以我不会在我的 .vimrc 中添加太多

这是我的结果:

"Makes f and t work across multiple lines
nmap <silent> f :call FindChar(0, 0, 0)<cr>
omap <silent> f :call FindChar(0, 1, 0)<cr>
nmap <silent> F :call FindChar(1, 0, 0)<cr>
omap <silent> F :call FindChar(1, 1, 0)<cr>
nmap <silent> t :call FindChar(0, 0, 1)<cr>
omap <silent> t :call FindChar(0, 0, 0)<cr>
nmap <silent> T :call FindChar(1, 0, 1)<cr>
omap <silent> T :call FindChar(1, 0, 0)<cr>

"Functions
fun! FindChar(back, inclusive, exclusive)
  let flag = 'W' 
  if a:back
    let flag = 'Wb'
  endif
  if search('\V' . nr2char(getchar()), flag)
    if a:inclusive
      norm! l
    endif
    if a:exclusive
      norm! h
    endif
  endif
endfun

【讨论】:

  • 似乎工作正常,但它没有保留搜索到的字符供;,使用
  • 关闭花括号的动作:]} - 如果你想删除:d]} - 也适用于括号]) - 打开大括号的动作是 [{
  • 以数字为前缀时对我不起作用,例如c2fa 更改为 first a.
【解决方案5】:

啊啊,vimscript。写好 20 行大约需要 2 年时间:D。这是最新、最时尚的版本:适用于所有模式:视觉、操作员待定、正常。

let prvft='f'
let prvftc=32
fun! MLvF(c,...)
    let [g:prvftc,g:prvft]=[a:c,a:0? 'f':'F']
    let pos=searchpos('\C\V'.nr2char(g:prvftc),'bW')
    call setpos("'x", pos==[0,0]? [0,line('.'),col('.'),0] : [0,pos[0],pos[1],0])
    return "`x"
endfun
fun! MLvf(c,...)
    let [g:prvftc,g:prvft]=[a:c,a:0? 'F':'f']
    let pos=searchpos('\C\V'.nr2char(g:prvftc).(mode(1)=='no'? '\zs' : ''),'W')
    call setpos("'x", pos==[0,0]? [0,line('.'),col('.'),0] : [0,pos[0],pos[1],0])
    return "`x"
endfun
fun! MLvT(c,...)
    let [g:prvftc,g:prvft]=[a:c,a:0? 't':'T']
    let pos=searchpos('\C\V'.nr2char(g:prvftc).'\zs','bW')
    call setpos("'x", pos==[0,0]? [0,line('.'),col('.'),0] : [0,pos[0],pos[1],0])
    return "`x"
endfun
fun! MLvt(c,...)
    let [g:prvftc,g:prvft]=[a:c,a:0? 'T':'t']
    let pos=searchpos('\C\V\_.'.(mode(1)=='no'? '\zs' : '').nr2char(g:prvftc),'W')
    call setpos("'x", pos==[0,0]? [0,line('.'),col('.'),0] : [0,pos[0],pos[1],0])
    return "`x"
endfun
no <expr> F MLvF(getchar())
no <expr> f MLvf(getchar())
no <expr> T MLvT(getchar())
no <expr> t MLvt(getchar())
no <expr> ; MLv{prvft}(prvftc)
no <expr> , MLv{prvft<#'Z'? tolower(prvft) : toupper(prvft)}(prvftc,1)

还是超级乱码:

let [pvft,pvftc]=[1,32]
fun! Multift(x,c,i)
    let [g:pvftc,g:pvft]=[a:c,a:i]
    let pos=searchpos((a:x==2? mode(1)=='no'? '\C\V\_.\zs' : '\C\V\_.' : '\C\V').(a:x==1 && mode(1)=='no' || a:x==-2? nr2char(g:pvftc).'\zs' : nr2char(g:pvftc)),a:x<0? 'bW':'W')
    call setpos("'x", pos[0]? [0,pos[0],pos[1],0] : [0,line('.'),col('.'),0]) 
    return "`x"
endfun
no <expr> F Multift(-1,getchar(),-1)
no <expr> f Multift(1,getchar(),1)
no <expr> T Multift(-2,getchar(),-2)
no <expr> t Multift(2,getchar(),2)
no <expr> ; Multift(pvft,pvftc,pvft)
no <expr> , Multift(-pvft,pvftc,pvft)

【讨论】:

    【解决方案6】:

    解决此问题的一种方法是使用easymotion 插件。

    这使您可以在整个可见文本窗口中使用诸如f 之类的动作。您触发插件,然后输入f 和您要查找的字符。它以突出显示颜色(例如红色)突出显示字符出现在屏幕上的每个位置,并使用字母(abcd,...)显示位置。您只需按与您要跳转的位置对应的字母即可。

    该插件在 Github 上的 README 包含一个动画,可以直观地演示其工作原理。

    【讨论】:

      【解决方案7】:

      您可以进行映射以转到光标下的下一个字符:

      :map f yl/\V<c-r>"<c-m>
      

      \V 将确保符号在字面上匹配。

      此外,您可能需要查看已为您定义的 *# 命令,尽管它们可能不是您想要的。

      【讨论】:

        【解决方案8】:

        目前最合理的做法隐藏在this comment中。

        您只需安装两个插件:vim-repeatvim-fanfingtastic

        就我个人而言,我使用Vundle 来管理我的vim 插件。

        因此,您可以通过这种方式使fF 等按需要工作:

        1. 安装 Vundle。
        2. 将这些行添加到您的.vimrc

          Plugin 'tpope/vim-repeat'
          Plugin 'dahu/vim-fanfingtastic'
          
        3. 在你的 shell 中运行 $ vim +PluginInstall +qall
        4. 瞧!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-07-15
          • 1970-01-01
          • 2013-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多