-
-
Save romainl/3c7ee68125f822ec550c to your computer and use it in GitHub Desktop.
| function! List(command, selection, start_at_cursor, ...) | |
| let excmd = a:command . "list" | |
| let normcmd = toupper(a:command) | |
| if a:selection | |
| if 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 | |
| let lines = split(output, '\n') | |
| if lines[0] =~ '^Error detected' | |
| echomsg 'Could not find "' . (a:selection ? search_pattern : expand("<cword>")) . '".' | |
| return | |
| endif | |
| let filename = "" | |
| let qf_entries = [] | |
| for line in lines | |
| if line =~ '^\S' | |
| let filename = line | |
| else | |
| call add(qf_entries, {"filename" : filename, "lnum" : split(line)[1], "text" : join(split(line)[2:-1])}) | |
| endif | |
| endfor | |
| call setqflist(qf_entries) | |
| cwindow | |
| endfunction | |
| nnoremap <silent> [I :call List("i", 0, 0)<CR> | |
| nnoremap <silent> ]I :call List("i", 0, 1)<CR> | |
| xnoremap <silent> [I :<C-u>call List("i", 1, 0)<CR> | |
| xnoremap <silent> ]I :<C-u>call List("i", 1, 1)<CR> | |
| command! -nargs=1 Ilist call List("i", 1, 0, <f-args>) | |
| nnoremap <silent> [D :call List("d", 0, 0)<CR> | |
| nnoremap <silent> ]D :call List("d", 0, 1)<CR> | |
| xnoremap <silent> [D :<C-u>call List("d", 1, 0)<CR> | |
| xnoremap <silent> ]D :<C-u>call List("d", 1, 1)<CR> | |
| 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) > 0be replaced withif a:0 > 0orif 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:1exists.