├── .gitignore ├── LICENSE ├── README.md ├── plugin └── qlist.vim ├── autoload └── qlist.vim └── doc └── qlist.txt /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Romain Lafourcade 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-qlist 2 | 3 | Vim-qlist is an updated, more powerful, version of the function discussed in [this /r/vim thread](http://www.reddit.com/r/vim/comments/1rzvsm/do_any_of_you_redirect_results_of_i_to_the/). 4 | 5 | The purpose of this script is to make the results of "include-search" and "definition-search" easier to navigate and more persistent by using the quickfix list instead of the default list-like interface. 6 | 7 | ![screenshot](http://romainl.github.io/vim-qlist/images/qlist.png) 8 | 9 | ## Installation 10 | 11 | Use your favorite plugin manager or dump the files in this repository in their 12 | standard location: 13 | 14 | on Unix-like systems... 15 | 16 | ~/.vim/doc/qlist.txt 17 | ~/.vim/plugin/qlist.vim 18 | 19 | on Windows... 20 | 21 | %userprofile%\vimfiles\doc\qlist.txt 22 | %userprofile%\vimfiles\plugin\qlist.vim 23 | 24 | Don't forget to execute the following command to make the documentation 25 | globally available: 26 | 27 | on Unix-like systems... 28 | 29 | :helptags ~/.vim/doc 30 | 31 | on Windows... 32 | 33 | :helptags %userprofile%\vimfiles\doc 34 | 35 | ## TODO 36 | 37 | * Add options? 38 | 39 | ## DONE 40 | 41 | * Add a gifcast to the `README`. (sort of) 42 | * Add proper documentation. 43 | -------------------------------------------------------------------------------- /plugin/qlist.vim: -------------------------------------------------------------------------------- 1 | " qlist.vim - Persist the result of :ilist and related commands via the quickfix list. 2 | " Maintainer: romainl 3 | " Version: 0.0.3 4 | " License: MIT 5 | " Location: plugin/qlist.vim 6 | " Website: https://github.com/romainl/vim-qlist 7 | 8 | if exists("g:loaded_qlist") || v:version < 703 || &compatible 9 | finish 10 | endif 11 | let g:loaded_qlist = 1 12 | 13 | let s:save_cpo = &cpo 14 | set cpo&vim 15 | 16 | " Add the :Ilist command. 17 | command! -nargs=1 -bar -bang Ilist call qlist#Qlist("i", 1, 0, '' == '!', ) 18 | 19 | " Add the :Dlist command. 20 | command! -nargs=1 -bar -bang Dlist call qlist#Qlist("d", 1, 0, '' == '!', ) 21 | 22 | " Internal mappings 23 | " Override the built-in [I and ]I. 24 | nnoremap QlistIncludefromtop :call qlist#Qlist("i", 0, 0, 0) 25 | xnoremap QlistIncludefromtopvisual :call qlist#Qlist("i", 1, 0, 0) 26 | 27 | nnoremap QlistIncludefromhere :call qlist#Qlist("i", 0, 1, 0) 28 | xnoremap QlistIncludefromherevisual :call qlist#Qlist("i", 1, 1, 0) 29 | 30 | " Override the built-in [D and ]D. 31 | nnoremap QlistDefinefromtop :call qlist#Qlist("d", 0, 0, 0) 32 | xnoremap QlistDefinefromtopvisual :call qlist#Qlist("d", 1, 0, 0) 33 | 34 | nnoremap QlistDefinefromhere :call qlist#Qlist("d", 0, 1, 0) 35 | xnoremap QlistDefinefromherevisual :call qlist#Qlist("d", 1, 1, 0) 36 | 37 | " Default, user-configurable, mappings 38 | if !hasmapto('QlistIncludefromtop') 39 | nmap [I QlistIncludefromtop 40 | endif 41 | 42 | if !hasmapto('QlistIncludefromtopvisual') 43 | xmap [I QlistIncludefromtopvisual 44 | endif 45 | 46 | if !hasmapto('QlistIncludefromhere') 47 | nmap ]I QlistIncludefromhere 48 | endif 49 | 50 | if !hasmapto('QlistIncludefromherevisual') 51 | xmap ]I QlistIncludefromherevisual 52 | endif 53 | 54 | if !hasmapto('QlistDefinefromtop') 55 | nmap [D QlistDefinefromtop 56 | endif 57 | 58 | if !hasmapto('QlistDefinefromtopvisual') 59 | xmap [D QlistDefinefromtopvisual 60 | endif 61 | 62 | if !hasmapto('QlistDefinefromhere') 63 | nmap ]D QlistDefinefromhere 64 | endif 65 | 66 | if !hasmapto('QlistDefinefromherevisual') 67 | xmap ]D QlistDefinefromherevisual 68 | endif 69 | 70 | let &cpo = s:save_cpo 71 | -------------------------------------------------------------------------------- /autoload/qlist.vim: -------------------------------------------------------------------------------- 1 | " qlist.vim - Persist the result of :ilist and related commands via the quickfix list. 2 | " Maintainer: romainl 3 | " Version: 0.0.3 4 | " License: MIT 5 | " Location: autoload/qlist.vim 6 | " Website: https://github.com/romainl/vim-qlist 7 | 8 | let s:save_cpo = &cpo 9 | set cpo&vim 10 | 11 | function! qlist#Qlist(command, selection, start_at_cursor, force, ...) 12 | " Derive the commands used below from the first argument. 13 | if a:force == 1 14 | let excmd = a:command . "list!" 15 | else 16 | let excmd = a:command . "list" 17 | endif 18 | let normcmd = toupper(a:command) 19 | 20 | " If we are operating on a visual selection, redirect the output of '[I', ']I', '[D' or ']D'. 21 | " If we don't, redirect the output of ':ilist /argument' or ':dlist /argument'. 22 | let output = "" 23 | if a:selection 24 | if a:0 > 0 && len(a:1) > 0 25 | let search_pattern = a:1 26 | else 27 | let old_reg = getreg("v") 28 | normal! gv"vy 29 | let raw_search = getreg("v") 30 | let search_pattern = substitute(escape(raw_search, '\/.*$^~[]'), '\\n', '\\n', 'g') 31 | call setreg("v", old_reg) 32 | endif 33 | redir => output 34 | silent! execute (a:start_at_cursor ? '+,$' : '') . excmd . ' /' . search_pattern 35 | redir END 36 | let feedback = excmd . ' /' . search_pattern 37 | else 38 | redir => output 39 | silent! execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . normcmd 40 | redir END 41 | let feedback = (a:start_at_cursor ? ']' : '[') . normcmd 42 | endif 43 | 44 | " Clean up the output. 45 | let lines = split(output, '\n') 46 | 47 | " Bail out on errors. 48 | if (len(lines) == 3) && ((normcmd is# 'D' && lines[2] =~# '^E388:') || normcmd is# 'I' && (lines[2] =~# '^E389:')) 49 | echomsg 'Could not find "' . (a:selection ? search_pattern : expand("")) . '".' 50 | return 51 | endif 52 | 53 | " Our results may span multiple files so we need to build a relatively complex list based on filenames. 54 | let filename = "" 55 | let qf_entries = [] 56 | for line in lines 57 | if line !~ '^\s*\d\+:' 58 | let filename = fnamemodify(line, ':p:.') 59 | else 60 | let lnum = split(line)[1] 61 | let text = substitute(line, '^\s*.\{-}:\s*\S\{-}\s', "", "") 62 | let col = match(text, a:selection ? search_pattern : expand("")) + 1 63 | call add(qf_entries, {"filename" : filename, "lnum" : lnum, "col" : col, "vcol" : 1, "text" : text}) 64 | endif 65 | endfor 66 | 67 | " Build the quickfix list from our results. 68 | call setqflist(qf_entries) 69 | 70 | " Open the quickfix window if there is something to show. 71 | if exists("g:loaded_qf") 72 | doautocmd QuickFixCmdPost cwindow 73 | else 74 | cclose 75 | execute min([ 10, len(getqflist()) ]) 'cwindow' 76 | endif 77 | 78 | " Add proper feedback to the statusline. 79 | if has("patch-7.4.2200") 80 | call setqflist([], 'r', {'title': feedback}) 81 | else 82 | let w:quickfix_title = feedback 83 | endif 84 | endfunction 85 | 86 | let &cpo = s:save_cpo 87 | -------------------------------------------------------------------------------- /doc/qlist.txt: -------------------------------------------------------------------------------- 1 | *qlist.txt* A plugin to make working with the quickfix list/window smoother. 2 | 3 | 4 | VIM-qlist DOCUMENTATION by Romain Lafourcade 5 | 6 | 7 | Help on using vim-qlist *qlist* *vim-qlist* 8 | 9 | 1. Introduction ............................... |qlist-intro| 10 | 2. Installation ............................... |qlist-installation| 11 | 3. Configuration .............................. |qlist-configuration| 12 | 4. Usage ...................................... |qlist-usage| 13 | 5. Tips and tricks ............................ |qlist-tricks| 14 | 6. Acknowledgments ............................ |qlist-acknowledgments| 15 | 7. TODO ....................................... |qlist-todo| 16 | 8. DONE ....................................... |qlist-done| 17 | 18 | ============================================================================== 19 | 1. INTRODUCTION *qlist-intro* 20 | 21 | Vim-qlist is an updated, more powerful, version of the function discussed 22 | in this /r/vim thread: 23 | 24 | http://goo.gl/AkYQ1L 25 | 26 | The purpose of this script is to make the results of |include-search| easier 27 | to navigate and more persistent by using the |quickfix| list instead of the 28 | default non-interactive interface. 29 | 30 | ============================================================================== 31 | 2. INSTALLATION *qlist-installation* 32 | 33 | Use your favorite plugin manager or dump the files in this repository in their 34 | standard location: 35 | 36 | on Unix-like systems... > 37 | 38 | ~/.vim/doc/qlist.txt 39 | ~/.vim/plugin/qlist.vim 40 | < 41 | on Windows... > 42 | 43 | %userprofile%\vimfiles\doc\qlist.txt 44 | %userprofile%\vimfiles\plugin\qlist.vim 45 | < 46 | and don't forget to execute the following command to make the documentation 47 | globally available: 48 | 49 | on Unix-like systems... > 50 | 51 | :helptags ~/.vim/doc 52 | < 53 | on Windows... > 54 | 55 | :helptags %userprofile%\vimfiles\doc 56 | < 57 | ============================================================================== 58 | 3. CONFIGURATION *qlist-configuration* 59 | 60 | |[I|, |]I|, |[D|, and |]D| are all overriden by default in normal mode using 61 | the mappings below: 62 | 63 | QlistIncludefromtop ................ |QlistIncludefromtop| 64 | QlistIncludefromhere ............... |QlistIncludefromhere| 65 | QlistDefinefromtop ................. |QlistDefinefromtop| 66 | QlistDefinefromhere ................ |QlistDefinefromhere| 67 | 68 | If you don't want to override the default commands you can still map each 69 | of them to whatever works for you. 70 | 71 | Vim-qlist also provides visual mode equivalents of those commands for your 72 | convenience: 73 | 74 | QlistIncludefromtopvisual .......... |QlistIncludefromtopvisual| 75 | QlistIncludefromherevisual ......... |QlistIncludefromherevisual| 76 | QlistDefinefromtopvisual ........... |QlistDefinefromtopvisual| 77 | QlistDefinefromherevisual .......... |QlistDefinefromherevisual| 78 | 79 | ------------------------------------------------------------------------------ 80 | *QlistIncludefromtop* 81 | QlistIncludefromtop 82 | 83 | Like |[I| List every occurrence of the word under the cursor 84 | in the current buffer and included files. 85 | Comments are skipped. 86 | Search starts from the top. 87 | 88 | Default mapping: > 89 | 90 | nmap [I QlistIncludefromtop 91 | < 92 | ------------------------------------------------------------------------------ 93 | *QlistIncludefromtopvisual* 94 | QlistIncludefromtopvisual 95 | 96 | Like |[I| List every occurrence of the highlighted text 97 | in the current buffer and included files. 98 | Comments are skipped. 99 | Search starts from the top. 100 | 101 | Default mapping: > 102 | 103 | xmap [I QlistIncludefromtopvisual 104 | < 105 | ------------------------------------------------------------------------------ 106 | *QlistIncludefromhere* 107 | QlistIncludefromhere 108 | 109 | Like |]I| List every occurrence of the word under the cursor 110 | in the current buffer and included files. 111 | Comments are skipped. 112 | Search starts after the current position. 113 | 114 | Default mapping: > 115 | 116 | nmap ]I QlistIncludefromhere 117 | < 118 | ------------------------------------------------------------------------------ 119 | *QlistIncludefromherevisual* 120 | QlistIncludefromherevisual 121 | 122 | Like |]I| List every occurrence of the highlighted text 123 | in the current buffer and included files. 124 | Comments are skipped. 125 | Search starts after the current position. 126 | 127 | Default mapping: > 128 | 129 | xmap ]I QlistIncludefromherevisual 130 | < 131 | ------------------------------------------------------------------------------ 132 | *QlistDefinefromtop* 133 | QlistDefinefromtop 134 | 135 | Like |[D| List every definition of the symbol under the cursor 136 | in the current buffer and included files. 137 | Comments are skipped. 138 | Search starts from the top. 139 | 140 | Default mapping: > 141 | 142 | nmap [D QlistDefinefromtop 143 | < 144 | ------------------------------------------------------------------------------ 145 | *QlistDefinefromtopvisual* 146 | QlistDefinefromtopvisual 147 | 148 | Like |[D| List every definition of the highlighted text 149 | in the current buffer and included files. 150 | Comments are skipped. 151 | Search starts from the top. 152 | 153 | Default mapping: > 154 | 155 | xmap [D QlistDefinefromtopvisual 156 | < 157 | ------------------------------------------------------------------------------ 158 | *QlistDefinefromhere* 159 | QlistDefinefromhere 160 | 161 | Like |]D| List every definition of the symbol under the cursor 162 | in the current buffer and included files. 163 | Comments are skipped. 164 | Search starts after the current position. 165 | 166 | Default mapping: > 167 | 168 | nmap ]D QlistDefinefromhere 169 | < 170 | ------------------------------------------------------------------------------ 171 | *QlistDefinefromherevisual* 172 | QlistDefinefromherevisual 173 | 174 | Like |]D| List every definition of the highlighted text 175 | in the current buffer and included files. 176 | Comments are skipped. 177 | Search starts after the current position. 178 | 179 | Default mapping: > 180 | 181 | xmap ]D QlistDefinefromherevisual 182 | 183 | ============================================================================== 184 | 4. USAGE *qlist-usage* 185 | 186 | This plugin adds two custom commands to your configuration, |:Ilist| and |:Dlist|, 187 | overrides these four normal mode commands: |[I|, |]I|, |[D|, |]D| and adds their 188 | visual mode equivalents. 189 | 190 | Those commands still behave pretty much like the originals and share the same 191 | requirements. There are two differences, though... 192 | 193 | The first difference is the whole point of this humble plugin: 194 | instead of displaying the results as a non-interactive list, we use the 195 | quickfix list. The benefits are huge. 196 | 197 | - the results can be displayed in an interactive window where you can 198 | search and move around with regular Vim commands, 199 | - the results are still accessible even if the quickfix window is closed, 200 | - older searches can be re-called if needed. 201 | 202 | The second difference is minimal but worth noting: > 203 | 204 | :Ilist foo 205 | < 206 | works like: > 207 | 208 | :ilist /foo 209 | 210 | and: > 211 | 212 | :Dlist bar 213 | 214 | works like: > 215 | 216 | :dlist /bar 217 | < 218 | The forward slash forces vim to perform regular expression search instead of 219 | the default whole word search. This is actually a built-in feature that 220 | happens to be quite handy for quick searches. 221 | 222 | *:Ilist[!]* 223 | 224 | Like |:ilist| List every word containing the argument in the current 225 | buffer and included files. 226 | Comments are skipped. 227 | Search starts from the top. 228 | See |:search-args| for and [!]. 229 | 230 | Example: > 231 | 232 | :Ilist user 233 | :Ilist! user 234 | > 235 | *:Dlist[!]* 236 | 237 | Like |:dlist| List every definition containing the argument in the current 238 | buffer and included files. 239 | Comments are skipped. 240 | Search starts from the top. 241 | See |:search-args| for and [!]. 242 | 243 | Example: > 244 | 245 | :Dlist getContent 246 | :Dlist! getContent 247 | > 248 | ============================================================================== 249 | 5. TIPS AND TRICKS *qlist-tricks* 250 | 251 | If you want to open/refresh the quickfix window each time you do a search 252 | (with vim-qlist but also with |:grep| and friends) you can add these lines 253 | to your vimrc: > 254 | 255 | augroup automaticquickfix 256 | autocmd! 257 | autocmd QuickFixCmdPost [^l]* cwindow 258 | autocmd QuickFixCmdPost l* lwindow 259 | augroup END 260 | < 261 | The command below lists every definition in the current buffer and include 262 | files. A nice and cheap code navigation tool: > 263 | 264 | :Dlist / 265 | < 266 | The command below gives you a nice actionable TOC of the current Markdown 267 | file: > 268 | 269 | :Ilist ^# 270 | < 271 | Of course, those tricks work just as well with |:dlist| and |:ilist| but the 272 | quickfix window makes all the difference ;-) 273 | 274 | The behavior of |include-search| and |definition-search| largely depends on 275 | a number of filetype-specific options that may or may not be set by your 276 | ftplugins. Reading the following help sections is `strongly` recommended: 277 | 278 | |'include'| tells Vim how to find include directives in your files 279 | |'define'| tells Vim how to find definitions in your files 280 | |'includeexpr'| can be useful to clean up your include directives 281 | |'suffixesadd'| helps Vim infer `foo.js` from `foo` 282 | |'path'| tells Vim where to look for include files 283 | 284 | ============================================================================== 285 | 6. ACKNOWLEDGMENTS *qlist-acknowledgments* 286 | 287 | All the templates used to turn this multifarious snippets collection into 288 | a proper plugin come from Barry Arthur's Area 41 plugin: 289 | 290 | https://github.com/dahu/Area-41 291 | 292 | ============================================================================== 293 | 7. TODO *qlist-todo* 294 | 295 | - Export more options? 296 | 297 | ============================================================================== 298 | 8. DONE *qlist-done* 299 | 300 | - Use mappings. 301 | - Write a proper help file. 302 | - Add a gifcast to the README? 303 | 304 | vim:tw=78:ts=8:ft=help:norl: 305 | --------------------------------------------------------------------------------