Skip to content

Instantly share code, notes, and snippets.

@johnmastro
Forked from romainl/list.md
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnmastro/1e9fc652e6f74c8f535f to your computer and use it in GitHub Desktop.
Save johnmastro/1e9fc652e6f74c8f535f 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/
" that shows ]I, [I, ]D, [D, :ilist and :dlist results in the quickfix window, even spanning multiple files.
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 a:selection
if a:0 > 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 file names
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
" build the quickfix list from our results
call setqflist(qf_entries)
" open the quickfix window if there is something to show
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>)
@romainl
Copy link

romainl commented Mar 27, 2015

I updated my gist as per your comment and also fixed a bug that limited the list to 99.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment