See https://github.com/romainl/vim-qlist for an up-to-date version.
-
-
Save romainl/3c7ee68125f822ec550c to your computer and use it in GitHub Desktop.
" This is an updated, more powerful, version of the function discussed here: | |
" http://www.reddit.com/r/vim/comments/1rzvsm/do_any_of_you_redirect_results_of_i_to_the/ | |
" The purpose of this function is to make the results of ']I', '[I', ']D', '[D', ':ilist' and ':dlist' | |
" easier to navigate and more persistant by using the quickfix window instead of the default list-like interface. | |
function! List(command, selection, start_at_cursor, ...) | |
" Derive the commands used below from the first argument. | |
let excmd = a:command . "list" | |
let normcmd = toupper(a:command) | |
" If we are operating on a visual selection, redirect the output of '[I', ']I', '[D' or ']D'. | |
" If we don't, redirect the output of ':ilist argument' or ':dlist argument'. | |
let output = "" | |
if a:selection | |
if a:0 > 0 && len(a:1) > 0 | |
let search_pattern = a:1 | |
else | |
let old_reg = @v | |
normal! gv"vy | |
let search_pattern = substitute(escape(@v, '\/.*$^~[]'), '\\n', '\\n', 'g') | |
let @v = old_reg | |
endif | |
redir => output | |
silent! execute (a:start_at_cursor ? '+,$' : '') . excmd . ' /' . search_pattern | |
redir END | |
else | |
redir => output | |
silent! execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . normcmd | |
redir END | |
endif | |
" Clean up the output. | |
let lines = split(output, '\n') | |
" Bail out on errors. | |
if lines[0] =~ '^Error detected' | |
echomsg 'Could not find "' . (a:selection ? search_pattern : expand("<cword>")) . '".' | |
return | |
endif | |
" Our results may span multiple files so we need to build a relatively complex list based on filenames. | |
let filename = "" | |
let qf_entries = [] | |
for line in lines | |
if line !~ '^\s*\d\+:' | |
let filename = split(line, '\.\./')[-1] | |
else | |
let lnum = split(line)[1] | |
let text = substitute(line, '^\s*.\{-}:\s*\S\{-}\s\s', "", "") | |
let col = match(text, a:selection ? search_pattern : expand("<cword>")) + 2 | |
call add(qf_entries, {"filename" : filename, "lnum" : lnum, "col" : col, "text" : text}) | |
endif | |
endfor | |
" Build the quickfix list from our results. | |
call setqflist(qf_entries) | |
" Open the quickfix window if there is something to show. | |
cwindow | |
endfunction | |
" Override the built-in [I and ]I. | |
nnoremap <silent> [I :call List("i", 0, 0)<CR> | |
nnoremap <silent> ]I :call List("i", 0, 1)<CR> | |
" Add [I and ]I for visual mode. | |
xnoremap <silent> [I :<C-u>call List("i", 1, 0)<CR> | |
xnoremap <silent> ]I :<C-u>call List("i", 1, 1)<CR> | |
" Add the :Ilist command. | |
command! -nargs=1 Ilist call List("i", 1, 0, <f-args>) | |
" Override the built-in [D and ]D. | |
nnoremap <silent> [D :call List("d", 0, 0)<CR> | |
nnoremap <silent> ]D :call List("d", 0, 1)<CR> | |
" Add [D and ]D for visual mode. | |
xnoremap <silent> [D :<C-u>call List("d", 1, 0)<CR> | |
xnoremap <silent> ]D :<C-u>call List("d", 1, 1)<CR> | |
" Add the :Dlist command. | |
command! -nargs=1 Dlist call List("d", 1, 0, <f-args>) |
I updated the function as per @johnmastro's comment above and @Kyiv's comment on reddit:
- better check for the existence of
a:1
, - better check for filename lines
New version jumps to the actual match not the the line as it did (stupidly) before.
Line 47, for my use case, should be:
let filename=split(line, '\.\./')[-1]
I have includes like this in *.hpp file:
#include "../foo/bar.hpp"
Snippet shows such paths as:
~/path/to/../foo/bar.hpp
And hitting Enter
on top of such item opens empty buffer with path like in quickfix. Going to netrw opens correct folder, and hitting Enter
opens file in correct form foo/bar.hpp
.
[count][<c-i>
also works well for such case.
Fixed the column jumping.
Modified line 47 as per c0ffeeartc's comment. Didn't notice any undesirable side effect.
I'm wondering if I should turn this thing into an actual plugin. On one hand it would help tracking issues, on the other hand this function may be too small for that.
This gist is no longer maintained. See romainl/vim-qlist.
This is very useful, thanks!
Should
if len(a:1) > 0
be replaced withif a:0 > 0
orif a:0 > 0 && len(a:1) > 0
?I get an error (
Undefined variable: a1
) in the former case and, if I understand correctly, the intent is to check whethera:1
exists.