Searching in Vim isn't limited to /
and ?
however those other
searches don't have the same easy one key command to move through
matches and I'm lazy. So let's make N
and n
move to the next match
for whatever the last type of search was performed. I'm mainly
interested in the quickfix list but I've written this generically so it
can be easily adapted to other sources.
function! Cycle(type, forward) abort
try
execute a:type . (a:forward ? 'next' : 'previous')
catch
execute a:type . (a:forward ? 'first' : 'last')
endtry
endfunction
augroup Next
autocmd!
autocmd CmdlineLeave /,\? silent! unmap N
autocmd CmdlineLeave /,\? silent! unmap n
autocmd QuickFixCmdPost [^l]*
\ if !empty(getqflist())
\ | execute "nnoremap N :call Cycle('c', 0)<CR>"
\ | execute "nnoremap n :call Cycle('c', 1)<CR>"
\ | endif
autocmd CmdlineLeave :
\ let s:cmd = get(split(getcmdline()), 0, '')
\ | if s:cmd ==# 'cnext'
\ | execute "nnoremap N :call Cycle('c', 0)<CR>"
\ | execute "nnoremap n :call Cycle('c', 1)<CR>"
\ | elseif s:cmd ==# 'cprevious'
\ | execute "nnoremap N :call Cycle('c', 1)<CR>"
\ | execute "nnoremap n :call Cycle('c', 0)<CR>"
\ | endif
augroup END
This is a simplification in a few regards.
- Saving and restoring any current mappings
N
andn
have would be a courtesy. - Paying attention to the
wrapscan
setting may be of interest. - When
N
andn
have been mapped to move through items in the quickfix list they are performing jumps rather than motions and as such are not composable with operators. - Mappings are not altered if shorthand
:cp
or:cn
commands are used. Usinggetcompletion()
to try and expand these would givecpfile
andcnewer
respectively however. An ugly regex or list andindex()
check could catch these. - If a
/
or?
search is performed in the quickfix window and then a item is selected and jumpedN
andn
will behave as normal. Creating a buffer local mapping for<CR>
in the quickfix window would be a way to alter this.