Using vim's f command over multiple lines

Vim

Vim Problem Overview


Anyone knows how to quickly find the next occurrence of a character (like the f command) but multi-line? I.e. to quickly jump to the next occurrence of some character in a file?

Vim Solutions


Solution 1 - Vim

Isn't that what "/" does?

If you're looking for the next "x" then do /x while in command mode.

Then you can hit "n" to advance to the next x, and then the next x, etc.

There are lots of vim cheat sheets out there with all kinds of tips.

Solution 2 - Vim

There's an example of redefining f to ignore case in the 'eval.txt' help file.

:h eval.txt

(search for "ignore case" a couple times)

We can modify that to do what you want. Add the following function to your ~/.vimrc file or better yet, create a plugin file: ~/.vim/plugin/find-char.vim (create the directories if you do not already have them).

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

Then, in your ~/.vimrc add the following line:

nmap f :call FindChar()<CR>

Now, f should work like you want it to.

BTW, this was tested with Vim 7.2 on Ubuntu 10.04.

Solution 3 - Vim

Christian Brabandt's ft_improved plugin extends the built-in f / t commands to search in following lines, too.

Solution 4 - Vim

Having wanted to know exactly the same thing I looked through the answers here. None of are exactly what I wanted so I cobbled together a few of them.

q335's answer was the closest because it handles omaps properly which is necessary to do something like dt} (delete everything up to, but not including the next curly brace) but Curt's answer handles special character searching and uses a single function which to me is much more preferable so I'm not adding too much to my .vimrc

Here is my result:

"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

Solution 5 - Vim

Aaaa, vimscript. It takes about 2 years to write 20 lines well :D. Here is the latest, sleekest version: works for ALL modes: visual, operator pending, normal.

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)

Or the super garbled:

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)

Solution 6 - Vim

One approach to this problem is to use the easymotion plugin.

This lets you use motions such as f across the entire visible window of text. You trigger the plugin, then enter f and the character you are looking for. It highlights each position that the character appears on screen in a highlight color (e.g. red), and shows the position using a letter (a, b, c, d, ...). You simply press the letter corresponding to the position you wish to jump to.

The plugin's README on Github includes an animation that visually demonstrates how it works.

Solution 7 - Vim

You could make a mapping to go to the next character under the cursor:

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

the \V will make sure symbols are matched literally.

Also, you may want to look at the * and # commands, which are already defined for you, although they might not be what you want.

Solution 8 - Vim

The most reasonable way of doing this at the moment is hidden in this comment.

You just have to install two plugins: vim-repeat and vim-fanfingtastic.

Personally, I use Vundle to manage my vim plugins.

So this is the way you can make f, F, etc. work as desired:

  1. Install Vundle.

  2. Add these lines to your .vimrc:

     Plugin 'tpope/vim-repeat'
     Plugin 'dahu/vim-fanfingtastic'
    
  3. Run $ vim +PluginInstall +qall in your shell.

  4. Voila!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKokoView Question on Stackoverflow
Solution 1 - VimPeter RecoreView Answer on Stackoverflow
Solution 2 - VimCurt NelsonView Answer on Stackoverflow
Solution 3 - VimIngo KarkatView Answer on Stackoverflow
Solution 4 - VimthagornView Answer on Stackoverflow
Solution 5 - Vimq335r49View Answer on Stackoverflow
Solution 6 - VimDan LoweView Answer on Stackoverflow
Solution 7 - VimKimball RobinsonView Answer on Stackoverflow
Solution 8 - VimMateusz PiotrowskiView Answer on Stackoverflow