2010-10-13 49 views
34

任何人都知道如何快速找到下一次出现的字符(如f命令),但多行?即快速跳转到文件中某个字符的下一个出现位置?在多行中使用vim的f命令

+1

我[这里总结了一些替代方法](http://vi.stackexchange.com/questions/4486/expand-f-and-t-motion-to-next-lines#4525),其中包括我帮忙写的一个哪个*闪烁计数*在屏幕上! – joeytwiddle 2016-03-10 10:03:42

回答

35

这不就是“/”么?

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

然后你就可以点击“N”以前进到下一个x,然后在下一个X等

有很多VIM cheat sheets有各种提示在那里的。

+0

谢谢!我其实知道/并想知道你是否知道更快的方法(抱歉,我没有在原始问题中说过)。而不是键入/然后需要键入是否有一个关键的方法来做到这一点?谢谢! – Koko 2010-10-13 15:48:28

+4

嗯......“fx”是两个按键。击中“/ x ”是三个击键。在第一场比赛之后,你可以在两种情况下进行一次击键。除了vi(m)用户可能会因为效率低下而感到沮丧:)你是否总是在寻找相同的角色或角色类型?如果是这样,可能会有解决方案,特别是如果它是编程相关的,如“移动到下一个大括号” – 2010-10-13 17:28:24

+0

@Koko - 答案是,是的,有一个字符可以找到下一个事件,字母'n' 。这包括在答案中。 – KevinDTimm 2010-10-14 00:34:02

12

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

: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测试的。

+1

如果您正在搜索'''','',''''或'/'以及其他(也可能是星号,询问标记等等),这将不起作用。您可以'let command =“normal!/ \ V” c。“^ M”'仍然不能用于反斜杠。 – Benoit 2010-10-14 06:57:20

+2

@Benoit:啊,特殊的角色,我应该知道的更好。我已经更新了回复。 – 2010-10-14 11:10:16

+1

如果您只是将每个搜索模式加上'\ V',您可以跳过if语句 - 函数FindChar() let c = nr2char(getchar()) let match = search('\ V'。c) endfunction – 2010-10-14 17:16:31

1

你可以做一个映射去到下一个字符光标下:

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

的符\ v将确保符号字面匹配。

此外,您可能想看看*#命令,这些命令已经为您定义,但它们可能不是您想要的。

4

Aaaa,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

已经想清楚地知道我经历的答案在这里看同样的事情。没有一个是我想要的,所以我拼凑了其中的一些。

Q335的答案是最接近的,因为它处理omaps妥善这是必要像做dt}(删除了一切,但不包括下一个大括号),但科特的回答处理特殊字符的搜索和使用一个单一的功能,以我更加可取,所以我不会给我添加太多东西。的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 
+0

似乎可以正常工作,但它并没有保留搜索字符供''''和',' – joeytwiddle 2013-07-02 06:33:44

+0

运动来关闭大括号:]} - 如果您想删除:d]} - 也适用于parens] ) - 打开大括号的动作是[{ – 2013-09-18 07:19:43

+0

当用数字前缀时不适用于我,例如'c2fa'变成_first_'a'。 – 2014-07-11 10:37:12

5

基督教Brabandt的ft_improved plugin扩展了内置f/t命令在以下行进行搜索了。

+3

谢谢,我试过了。但是我最终使用了http://github.com/dahu/vim-fanfingtastic(如果你还安装了http://github.com/tpope/vim-repeat),它可以使用'.'命令。 9个月没有投诉! – joeytwiddle 2014-03-03 09:09:51

1

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

你只需要安装两个插件:vim-repeatvim-fanfingtastic。我使用Vundle来管理我的vim插件。

所以这是可以让fF等方面的工作所期望的方式:

  1. 安装Vundle。在你的shell

    Plugin 'tpope/vim-repeat' 
    Plugin 'dahu/vim-fanfingtastic' 
    
  2. 运行$ vim +PluginInstall +qall
  3. 这些行添加到您的.vimrc

  4. Voila!
1

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

这可让您在整个可见文本窗口中使用诸如f之类的动作。你触发插件,然后输入f和你正在寻找的角色。它突出显示角色以高亮颜色(例如红色)显示在屏幕上的每个位置,并使用字母(a,b,c,c, d,...)显示位置。您只需按相应于您想要跳转到的位置的字母。

Github上的插件的README包含一个可视化演示它如何工作的动画。