See https://github.com/romainl/vim-qlist for an up-to-date version.
Last active
November 7, 2021 20:57
-
-
Save romainl/3c7ee68125f822ec550c to your computer and use it in GitHub Desktop.
Show ]I, [I, ]D, [D, :ilist and :dlist results — even spanning multiple files — in the quickfix window.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" 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>) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.