我将如何设置热键(例如:CTRL+g)来执行 VIMGREP
对当前缓冲区中的当前视觉选择进行操作?我的目的是在所有匹配搜索结果的“快速修复”窗口中显示一个行编号列表。
现在,如果我想获取正则表达式搜索的结果列表,我可以执行命令模式查询,如下所示:
:vimgrep /foo/ %
但是,这样做有两个问题:
谢谢你。
最佳答案
低级解决方案
试试 [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 在 this /r/vim thread 中的回答。 ,给你一个几乎完整的解决方案:
[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>
在光标下插入单词,而不是视觉选择,不幸的是没有这样的快捷方式。我们别无选择,只能猛拉。
关于regex - VIM - 当前缓冲区中视觉选择的 VIMGREP 热键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26538875/