低级解决方案
尝试[I
和:ilist
命令:
[I " lists every occurrence of the word under the cursor
" in the current buffer (and includes)
:ilist /foo<CR> " lists every occurrence of foo in the current buffer
" (and includes)
按:
后跟一个行号并<CR>
跳到该行。
您可以通过简单的映射在视觉选择上使用它们:
xnoremap <key> "vy:<C-u>ilist /<C-r>v<CR>:
不过,您可能需要在插入时对寄存器进行消毒。
见:help :ilist
。
另一个更低级别的解决方案
既然我们在这里,让我们更深入地挖掘,发现惊人的简单和优雅:
:g/foo/#
您可以以与上述相同的方式使用:ilist
:
xnoremap <key> "vy:<C-u>g/<C-r>v/#<CR>:
限制
显然,上述解决方案不使用 quickfix 窗口,但它们允许您:
- 以列表的形式查看他们的结果,
- 使用行号实际到达您想要的位置。
但是,它们有局限性:
- 该列表未缓存,因此如果您想获得不同的出现,则必须再次执行搜索,
- 该列表不像快速修复列表那样是瞬态的,因此您不能使用导航命令
:cnext
或:clast
在结果中移动。
更高层次的解决方案
如果这些限制是一个阻碍,下面的函数,改编自 justinmk 在这个 /r/vim 线程中的回答,给你一个几乎完整的解决方案:
[I
在普通模式下按可在整个缓冲区中搜索光标下的单词,
]I
在普通模式下按可在当前行之后搜索光标下的单词,
[I
在可视模式下按下以在整个缓冲区中搜索选定的文本,
]I
在可视模式下按下可在当前行之后搜索所选文本。
下面的函数在缓冲区与文件关联时使用快速修复列表/窗口并回退到常规行为[I
和]I
其他情况。它可能会被修改为用作:Ilist
命令的一部分。
" Show ]I and [I results in the quickfix window.
" See :help include-search.
function! Ilist_qf(selection, start_at_cursor)
" there's a file associated with this buffer
if len(expand('%')) > 0
" we are working with visually selected text
if a:selection
" we build a clean search pattern from the visual selection
let old_reg = @v
normal! gv"vy
let search_pattern = substitute(escape(@v, '\/.*$^~[]'), '\\n', '\\n', 'g')
let @v = old_reg
" and we redirect the output of our command for later use
redir => output
silent! execute (a:start_at_cursor ? '+,$' : '') . 'ilist /' . search_pattern
redir END
" we are working with the word under the cursor
else
" we redirect the output of our command for later use
redir => output
silent! execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . "I"
redir END
endif
let lines = split(output, '\n')
" better safe than sorry
if lines[0] =~ '^Error detected'
echomsg 'Could not find "' . (a:selection ? search_pattern : expand("<cword>")) . '".'
return
endif
" we retrieve the filename
let [filename, line_info] = [lines[0], lines[1:-1]]
" we turn the :ilist output into a quickfix dictionary
let qf_entries = map(line_info, "{
\ 'filename': filename,
\ 'lnum': split(v:val)[1],
\ 'text': getline(split(v:val)[1])
\ }")
call setqflist(qf_entries)
" and we finally open the quickfix window if there's something to show
cwindow
" there's no file associated with this buffer
else
" we are working with visually selected text
if a:selection
" we build a clean search pattern from the visual selection
let old_reg = @v
normal! gv"vy
let search_pattern = substitute(escape(@v, '\/.*$^~[]'), '\\n', '\\n', 'g')
let @v = old_reg
" and we try to perform the search
try
execute (a:start_at_cursor ? '+,$' : '') . 'ilist /' . search_pattern . '<CR>:'
catch
echomsg 'Could not find "' . search_pattern . '".'
return
endtry
" we are working with the word under the cursor
else
" we try to perform the search
try
execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . "I"
catch
echomsg 'Could not find "' . expand("<cword>") . '".'
return
endtry
endif
endif
endfunction
nnoremap <silent> [I :call Ilist_qf(0, 0)<CR>
nnoremap <silent> ]I :call Ilist_qf(0, 1)<CR>
xnoremap <silent> [I :<C-u>call Ilist_qf(1, 0)<CR>
xnoremap <silent> ]I :<C-u>call Ilist_qf(1, 1)<CR>
注意:<C-r><C-w>
在光标下插入单词,而不是视觉选择,不幸的是没有这样的快捷方式。我们别无选择,只能猛拉。