├── .gitignore ├── LICENSE.md ├── README.md ├── autoload └── grep.vim ├── doc └── grep.txt └── plugin └── grep.vim /.gitignore: -------------------------------------------------------------------------------- 1 | doc/tags 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2002-2018 Yegappan Lakshmanan 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | grep 2 | ==== 3 | 4 | Plugin to integrate various grep like search tools with Vim. 5 | 6 | The grep plugin integrates grep like utilities (grep, fgrep, egrep, agrep, 7 | findstr, silver searcher (ag), ripgrep, ack, git grep, sift, platinum searcher 8 | and universal code grep) with Vim and allows you to search for a pattern in one 9 | or more files and jump to them. 10 | 11 | In Vim version 8.0 and above, the search command is run asynchronously 12 | in the background and the results are added to a quickfix list. 13 | 14 | This plugin works only with Vim and not with neovim. 15 | 16 | To use this plugin, you will need the grep like utilities in your system. If a 17 | particular utility is not present, then you cannot use the corresponding 18 | features, but you can still use the rest of the features supported by the 19 | plugin. 20 | 21 | To use the this plugin with grep, you will need the grep, fgrep and egrep 22 | utilities. To recursively search for files using grep, you will need the find 23 | and xargs utilities. These tools are present in most of the Unix and MacOS 24 | installations. For MS-Windows systems, you can download the GNU grep and find 25 | utilities from the following sites: 26 | 27 | http://gnuwin32.sourceforge.net/packages/grep.htm 28 | http://gnuwin32.sourceforge.net/packages/findutils.htm 29 | 30 | On MS-Windows, you can use the findstr utility to search for patterns. 31 | This is available by default on all MS-Windows systems. 32 | 33 | The plugin supports various search utilities listed in the table below. 34 | 35 | Search Tool | Home Page | Grep Plugin Command | 36 | ----------- | ----------| --------------------| 37 | Ripgrep | https://github.com/BurntSushi/ripgrep | :Rg 38 | Silver Searcher | https://github.com/ggreer/the_silver_searcher | :Ag 39 | Git grep | https://git-scm.com/ | :Gitgrep 40 | Ack | https://beyondgrep.com/ | :Ack 41 | Sift | https://sift-tool.org | :Sift 42 | Platinum Searcher | https://github.com/monochromegane/the_platinum_searcher | :Ptgrep 43 | Universal Code Grep | https://gvansickle.github.io/ucg | :Ucgrep 44 | agrep | https://www.tgries.de/agrep | :Agrep 45 | 46 | The ripgrep, silver searcher, git grep, ack, sift, platinum searcher and 47 | universal code grep utilities can search for a pattern recursively 48 | across directories without using any other additional utilities like 49 | find and xargs. 50 | -------------------------------------------------------------------------------- /autoload/grep.vim: -------------------------------------------------------------------------------- 1 | " File: grep.vim 2 | " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) 3 | " Version: 2.2 4 | " Last Modified: June 14, 2020 5 | " 6 | " Plugin to integrate grep like utilities with Vim 7 | " Supported utilities are: grep, fgrep, egrep, agrep, findstr, ag, ack, 8 | " ripgrep, git grep, sift, platinum searcher and universal code grep. 9 | " 10 | " License: MIT License 11 | " Copyright (c) 2002-2020 Yegappan Lakshmanan 12 | " 13 | " Permission is hereby granted, free of charge, to any person obtaining a copy 14 | " of this software and associated documentation files (the "Software"), to 15 | " deal in the Software without restriction, including without limitation the 16 | " rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 17 | " sell copies of the Software, and to permit persons to whom the Software is 18 | " furnished to do so, subject to the following conditions: 19 | " 20 | " The above copyright notice and this permission notice shall be included in 21 | " all copies or substantial portions of the Software. 22 | " 23 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 | " FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 29 | " IN THE SOFTWARE. 30 | " ======================================================================= 31 | 32 | " Line continuation used here 33 | let s:cpo_save = &cpo 34 | set cpo&vim 35 | 36 | " Location of the grep utility 37 | if !exists("Grep_Path") 38 | let Grep_Path = 'grep' 39 | endif 40 | 41 | " Location of the fgrep utility 42 | if !exists("Fgrep_Path") 43 | let Fgrep_Path = 'fgrep' 44 | endif 45 | 46 | " Location of the egrep utility 47 | if !exists("Egrep_Path") 48 | let Egrep_Path = 'egrep' 49 | endif 50 | 51 | " Location of the agrep utility 52 | if !exists("Agrep_Path") 53 | let Agrep_Path = 'agrep' 54 | endif 55 | 56 | " Location of the Silver Searcher (ag) utility 57 | if !exists("Ag_Path") 58 | let Ag_Path = 'ag' 59 | endif 60 | 61 | " Location of the Ripgrep (rg) utility 62 | if !exists("Rg_Path") 63 | let Rg_Path = 'rg' 64 | endif 65 | 66 | " Location of the ack utility 67 | if !exists("Ack_Path") 68 | let Ack_Path = 'ack' 69 | endif 70 | 71 | " Location of the findstr utility 72 | if !exists("Findstr_Path") 73 | let Findstr_Path = 'findstr.exe' 74 | endif 75 | 76 | " Location of the git utility used by the git grep command 77 | if !exists("Git_Path") 78 | let Git_Path = 'git' 79 | endif 80 | 81 | " Location of the sift utility 82 | if !exists("Sift_Path") 83 | let Sift_Path = 'sift' 84 | endif 85 | 86 | " Location of the platinum searcher utility 87 | if !exists("Pt_Path") 88 | let Pt_Path = 'pt' 89 | endif 90 | 91 | " Location of the Universal Code Grep (UCG) utility 92 | if !exists("Ucg_Path") 93 | let Ucg_Path = 'ucg' 94 | endif 95 | 96 | " grep options 97 | if !exists("Grep_Options") 98 | let Grep_Options = '' 99 | endif 100 | 101 | " fgrep options 102 | if !exists("Fgrep_Options") 103 | let Fgrep_Options = '' 104 | endif 105 | 106 | " egrep options 107 | if !exists("Egrep_Options") 108 | let Egrep_Options = '' 109 | endif 110 | 111 | " agrep options 112 | if !exists("Agrep_Options") 113 | let Agrep_Options = '' 114 | endif 115 | 116 | " ag options 117 | if !exists("Ag_Options") 118 | let Ag_Options = '' 119 | endif 120 | 121 | " ripgrep options 122 | if !exists("Rg_Options") 123 | let Rg_Options = '' 124 | endif 125 | 126 | " ack options 127 | if !exists("Ack_Options") 128 | let Ack_Options = '' 129 | endif 130 | 131 | " findstr options 132 | if !exists("Findstr_Options") 133 | let Findstr_Options = '' 134 | endif 135 | 136 | " git grep options 137 | if !exists("Gitgrep_Options") 138 | let Gitgrep_Options = '' 139 | endif 140 | 141 | " sift options 142 | if !exists("Sift_Options") 143 | let Sift_Options = '' 144 | endif 145 | 146 | " pt options 147 | if !exists("Pt_Options") 148 | let Pt_Options = '' 149 | endif 150 | 151 | " ucg options 152 | if !exists("Ucg_Options") 153 | let Ucg_Options = '' 154 | endif 155 | 156 | " Location of the find utility 157 | if !exists("Grep_Find_Path") 158 | let Grep_Find_Path = 'find' 159 | endif 160 | 161 | " Location of the xargs utility 162 | if !exists("Grep_Xargs_Path") 163 | let Grep_Xargs_Path = 'xargs' 164 | endif 165 | 166 | " Open the Grep output window. Set this variable to zero, to not open 167 | " the Grep output window by default. You can open it manually by using 168 | " the :cwindow command. 169 | if !exists("Grep_OpenQuickfixWindow") 170 | let Grep_OpenQuickfixWindow = 1 171 | endif 172 | 173 | " Default grep file list 174 | if !exists("Grep_Default_Filelist") 175 | let Grep_Default_Filelist = '*' 176 | endif 177 | 178 | " Use the 'xargs' utility in combination with the 'find' utility. Set this 179 | " to zero to not use the xargs utility. 180 | if !exists("Grep_Find_Use_Xargs") 181 | let Grep_Find_Use_Xargs = 1 182 | endif 183 | 184 | " The command-line arguments to supply to the xargs utility 185 | if !exists('Grep_Xargs_Options') 186 | let Grep_Xargs_Options = '-0' 187 | endif 188 | 189 | " The find utility is from the cygwin package or some other find utility. 190 | if !exists("Grep_Cygwin_Find") 191 | let Grep_Cygwin_Find = 0 192 | endif 193 | 194 | " NULL device name to supply to grep. We need this because, grep will not 195 | " print the name of the file, if only one filename is supplied. We need the 196 | " filename for Vim quickfix processing. 197 | if !exists("Grep_Null_Device") 198 | if has('win32') 199 | let Grep_Null_Device = 'NUL' 200 | else 201 | let Grep_Null_Device = '/dev/null' 202 | endif 203 | endif 204 | 205 | " Character to use to escape special characters before passing to grep. 206 | if !exists("Grep_Shell_Escape_Char") 207 | if has('win32') 208 | let Grep_Shell_Escape_Char = '' 209 | else 210 | let Grep_Shell_Escape_Char = '\' 211 | endif 212 | endif 213 | 214 | " The list of directories to skip while searching for a pattern. Set this 215 | " variable to '', if you don't want to skip directories. 216 | if !exists("Grep_Skip_Dirs") 217 | let Grep_Skip_Dirs = 'RCS CVS SCCS' 218 | endif 219 | 220 | " The list of files to skip while searching for a pattern. Set this variable 221 | " to '', if you don't want to skip any files. 222 | if !exists("Grep_Skip_Files") 223 | let Grep_Skip_Files = '*~ *,v s.*' 224 | endif 225 | 226 | " Run the grep commands asynchronously and update the quickfix list with the 227 | " results in the background. Needs Vim version 8.0 and above. 228 | if !exists('Grep_Run_Async') 229 | " Check whether we can run the grep command asynchronously. 230 | if v:version >= 800 231 | let Grep_Run_Async = 1 232 | " Check whether we can use the quickfix identifier to add the grep 233 | " output to a specific quickfix list. 234 | if v:version >= 801 || has('patch-8.0.1023') 235 | let s:Grep_Use_QfID = 1 236 | else 237 | let s:Grep_Use_QfID = 0 238 | endif 239 | else 240 | let Grep_Run_Async = 0 241 | endif 242 | endif 243 | 244 | " Table containing information about various grep commands. 245 | " command path, option prefix character, command options and the search 246 | " pattern expression option 247 | let s:cmdTable = { 248 | \ 'grep' : { 249 | \ 'cmdpath' : g:Grep_Path, 250 | \ 'optprefix' : '-', 251 | \ 'defopts' : '-s -n', 252 | \ 'opts' : g:Grep_Options, 253 | \ 'expropt' : '--', 254 | \ 'nulldev' : g:Grep_Null_Device 255 | \ }, 256 | \ 'fgrep' : { 257 | \ 'cmdpath' : g:Fgrep_Path, 258 | \ 'optprefix' : '-', 259 | \ 'defopts' : '-s -n', 260 | \ 'opts' : g:Fgrep_Options, 261 | \ 'expropt' : '-e', 262 | \ 'nulldev' : g:Grep_Null_Device 263 | \ }, 264 | \ 'egrep' : { 265 | \ 'cmdpath' : g:Egrep_Path, 266 | \ 'optprefix' : '-', 267 | \ 'defopts' : '-s -n', 268 | \ 'opts' : g:Egrep_Options, 269 | \ 'expropt' : '-e', 270 | \ 'nulldev' : g:Grep_Null_Device 271 | \ }, 272 | \ 'agrep' : { 273 | \ 'cmdpath' : g:Agrep_Path, 274 | \ 'optprefix' : '-', 275 | \ 'defopts' : '-n', 276 | \ 'opts' : g:Agrep_Options, 277 | \ 'expropt' : '', 278 | \ 'nulldev' : g:Grep_Null_Device 279 | \ }, 280 | \ 'ag' : { 281 | \ 'cmdpath' : g:Ag_Path, 282 | \ 'optprefix' : '-', 283 | \ 'defopts' : '--vimgrep', 284 | \ 'opts' : g:Ag_Options, 285 | \ 'expropt' : '', 286 | \ 'nulldev' : '' 287 | \ }, 288 | \ 'rg' : { 289 | \ 'cmdpath' : g:Rg_Path, 290 | \ 'optprefix' : '-', 291 | \ 'defopts' : '--vimgrep', 292 | \ 'opts' : g:Rg_Options, 293 | \ 'expropt' : '-e', 294 | \ 'nulldev' : '' 295 | \ }, 296 | \ 'ack' : { 297 | \ 'cmdpath' : g:Ack_Path, 298 | \ 'optprefix' : '-', 299 | \ 'defopts' : '-H --column --nofilter --nocolor --nogroup', 300 | \ 'opts' : g:Ack_Options, 301 | \ 'expropt' : '--match', 302 | \ 'nulldev' : '' 303 | \ }, 304 | \ 'findstr' : { 305 | \ 'cmdpath' : g:Findstr_Path, 306 | \ 'optprefix' : '/', 307 | \ 'defopts' : '/N', 308 | \ 'opts' : g:Findstr_Options, 309 | \ 'expropt' : '', 310 | \ 'nulldev' : '' 311 | \ }, 312 | \ 'git' : { 313 | \ 'cmdpath' : g:Git_Path, 314 | \ 'optprefix' : '-', 315 | \ 'defopts' : 'grep --no-color -n', 316 | \ 'opts' : g:Gitgrep_Options, 317 | \ 'expropt' : '-e', 318 | \ 'nulldev' : '' 319 | \ }, 320 | \ 'sift' : { 321 | \ 'cmdpath' : g:Sift_Path, 322 | \ 'optprefix' : '-', 323 | \ 'defopts' : '--no-color -n --filename --binary-skip', 324 | \ 'opts' : g:Sift_Options, 325 | \ 'expropt' : '-e', 326 | \ 'nulldev' : '' 327 | \ }, 328 | \ 'pt' : { 329 | \ 'cmdpath' : g:Pt_Path, 330 | \ 'optprefix' : '-', 331 | \ 'defopts' : '--nocolor --nogroup', 332 | \ 'opts' : g:Pt_Options, 333 | \ 'expropt' : '', 334 | \ 'nulldev' : '' 335 | \ }, 336 | \ 'ucg' : { 337 | \ 'cmdpath' : g:Ucg_Path, 338 | \ 'optprefix' : '-', 339 | \ 'defopts' : '--nocolor', 340 | \ 'opts' : g:Ucg_Options, 341 | \ 'expropt' : '', 342 | \ 'nulldev' : '' 343 | \ } 344 | \ } 345 | 346 | " warnMsg 347 | " Display a warning message 348 | func! s:warnMsg(msg) abort 349 | echohl WarningMsg | echomsg a:msg | echohl None 350 | endfunc 351 | 352 | let s:grep_cmd_job = 0 353 | let s:grep_tempfile = '' 354 | 355 | " deleteTempFile() 356 | " Delete the temporary file created on MS-Windows to run the grep command 357 | func! s:deleteTempFile() abort 358 | if has('win32') && !has('win32unix') && (&shell =~ 'cmd.exe') 359 | if exists('s:grep_tempfile') && s:grep_tempfile != '' 360 | " Delete the temporary cmd file created on MS-Windows 361 | call delete(s:grep_tempfile) 362 | let s:grep_tempfile = '' 363 | endif 364 | endif 365 | endfunc 366 | 367 | " grep#cmd_output_cb() 368 | " Add output (single line) from a grep command to the quickfix list 369 | func! grep#cmd_output_cb(qf_id, channel, msg) abort 370 | let job = ch_getjob(a:channel) 371 | if job_status(job) == 'fail' 372 | call s:warnMsg('Error: Job not found in grep command output callback') 373 | return 374 | endif 375 | 376 | " Check whether the quickfix list is still present 377 | if s:Grep_Use_QfID 378 | let l = getqflist({'id' : a:qf_id}) 379 | if !has_key(l, 'id') || l.id == 0 380 | " Quickfix list is not present. Stop the search. 381 | call job_stop(job) 382 | return 383 | endif 384 | 385 | call setqflist([], 'a', {'id' : a:qf_id, 386 | \ 'efm' : '%f:%\\s%#%l:%c:%m,%f:%\s%#%l:%m', 387 | \ 'lines' : [a:msg]}) 388 | else 389 | let old_efm = &efm 390 | set efm=%f:%\\s%#%l:%c:%m,%f:%\\s%#%l:%m 391 | caddexpr a:msg . "\n" 392 | let &efm = old_efm 393 | endif 394 | endfunc 395 | 396 | " grep#chan_close_cb 397 | " Close callback for the grep command channel. No more grep output is 398 | " available. 399 | func! grep#chan_close_cb(qf_id, channel) abort 400 | let job = ch_getjob(a:channel) 401 | if job_status(job) == 'fail' 402 | call s:warnMsg('Error: Job not found in grep channel close callback') 403 | return 404 | endif 405 | let emsg = '[Search command exited with status ' . job_info(job).exitval . ']' 406 | 407 | " Check whether the quickfix list is still present 408 | if s:Grep_Use_QfID 409 | let l = getqflist({'id' : a:qf_id}) 410 | if has_key(l, 'id') && l.id == a:qf_id 411 | call setqflist([], 'a', {'id' : a:qf_id, 412 | \ 'efm' : '%f:%\s%#%l:%m', 413 | \ 'lines' : [emsg]}) 414 | endif 415 | else 416 | caddexpr emsg 417 | endif 418 | endfunc 419 | 420 | " grep#cmd_exit_cb() 421 | " grep command exit handler 422 | func! grep#cmd_exit_cb(qf_id, job, exit_status) abort 423 | " Process the exit status only if the grep cmd is not interrupted 424 | " by another grep invocation 425 | if s:grep_cmd_job == a:job 426 | let s:grep_cmd_job = 0 427 | call s:deleteTempFile() 428 | endif 429 | endfunc 430 | 431 | " runGrepCmdAsync() 432 | " Run the grep command asynchronously 433 | func! s:runGrepCmdAsync(cmd, pattern, action) abort 434 | if s:grep_cmd_job isnot 0 435 | " If the job is already running for some other search, stop it. 436 | call job_stop(s:grep_cmd_job) 437 | caddexpr '[Search command interrupted]' 438 | endif 439 | 440 | let title = '[Search results for ' . a:pattern . ']' 441 | if a:action == 'add' 442 | caddexpr title . "\n" 443 | else 444 | cgetexpr title . "\n" 445 | endif 446 | "caddexpr 'Search cmd: "' . a:cmd . '"' 447 | call setqflist([], 'a', {'title' : title}) 448 | " Save the quickfix list id, so that the grep output can be added to 449 | " the correct quickfix list 450 | let l = getqflist({'id' : 0}) 451 | if has_key(l, 'id') 452 | let qf_id = l.id 453 | else 454 | let qf_id = -1 455 | endif 456 | 457 | if has('win32') && !has('win32unix') && (&shell =~ 'cmd.exe') 458 | let cmd_list = [a:cmd] 459 | else 460 | let cmd_list = [&shell, &shellcmdflag, a:cmd] 461 | endif 462 | let s:grep_cmd_job = job_start(cmd_list, 463 | \ {'callback' : function('grep#cmd_output_cb', [qf_id]), 464 | \ 'close_cb' : function('grep#chan_close_cb', [qf_id]), 465 | \ 'exit_cb' : function('grep#cmd_exit_cb', [qf_id]), 466 | \ 'in_io' : 'null'}) 467 | 468 | if job_status(s:grep_cmd_job) == 'fail' 469 | let s:grep_cmd_job = 0 470 | call s:warnMsg('Error: Failed to start the grep command') 471 | call s:deleteTempFile() 472 | return 473 | endif 474 | 475 | " Open the grep output window 476 | if g:Grep_OpenQuickfixWindow == 1 477 | " Open the quickfix window below the current window 478 | botright copen 479 | endif 480 | endfunc 481 | 482 | " runGrepCmd() 483 | " Run the specified grep command using the supplied pattern 484 | func! s:runGrepCmd(cmd, pattern, action) abort 485 | if has('win32') && !has('win32unix') && (&shell =~ 'cmd.exe') 486 | " Windows does not correctly deal with commands that have more than 1 487 | " set of double quotes. It will strip them all resulting in: 488 | " 'C:\Program' is not recognized as an internal or external command 489 | " operable program or batch file. To work around this, place the 490 | " command inside a batch file and call the batch file. 491 | " Do this only on Win2K, WinXP and above. 492 | let s:grep_tempfile = fnamemodify(tempname(), ':h:8') . '\mygrep.cmd' 493 | call writefile(['@echo off', a:cmd], s:grep_tempfile) 494 | 495 | if g:Grep_Run_Async 496 | call s:runGrepCmdAsync(s:grep_tempfile, a:pattern, a:action) 497 | return 498 | endif 499 | let cmd_output = system('"' . s:grep_tempfile . '"') 500 | 501 | if exists('s:grep_tempfile') 502 | " Delete the temporary cmd file created on MS-Windows 503 | call delete(s:grep_tempfile) 504 | endif 505 | else 506 | if g:Grep_Run_Async 507 | return s:runGrepCmdAsync(a:cmd, a:pattern, a:action) 508 | endif 509 | let cmd_output = system(a:cmd) 510 | endif 511 | 512 | " Do not check for the shell_error (return code from the command). 513 | " Even if there are valid matches, grep returns error codes if there 514 | " are problems with a few input files. 515 | 516 | if cmd_output == '' 517 | call s:warnMsg('Error: Pattern ' . a:pattern . ' not found') 518 | return 519 | endif 520 | 521 | let tmpfile = tempname() 522 | 523 | let old_verbose = &verbose 524 | set verbose&vim 525 | 526 | exe 'redir! > ' . tmpfile 527 | silent echon '[Search results for pattern: ' . a:pattern . "]\n" 528 | silent echon cmd_output 529 | redir END 530 | 531 | let &verbose = old_verbose 532 | 533 | let old_efm = &efm 534 | set efm=%f:%\\s%#%l:%c:%m,%f:%\\s%#%l:%m 535 | 536 | if a:action == 'add' 537 | execute 'silent! caddfile ' . tmpfile 538 | else 539 | execute 'silent! cgetfile ' . tmpfile 540 | endif 541 | 542 | let &efm = old_efm 543 | 544 | " Open the grep output window 545 | if g:Grep_OpenQuickfixWindow == 1 546 | " Open the quickfix window below the current window 547 | botright copen 548 | endif 549 | 550 | call delete(tmpfile) 551 | endfunc 552 | 553 | " parseArgs() 554 | " Parse arguments to the grep command. The expected order for the various 555 | " arguments is: 556 | " 557 | " grep command-line flags are specified using the "-flag" format. 558 | " the next argument is assumed to be the pattern. 559 | " and the next arguments are assumed to be filenames or file patterns. 560 | func! s:parseArgs(cmd_name, args) abort 561 | let cmdopt = '' 562 | let pattern = '' 563 | let filepattern = '' 564 | 565 | let optprefix = s:cmdTable[a:cmd_name].optprefix 566 | 567 | for one_arg in a:args 568 | if one_arg[0] == optprefix && pattern == '' 569 | " Process grep arguments at the beginning of the argument list 570 | let cmdopt = cmdopt . ' ' . one_arg 571 | elseif pattern == '' 572 | " Only one search pattern can be specified 573 | let pattern = shellescape(one_arg) 574 | else 575 | " More than one file patterns can be specified 576 | if filepattern != '' 577 | let filepattern = filepattern . ' ' . one_arg 578 | else 579 | let filepattern = one_arg 580 | endif 581 | endif 582 | endfor 583 | 584 | return [cmdopt, pattern, filepattern] 585 | endfunc 586 | 587 | " recursive_search_cmd 588 | " Returns TRUE if a command recursively searches by default. 589 | func! s:recursive_search_cmd(cmd_name) abort 590 | return a:cmd_name == 'ag' || 591 | \ a:cmd_name == 'rg' || 592 | \ a:cmd_name == 'ack' || 593 | \ a:cmd_name == 'git' || 594 | \ a:cmd_name == 'pt' || 595 | \ a:cmd_name == 'ucg' 596 | endfunc 597 | 598 | " formFullCmd() 599 | " Generate the full command to run based on the user supplied command name, 600 | " options, pattern and file names. 601 | func! s:formFullCmd(cmd_name, useropts, pattern, filenames) abort 602 | if !has_key(s:cmdTable, a:cmd_name) 603 | call s:warnMsg('Error: Unsupported command ' . a:cmd_name) 604 | return '' 605 | endif 606 | 607 | if has('win32') 608 | " On MS-Windows, convert the program pathname to 8.3 style pathname. 609 | " Otherwise, using a path with space characters causes problems. 610 | let s:cmdTable[a:cmd_name].cmdpath = 611 | \ fnamemodify(s:cmdTable[a:cmd_name].cmdpath, ':8') 612 | endif 613 | 614 | let cmdopt = s:cmdTable[a:cmd_name].defopts 615 | if s:cmdTable[a:cmd_name].opts != '' 616 | let cmdopt = cmdopt . ' ' . s:cmdTable[a:cmd_name].opts 617 | endif 618 | if a:useropts != '' 619 | let cmdopt = cmdopt . ' ' . a:useropts 620 | endif 621 | if s:cmdTable[a:cmd_name].expropt != '' 622 | let cmdopt = cmdopt . ' ' . s:cmdTable[a:cmd_name].expropt 623 | endif 624 | 625 | let fullcmd = s:cmdTable[a:cmd_name].cmdpath . ' ' . 626 | \ cmdopt . ' ' . 627 | \ a:pattern 628 | 629 | if a:filenames != '' 630 | let fullcmd = fullcmd . ' ' . a:filenames 631 | endif 632 | 633 | if s:cmdTable[a:cmd_name].nulldev != '' 634 | let fullcmd = fullcmd . ' ' . s:cmdTable[a:cmd_name].nulldev 635 | endif 636 | 637 | return fullcmd 638 | endfunc 639 | 640 | " getListOfBufferNames() 641 | " Get the file names of all the listed and valid buffer names 642 | func! s:getListOfBufferNames() abort 643 | let filenames = '' 644 | 645 | " Get a list of all the buffer names 646 | for i in range(1, bufnr("$")) 647 | if bufexists(i) && buflisted(i) 648 | let fullpath = fnamemodify(bufname(i), ':p') 649 | if filereadable(fullpath) 650 | if v:version >= 702 651 | let filenames = filenames . ' ' . fnameescape(fullpath) 652 | else 653 | let filenames = filenames . ' ' . fullpath 654 | endif 655 | endif 656 | endif 657 | endfor 658 | 659 | return filenames 660 | endfunc 661 | 662 | " getListOfArgFiles() 663 | " Get the names of all the files in the argument list 664 | func! s:getListOfArgFiles() abort 665 | let filenames = '' 666 | 667 | let arg_cnt = argc() 668 | if arg_cnt != 0 669 | for i in range(0, arg_cnt - 1) 670 | let filenames = filenames . ' ' . argv(i) 671 | endfor 672 | endif 673 | 674 | return filenames 675 | endfunc 676 | 677 | " grep#runGrepRecursive() 678 | " Run specified grep command recursively 679 | func! grep#runGrepRecursive(cmd_name, grep_cmd, action, ...) abort 680 | if a:0 > 0 && (a:1 == '-?' || a:1 == '-h') 681 | echo 'Usage: ' . a:cmd_name . ' [] [ ' . 682 | \ '[]]' 683 | return 684 | endif 685 | 686 | " Parse the arguments and get the grep options, search pattern 687 | " and list of file names/patterns 688 | let [opts, pattern, filenames] = s:parseArgs(a:grep_cmd, a:000) 689 | 690 | " No argument supplied. Get the identifier and file list from user 691 | if pattern == '' 692 | let pattern = input('Search for pattern: ', expand('')) 693 | if pattern == '' 694 | return 695 | endif 696 | let pattern = shellescape(pattern) 697 | echo "\r" 698 | endif 699 | 700 | let cwd = getcwd() 701 | if g:Grep_Cygwin_Find == 1 702 | let cwd = substitute(cwd, "\\", "/", 'g') 703 | endif 704 | let startdir = input('Start searching from directory: ', cwd, 'dir') 705 | if startdir == '' 706 | return 707 | endif 708 | echo "\r" 709 | 710 | if !isdirectory(startdir) 711 | call s:warnMsg('Error: Directory ' . startdir . " doesn't exist") 712 | return 713 | endif 714 | 715 | " To compare against the current directory, convert to full path 716 | let startdir = fnamemodify(startdir, ':p:h') 717 | 718 | if startdir == cwd 719 | let startdir = '.' 720 | else 721 | " On MS-Windows, convert the directory name to 8.3 style pathname. 722 | " Otherwise, using a path with space characters causes problems. 723 | if has('win32') 724 | let startdir = fnamemodify(startdir, ':8') 725 | endif 726 | endif 727 | 728 | if filenames == '' 729 | let filenames = input('Search in files matching pattern: ', 730 | \ g:Grep_Default_Filelist) 731 | if filenames == '' 732 | return 733 | endif 734 | echo "\r" 735 | endif 736 | 737 | let find_file_pattern = '' 738 | for one_pattern in split(filenames, ' ') 739 | if find_file_pattern != '' 740 | let find_file_pattern = find_file_pattern . ' -o' 741 | endif 742 | let find_file_pattern = find_file_pattern . ' -name ' . 743 | \ shellescape(one_pattern) 744 | endfor 745 | let find_file_pattern = g:Grep_Shell_Escape_Char . '(' . 746 | \ find_file_pattern . ' ' . g:Grep_Shell_Escape_Char . ')' 747 | 748 | let find_prune = '' 749 | if g:Grep_Skip_Dirs != '' 750 | for one_dir in split(g:Grep_Skip_Dirs, ' ') 751 | if find_prune != '' 752 | let find_prune = find_prune . ' -o' 753 | endif 754 | let find_prune = find_prune . ' -name ' . 755 | \ shellescape(one_dir) 756 | endfor 757 | 758 | let find_prune = '-type d ' . g:Grep_Shell_Escape_Char . '(' . 759 | \ find_prune . ' ' . g:Grep_Shell_Escape_Char . ')' . 760 | \ ' -prune -o' 761 | endif 762 | 763 | let find_skip_files = '-type f' 764 | for one_file in split(g:Grep_Skip_Files, ' ') 765 | let find_skip_files = find_skip_files . ' ! -name ' . 766 | \ shellescape(one_file) 767 | endfor 768 | 769 | " On MS-Windows, convert the find/xargs program path to 8.3 style path 770 | if has('win32') 771 | let g:Grep_Find_Path = fnamemodify(g:Grep_Find_Path, ':8') 772 | let g:Grep_Xargs_Path = fnamemodify(g:Grep_Xargs_Path, ':8') 773 | endif 774 | 775 | if g:Grep_Find_Use_Xargs == 1 776 | let grep_cmd = s:formFullCmd(a:grep_cmd, opts, pattern, '') 777 | let cmd = g:Grep_Find_Path . ' "' . startdir . '"' 778 | \ . ' ' . find_prune 779 | \ . ' ' . find_skip_files 780 | \ . ' ' . find_file_pattern 781 | \ . " -print0 | " 782 | \ . g:Grep_Xargs_Path . ' ' . g:Grep_Xargs_Options 783 | \ . ' ' . grep_cmd 784 | else 785 | let grep_cmd = s:formFullCmd(a:grep_cmd, opts, pattern, '{}') 786 | let cmd = g:Grep_Find_Path . ' ' . startdir 787 | \ . ' ' . find_prune . " -prune -o" 788 | \ . ' ' . find_skip_files 789 | \ . ' ' . find_file_pattern 790 | \ . " -exec " . grep_cmd . ' ' . 791 | \ g:Grep_Shell_Escape_Char . ';' 792 | endif 793 | 794 | call s:runGrepCmd(cmd, pattern, a:action) 795 | endfunc 796 | 797 | " grep#runGrepSpecial() 798 | " Search for a pattern in all the opened buffers or filenames in the 799 | " argument list 800 | func! grep#runGrepSpecial(cmd_name, which, action, ...) abort 801 | if a:0 > 0 && (a:1 == '-?' || a:1 == '-h') 802 | echo 'Usage: ' . a:cmd_name . ' [] []' 803 | return 804 | endif 805 | 806 | " Search in all the Vim buffers 807 | if a:which == 'buffer' 808 | let filenames = s:getListOfBufferNames() 809 | " No buffers 810 | if filenames == '' 811 | call s:warnMsg('Error: Buffer list is empty') 812 | return 813 | endif 814 | elseif a:which == 'args' 815 | " Search in all the filenames in the argument list 816 | let filenames = s:getListOfArgFiles() 817 | " No arguments 818 | if filenames == '' 819 | call s:warnMsg('Error: Argument list is empty') 820 | return 821 | endif 822 | endif 823 | 824 | if has('win32') && !has('win32unix') 825 | " On Windows-like systems, use 'findstr' to search in buffers/arglist 826 | let grep_cmd = 'findstr' 827 | else 828 | " On all other systems, use 'grep' to search in buffers/arglist 829 | let grep_cmd = 'grep' 830 | endif 831 | 832 | " Parse the arguments and get the command line options and pattern. 833 | " Filenames are not be supplied and should be ignored. 834 | let [opts, pattern, temp] = s:parseArgs(grep_cmd, a:000) 835 | 836 | if pattern == '' 837 | " No argument supplied. Get the identifier and file list from user 838 | let pattern = input('Search for pattern: ', expand('')) 839 | if pattern == '' 840 | return 841 | endif 842 | echo "\r" 843 | endif 844 | 845 | " Form the complete command line and run it 846 | let cmd = s:formFullCmd(grep_cmd, opts, pattern, filenames) 847 | call s:runGrepCmd(cmd, pattern, a:action) 848 | endfunc 849 | 850 | " grep#runGrep() 851 | " Run the specified grep command 852 | func! grep#runGrep(cmd_name, grep_cmd, action, ...) abort 853 | if a:0 > 0 && (a:1 == '-?' || a:1 == '-h') 854 | echo 'Usage: ' . a:cmd_name . ' [] [ ' . 855 | \ '[]]' 856 | return 857 | endif 858 | 859 | " Parse the arguments and get the grep options, search pattern 860 | " and list of file names/patterns 861 | let [opts, pattern, filenames] = s:parseArgs(a:grep_cmd, a:000) 862 | 863 | " Get the identifier and file list from user 864 | if pattern == '' 865 | let pattern = input('Search for pattern: ', expand('')) 866 | if pattern == '' 867 | return 868 | endif 869 | let pattern = shellescape(pattern) 870 | echo "\r" 871 | endif 872 | 873 | if filenames == '' && !s:recursive_search_cmd(a:grep_cmd) 874 | let filenames = input('Search in files: ', g:Grep_Default_Filelist, 875 | \ 'file') 876 | if filenames == '' 877 | return 878 | endif 879 | echo "\r" 880 | endif 881 | 882 | " Form the complete command line and run it 883 | let cmd = s:formFullCmd(a:grep_cmd, opts, pattern, filenames) 884 | call s:runGrepCmd(cmd, pattern, a:action) 885 | endfunc 886 | 887 | " restore 'cpo' 888 | let &cpo = s:cpo_save 889 | unlet s:cpo_save 890 | -------------------------------------------------------------------------------- /doc/grep.txt: -------------------------------------------------------------------------------- 1 | *grep.txt* Plugin for integrating grep like tools with Vim 2 | 3 | Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) 4 | For Vim version 7.0 and above 5 | Last change: May 26, 2018 6 | 7 | ============================================================================== 8 | *grep-license* 9 | License: MIT License 10 | Copyright (c) 2002-2018 Yegappan Lakshmanan 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to 14 | deal in the Software without restriction, including without limitation the 15 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | sell copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 28 | IN THE SOFTWARE. 29 | ============================================================================== 30 | CONTENTS~ 31 | 32 | 1. Overview |grep-overview| 33 | 2. Installation |grep-installation| 34 | 3. Usage |grep-usage| 35 | 4. Configuration |grep-configuration| 36 | 37 | ============================================================================== 38 | *grep-overview* 39 | 1. Overview~ 40 | 41 | The grep plugin integrates grep like utilities (grep, fgrep, egrep, agrep, 42 | findstr, silver searcher, ack, ripgrep, git grep, sift, platinum searcher and 43 | universal code grep) with Vim and allows you to search for a pattern in one or 44 | more files and jump to them. 45 | 46 | To use this plugin, you will need the grep like utilities in your system. If 47 | a particular utility is not present, then you cannot use the corresponding 48 | features, but you can still use the rest of the features supported by the 49 | plugin. 50 | 51 | To use the this plugin with grep, you will need the grep, fgrep and egrep 52 | utilities. To recursively search for files using grep, you will need the find 53 | and xargs utilities. These tools are present in most of the Linux/Unix and 54 | MacOS installations. For MS-Windows systems, you can download the GNU grep 55 | and find utilities from the following sites: 56 | 57 | http://gnuwin32.sourceforge.net/packages/grep.htm 58 | http://gnuwin32.sourceforge.net/packages/findutils.htm 59 | 60 | On MS-Windows, you can use the findstr utility to search for patterns. This 61 | is available by default on all MS-Windows systems. 62 | 63 | If you want to use the agrep command with this plugin, then you can download 64 | the agrep utility from: 65 | 66 | https://www.tgries.de/agrep/ 67 | 68 | If you want to use the Silver Searcher (ag) with this plugin, then you can 69 | download the Silver Searcher from: 70 | 71 | https://github.com/ggreer/the_silver_searcher 72 | 73 | If you want to use the ack utility with this plugin, then you can download the 74 | ack utility from: 75 | 76 | https://beyondgrep.com/ 77 | 78 | If you want to use ripgrep (rg) with this plugin, then you can download the 79 | ripgrep utility from: 80 | 81 | https://github.com/BurntSushi/ripgrep 82 | 83 | If you want to use the sift utility with this plugin, then you can download 84 | the sift utility from: 85 | 86 | https://sift-tool.org 87 | 88 | If you want to use the platinum searcher with this plugin, then you can 89 | download the platinum searcher utility from: 90 | 91 | https://github.com/monochromegane/the_platinum_searcher 92 | 93 | If you want to use the universal code grep with this plugin, then you can 94 | download the universal code grep utility from: 95 | 96 | https://gvansickle.github.io/ucg 97 | 98 | The silver searcher, ripgrep, ack, sift, platinum searcher and universal code 99 | grep utilities can search for a pattern recursively across directories without 100 | using any other additional utilities like find and xargs. 101 | 102 | The github repository for this plugin is at https://github.com/yegappan/grep 103 | 104 | ============================================================================== 105 | *grep-installation* 106 | 2. Installation~ 107 | 108 | You can use any one of the Vim plugin managers (dein.vim, pathogen, vam, 109 | vim-plug, volt, Vundle, etc.) to install and manage this plugin. 110 | 111 | Alternatively, you can also manually download and install the plugin 112 | using the following steps. 113 | 114 | 1. Download the grep.zip file from the https://vim.sourceforge.io site. 115 | 2. Expand the grep.zip file to the $HOME/.vim/plugin or 116 | $HOME/vimfiles/plugin or $VIM/vimfiles/plugin directory. 117 | 3. If the grep executables are not already present in one of the directories 118 | in the PATH environment variable, then set the Grep_Path and other _Path 119 | variables to point to the location of the grep utilities in the .vimrc 120 | file. 121 | 4. Restart Vim. 122 | 5. You can now use the ":Grep" and other commands to search for patterns in 123 | files. 124 | 125 | ============================================================================== 126 | *grep-usage* 127 | 3. Usage~ 128 | 129 | The grep.vim plugin introduces the following Vim commands: 130 | 131 | :Grep - Search for the specified pattern in the specified files 132 | :GrepAdd - Same as ":Grep" but adds the results to the current results 133 | :Rgrep - Run recursive grep 134 | :RgrepAdd - Same as ":Rgrep" but adds the results to the current results 135 | :GrepBuffer - Search for a pattern on all open buffers 136 | :GrepBufferAdd - Same as ":GrepBuffer" but adds the results to the current 137 | list 138 | :Bgrep - Same as :GrepBuffer 139 | :BgrepAdd - Same as :GrepBufferAdd 140 | :GrepArgs - Search for a pattern on all the Vim argument 141 | filenames (:args) 142 | :GrepArgsAdd - Same as ":GrepArgs" but adds the results to the current list 143 | :Fgrep - Run fgrep 144 | :FgrepAdd - Same as ":Fgrep" but adds the results to the current list 145 | :Rfgrep - Run recursive fgrep 146 | :RfgrepAdd - Same as ":Rfgrep" but adds the results to the current list 147 | :Egrep - Run egrep 148 | :EgrepAdd - Same as ":Egrep" but adds the results to the current list 149 | :Regrep - Run recursive egrep 150 | :RegrepAdd - Same as ":Regrep" but adds the results to the current list 151 | :Findstr - Search for a pattern in files. Available only on MS-Windows. 152 | :FindstrAdd - Same as ":Findstr" but adds the results to the current list 153 | :Agrep - Run agrep 154 | :AgrepAdd - Same as ":Agrep" but adds the results to the current list 155 | :Ragrep - Run recursive agrep 156 | :RagrepAdd - Same as ":Ragrep" but adds the results to the current list 157 | :Ag - Run the silver searcher (ag) 158 | :AgAdd - Same as ":Ag" but adds the results to the current list 159 | :Ack - Run ack 160 | :AckAdd - Same as ":Ack" but adds the results to the current list 161 | :Rg - Run ripgrep (rg) 162 | :RgAdd - Same as ":Rg" but adds the results to the current list 163 | :Gitgrep - Run git grep 164 | :GitgrepAdd - Same as ":Gitgrep" but adds the results to the current list 165 | :Sift - Run sift 166 | :SiftAdd - Same as ":Sift" but adds the results to the current list 167 | :Ptgrep - Run the platinum searcher (pt) 168 | :PtgrepAdd - Same as ":Ptgrep" but adds the results to the current list 169 | :Ucgrep - Run the Universal code grep (ucg) 170 | :UcgrepAdd - Same as ":Ucgrep" but adds the results to the current list 171 | 172 | The above commands can be invoked like this: 173 | 174 | :Grep [] [ []] 175 | :Rgrep [] [ []] 176 | :Fgrep [] [ []] 177 | :Rfgrep [] [ []] 178 | :Egrep [] [ []] 179 | :Regrep [] [ []] 180 | :Agrep [] [ []] 181 | :Ragrep [] [ []] 182 | :Findstr [] [ []] 183 | :Ag [] [ []] 184 | :Ack [] [ []] 185 | :Rg [] [ []] 186 | :Gitgrep [] [ []] 187 | :Sift [] [ []] 188 | :Ptgrep [] [ []] 189 | :Ucgrep [] [ []] 190 | 191 | :GrepAdd [] [ []] 192 | :RgrepAdd [] [ []] 193 | :FgrepAdd [] [ []] 194 | :RfgrepAdd [] [ []] 195 | :EgrepAdd [] [ []] 196 | :RegrepAdd [] [ []] 197 | :FindstrAdd [] [ []] 198 | :AgrepAdd [] [ []] 199 | :RagrepAdd [] [ []] 200 | :AgAdd [] [ []] 201 | :AckAdd [] [ []] 202 | :RgAdd [] [ []] 203 | :GitgrepAdd [] [ []] 204 | :SiftAdd [] [ []] 205 | :PtgrepAdd [] [ []] 206 | :UcgrepAdd [] [ []] 207 | 208 | :GrepBuffer [] [] 209 | :Bgrep [] [] 210 | :GrepArgs [] [] 211 | 212 | :GrepBufferAdd [] [] 213 | :BgrepAdd [] [] 214 | :GrepArgsAdd [] [] 215 | 216 | In the above commands, all the arguments are optional. 217 | 218 | You can specify grep options like -i (ignore case) or -w (search for a word) 219 | to the above commands. To always pass a set of command line flags to the 220 | grep command, you can set the Grep_Options variable. There are similar 221 | variables for other commands. 222 | 223 | You can specify the grep pattern to search as an argument to the above 224 | commands. If the is not specified, then you will be prompted 225 | to enter a search pattern. By default, the keyword under the cursor is 226 | displayed for the search pattern prompt. You can accept the default or modify 227 | it. 228 | 229 | The search pattern is automatically enclosed by the escape character. You 230 | should not enclose the search pattern with a shell escape character. 231 | 232 | If you want to specify a search pattern with space characters or a multi-word 233 | pattern, then you should run the Grep command without any arguments and use 234 | the search pattern input prompt to supply the search pattern. 235 | 236 | You can specify one or more file names (or file patterns) to the above 237 | commands. If the are not specified, then you will be prompted to 238 | enter file names. By default, the pattern specified by the 239 | Grep_Default_Filelist variable is used. To specify the file name(s) as an 240 | argument to the above commands, you have to specify the search pattern also. 241 | 242 | When using search utilities like ag, ack, ripgrep and git grep which searches 243 | recursively by default, if you don't specify a filename, then the command will 244 | search recursively. 245 | 246 | When you enter only the command name, you will be prompted to enter the search 247 | pattern and the files in which to search for the pattern. By default, the 248 | keyword under the cursor is displayed for the search pattern prompt. 249 | Depending on the command, you may prompted for additional parameters like the 250 | directories to search for the pattern. 251 | 252 | On MS-Windows, the command line options for the findstr.exe utility are 253 | prefixed with '/'. The ':Findstr' command accepts options prefixed with '/'. 254 | Examples: 255 | 256 | " To search for 'windows' ignoring case 257 | :Findstr /I windows *.java 258 | " To search for 'class' recursively from the current directory 259 | :Findstr /S class *.java 260 | 261 | You can retrieve previously entered values for the Grep prompts using the up 262 | and down arrow keys. You can cancel the command by pressing the escape key. 263 | You can use CTRL-U to erase the default shown for the prompt and CTRL-W to 264 | erase the previous word in the prompt. For more information about editing the 265 | prompt, read |:cmdline-editing| Vim help topic. 266 | 267 | After invoking any of the grep commands, you can cancel the command, when you 268 | are prompted for a search pattern or file names or a directory by pressing the 269 | key. If you are using a Vim version before 8.0, then you cannot cancel 270 | (or kill) the grep/fgrep/egrep/agrep commands after the external command is 271 | invoked. 272 | 273 | If you are using Vim version 8.0 and above, then the grep commands are run 274 | asynchronously in the background. The search output is parsed and the results 275 | are added to the quickfix list in the background. Invoking a grep command will 276 | cancel the current grep command which is running in the background (if any). 277 | 278 | The GrepAdd, RgrepAdd and other *Add commands append the search output to the 279 | current search output. This is useful if you want to see the search results 280 | for multiple patterns at the same time. These commands are available only in 281 | Vim version 7.0 and above. 282 | 283 | Some examples for using the silver searcher command to search for a pattern 284 | are below: 285 | > 286 | " To search for 'myclass' recursively from the current directory 287 | :Ag myclass . 288 | " To search for 'myclass' only in .java files in the current directory 289 | :Ag myclass *.java 290 | " To search for 'myclass' only in .java files recursively 291 | :Ag --java myclass . 292 | < 293 | You can map a key to invoke any of the above commands. For example, the 294 | following map invokes the :Grep command to search for the keyword under the 295 | cursor: 296 | 297 | nnoremap :Grep 298 | 299 | The output of the grep command will be listed in the Vim quickfix window. 300 | 1. You can select a line in the quickfix window and press or double 301 | click on a match to jump to that line. 302 | 2. You can use the ":cnext" and ":cprev" commands to the jump to the next or 303 | previous output line. 304 | 3. You can use the ":colder" and ":cnewer" commands to go between multiple 305 | grep quickfix output windows. 306 | 4. The quickfix window need not be opened always to use the grep output. 307 | You can close the quickfix window and use the quickfix commands to jump 308 | to the grep matches. Use the ":copen" command to open the quickfix 309 | window again. 310 | 311 | For more information about other quickfix commands read ":help quickfix" 312 | 313 | When using GUI Vim, the Tools->Search menu item with a few sub-menu items is 314 | created for few variations of the search command. 315 | 316 | Note that when recursively searching for a pattern using the silver searcher, 317 | ripgrep, ack, git grep, sift, platinum searcher or universal code grep 318 | utilities, if a large number (several thousands) of matching files are found, 319 | then it will take some time for Vim to load all the files into the buffer 320 | list. In the meantime, Vim will be slow to respond or may not respond to 321 | keystrokes. 322 | 323 | ============================================================================== 324 | *grep-configuration* 325 | 4. Configuration~ 326 | 327 | By changing the following variables you can configure the behavior of this 328 | plugin. Set the following variables in your .vimrc file using the |:let| 329 | command. 330 | 331 | The 'Grep_Path' variable is used to locate the grep utility. By default, this 332 | is set to grep. You can change this using the let command: 333 | 334 | :let Grep_Path = 'C:\Progra~1\Grep\grep.exe' 335 | 336 | The 'Fgrep_Path' variable is used to locate the fgrep utility. By default, 337 | this is set to fgrep. You can change this using the let command: 338 | 339 | :let Fgrep_Path = 'C:\Progra~1\Grep\fgrep.exe' 340 | 341 | The 'Egrep_Path' variable is used to locate the egrep utility. By default, 342 | this is set to egrep. You can change this using the let command: 343 | 344 | :let Egrep_Path = 'C:\Progra~1\Grep\egrep.exe' 345 | 346 | The 'Agrep_Path' variable is used to locate the agrep utility. By default, 347 | this is set to agrep. You can change this using the let command: 348 | 349 | :let Agrep_Path = 'C:\Progra~1\Grep\agrep.exe' 350 | 351 | The 'Findstr_Path' variable is used to locate the findstr.exe utility on 352 | MS-Windows. By default, this is set to findstr.exe. You can change this using 353 | the let command: 354 | 355 | :let Findstr_Path = 'C:\Windows\System32\findstr.exe' 356 | 357 | The 'Ag_Path' variable is used to locate the ag (silver searcher) utility. By 358 | default, this is set to ag. You can change this using the let command: 359 | 360 | :let Ag_Path = 'C:\Progra~1\Silver_Searcher\ag.exe' 361 | 362 | The 'Ack_Path' variable is used to locate the ack utility. By default, this is 363 | set to ack. You can change this using the let command: 364 | 365 | :let Ack_Path = 'C:\Progra~1\ack\ack.pl' 366 | 367 | The 'Rg_Path' variable is used to locate the rg (ripgrep) utility. By default, 368 | this is set to rg. You can change this using the let command: 369 | 370 | :let Rg_Path = 'C:\Progra~1\ripgrep\rg.exe' 371 | 372 | The 'Git_Path' variable is used to locate the git utility used by the Gitgrep 373 | command. By default, this is set to git. You can change this using the let 374 | command: 375 | 376 | :let Git_Path = 'C:\Progra~1\git\git.exe' 377 | 378 | The 'Sift_Path' variable is used to locate the sift utility used by the Sift 379 | command. By default, this is set to sift. You can change this using the let 380 | command: 381 | 382 | :let Sift_Path = 'C:\Progra~1\sift\sift.exe' 383 | 384 | The 'Pt_Path' variable is used to locate the platinum searcher utility used by 385 | the Ptgrep command. By default, this is set to pt. You can change this 386 | using the let command: 387 | 388 | :let Pt_Path = 'C:\Progra~1\pt\pt.exe' 389 | 390 | The 'Ucg_Path' variable is used to locate the universal code grep utility used by 391 | the Ucgrep command. By default, this is set to ucg. You can change this 392 | using the let command: 393 | 394 | :let Ucg_Path = '/usr/local/bin/ucg' 395 | 396 | The 'Grep_Find_Path' variable is used to locate the find utility. By default, 397 | this is set to 'find'. Note that on MS-Windows, there is a find.exe that is 398 | part of the base OS. This find utility is different from the Unix find 399 | utility. You cannot use this utility with this plugin. You must install the 400 | Unix compatible find utility and set the Grep_Find_Path variable to point to 401 | the location of the utility. You can change this using the let command: 402 | 403 | :let Grep_Find_Path = 'C:\Progra~1\Grep\find.exe' 404 | 405 | The 'Grep_Xargs_Path' variable is used to locate the xargs utility. By 406 | default, this is set to xargs. You can change this using the let command: 407 | 408 | :let Grep_Xargs_Path = 'C:\Progra~1\Grep\xargs.exe' 409 | 410 | When running any one of the Grep commands, you will be prompted for the files 411 | in which to search for the pattern. The 'Grep_Default_Filelist' variable is 412 | used to specify to default for this prompt. By default, this variable is set 413 | to '*'. You can specify multiple matching patterns separated by spaces. You 414 | can change this settings using the let command: 415 | 416 | :let Grep_Default_Filelist = '*.[chS]' 417 | :let Grep_Default_Filelist = '*.c *.cpp *.asm' 418 | 419 | The 'Grep_Options' variable is used to pass command line options to the grep 420 | command. By default, this is set to an empty string. You can change this 421 | using the let command: 422 | 423 | :let Grep_Options = '-i' 424 | 425 | Similarly you can pass command line options to other commands by setting the 426 | 'Fgrep_Options', 'Egrep_Options', 'Agrep_Options', 'Findstr_Options', 427 | 'Ag_options', 'Ack_Options', 'Rg_Options', "Gitgrep_Options', 'Sift_Options', 428 | 'Pt_Options' and 'Ucg_Options' variables in your .vimrc file. 429 | 430 | The 'Grep_Skip_Dirs' variable specifies the list of directories to skip while 431 | doing recursive searches. This is used only by the :Rgrep, :Rfgrep, :Regrep, 432 | and :Ragrep commands. By default, this is set to 'RCS CVS SCCS'. You can 433 | change this using the let command: 434 | 435 | :let Grep_Skip_Dirs = 'dir1 dir2 dir3' 436 | 437 | The 'Grep_Skip_Files' variable specifies the list of files to skip while doing 438 | recursive searches. This is used only by the :Rgrep, :Rfgrep, :Regrep, and 439 | :Ragrep commands. By default, this is set to '*~ *,v s.*'. You can change this 440 | using the let command: 441 | 442 | :let Grep_Skip_Files = '*.bak *~' 443 | 444 | By default, when you invoke the Grep commands the quickfix window will be 445 | opened with the grep output. You can disable opening the quickfix window, by 446 | setting the 'Grep_OpenQuickfixWindow' variable to zero: 447 | 448 | :let Grep_OpenQuickfixWindow = 0 449 | 450 | You can manually open the quickfix window using the :cwindow command. 451 | 452 | By default, for recursive searches, the 'find' and 'xargs' utilities are used. 453 | If you don't have the 'xargs' utility or don't want to use the 'xargs' 454 | utility, " then you can set the 'Grep_Find_Use_Xargs' variable to zero. If 455 | this is set to zero, then only the 'find' utility is used for recursive 456 | searches: 457 | 458 | :let Grep_Find_Use_Xargs = 0 459 | 460 | To handle file names with space characters in them, the xargs utility is 461 | invoked with the '-0' argument. If the xargs utility in your system doesn't 462 | accept the '-0' argument, then you can change the Grep_Xargs_Options variable. 463 | For example, to use the '--null' xargs argument, you can use the following 464 | command: 465 | 466 | :let Grep_Xargs_Options = '--null' 467 | 468 | The Grep_Cygwin_Find variable should be set to 1, if you are using the find 469 | utility from the cygwin package. This setting is used to handle the difference 470 | between the backslash and forward slash path separators. 471 | 472 | :let Grep_Cygwin_Find = 1 473 | 474 | The 'Grep_Null_Device' variable specifies the name of the null device to pass 475 | to the grep commands. This is needed to force the grep commands to print the 476 | name of the file in which a match is found, if only one filename is specified. 477 | For Unix systems, this is set to /dev/null and for MS-Windows systems, this is 478 | set to NUL. You can modify this by using the let command: 479 | 480 | :let Grep_Null_Device = '/dev/null' 481 | 482 | The 'Grep_Shell_Escape_Char' variable specifies the escape character to use 483 | for protecting special characters from being interpreted by the shell. For 484 | Unix systems, this is set to '\' and for MS-Window systems, this is set to an 485 | empty string. You can change this using the let command: 486 | 487 | :let Grep_Shell_Escape_Char = "'" 488 | 489 | The 'Grep_Run_Async' variable specifies whether the grep commands are run 490 | synchronously or asynchronously. Depending on the Vim version, this variable 491 | is set automatically. If you want to force Vim to run the grep commands 492 | synchronously, then you can set the 'Grep_Run_Async' variable to 1. 493 | 494 | ============================================================================== 495 | 496 | vim:tw=78:ts=8:noet:ft=help: 497 | -------------------------------------------------------------------------------- /plugin/grep.vim: -------------------------------------------------------------------------------- 1 | " File: grep.vim 2 | " Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) 3 | " Version: 2.2 4 | " Last Modified: May 26, 2018 5 | " 6 | " Plugin to integrate grep like utilities with Vim 7 | " Supported utilities are: grep, fgrep, egrep, agrep, findstr, ag, ack, 8 | " ripgrep, git grep, sift, platinum searcher and universal code grep 9 | " 10 | " License: MIT License 11 | " Copyright (c) 2002-2018 Yegappan Lakshmanan 12 | " 13 | " Permission is hereby granted, free of charge, to any person obtaining a copy 14 | " of this software and associated documentation files (the "Software"), to 15 | " deal in the Software without restriction, including without limitation the 16 | " rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 17 | " sell copies of the Software, and to permit persons to whom the Software is 18 | " furnished to do so, subject to the following conditions: 19 | " 20 | " The above copyright notice and this permission notice shall be included in 21 | " all copies or substantial portions of the Software. 22 | " 23 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | " IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | " FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | " AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | " LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 | " FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 29 | " IN THE SOFTWARE. 30 | " ======================================================================= 31 | if exists("loaded_grep") 32 | finish 33 | endif 34 | let loaded_grep = 1 35 | 36 | if v:version < 700 37 | " Needs vim version 7.0 and above 38 | finish 39 | endif 40 | 41 | " Line continuation used here 42 | let s:cpo_save = &cpo 43 | set cpo&vim 44 | 45 | " Define the commands for invoking various grep utilities 46 | 47 | " grep commands 48 | command! -nargs=* -complete=file Grep 49 | \ call grep#runGrep('Grep', 'grep', 'set', ) 50 | command! -nargs=* -complete=file Rgrep 51 | \ call grep#runGrepRecursive('Rgrep', 'grep', 'set', ) 52 | command! -nargs=* -complete=file GrepAdd 53 | \ call grep#runGrep('GrepAdd', 'grep', 'add', ) 54 | command! -nargs=* -complete=file RgrepAdd 55 | \ call grep#runGrepRecursive('RgrepAdd', 'grep', 'add', ) 56 | 57 | " fgrep commands 58 | command! -nargs=* -complete=file Fgrep 59 | \ call grep#runGrep('Fgrep', 'fgrep', 'set', ) 60 | command! -nargs=* -complete=file Rfgrep 61 | \ call grep#runGrepRecursive('Rfgrep', 'fgrep', 'set', ) 62 | command! -nargs=* -complete=file FgrepAdd 63 | \ call grep#runGrep('FgrepAdd', 'fgrep', 'add', ) 64 | command! -nargs=* -complete=file RfgrepAdd 65 | \ call grep#runGrepRecursive('RfgrepAdd', 'fgrep', 'add', ) 66 | 67 | " egrep commands 68 | command! -nargs=* -complete=file Egrep 69 | \ call grep#runGrep('Egrep', 'egrep', 'set', ) 70 | command! -nargs=* -complete=file Regrep 71 | \ call grep#runGrepRecursive('Regrep', 'egrep', 'set', ) 72 | command! -nargs=* -complete=file EgrepAdd 73 | \ call grep#runGrep('EgrepAdd', 'egrep', 'add', ) 74 | command! -nargs=* -complete=file RegrepAdd 75 | \ call grep#runGrepRecursive('RegrepAdd', 'egrep', 'add', ) 76 | 77 | " agrep commands 78 | command! -nargs=* -complete=file Agrep 79 | \ call grep#runGrep('Agrep', 'agrep', 'set', ) 80 | command! -nargs=* -complete=file Ragrep 81 | \ call grep#runGrepRecursive('Ragrep', 'agrep', 'set', ) 82 | command! -nargs=* -complete=file AgrepAdd 83 | \ call grep#runGrep('AgrepAdd', 'agrep', 'add', ) 84 | command! -nargs=* -complete=file RagrepAdd 85 | \ call grep#runGrepRecursive('RagrepAdd', 'agrep', 'add', ) 86 | 87 | " Silver Searcher (ag) commands 88 | command! -nargs=* -complete=file Ag 89 | \ call grep#runGrep('Ag', 'ag', 'set', ) 90 | command! -nargs=* -complete=file AgAdd 91 | \ call grep#runGrep('AgAdd', 'ag', 'add', ) 92 | 93 | " Ripgrep (rg) commands 94 | command! -nargs=* -complete=file Rg 95 | \ call grep#runGrep('Rg', 'rg', 'set', ) 96 | command! -nargs=* -complete=file RgAdd 97 | \ call grep#runGrep('RgAdd', 'rg', 'add', ) 98 | 99 | " ack commands 100 | command! -nargs=* -complete=file Ack 101 | \ call grep#runGrep('Ack', 'ack', 'set', ) 102 | command! -nargs=* -complete=file AckAdd 103 | \ call grep#runGrep('AckAdd', 'ack', 'add', ) 104 | 105 | " git grep commands 106 | command! -nargs=* -complete=file Gitgrep 107 | \ call grep#runGrep('Gitgrep', 'git', 'set', ) 108 | command! -nargs=* -complete=file GitgrepAdd 109 | \ call grep#runGrep('GitgrepAdd', 'git', 'add', ) 110 | 111 | " sift commands 112 | command! -nargs=* -complete=file Sift 113 | \ call grep#runGrep('Sift', 'sift', 'set', ) 114 | command! -nargs=* -complete=file SiftAdd 115 | \ call grep#runGrep('SiftAdd', 'sift', 'add', ) 116 | 117 | " Platinum Searcher commands 118 | command! -nargs=* -complete=file Ptgrep 119 | \ call grep#runGrep('Ptgrep', 'pt', 'set', ) 120 | command! -nargs=* -complete=file PtgrepAdd 121 | \ call grep#runGrep('PtgrepAdd', 'pt', 'add', ) 122 | 123 | " Universal Code Grep commands 124 | command! -nargs=* -complete=file Ucgrep 125 | \ call grep#runGrep('Ucgrep', 'ucg', 'set', ) 126 | command! -nargs=* -complete=file UcgrepAdd 127 | \ call grep#runGrep('UcgrepAdd', 'ucg', 'add', ) 128 | 129 | 130 | " findstr commands 131 | if has('win32') 132 | command! -nargs=* -complete=file Findstr 133 | \ call grep#runGrep('Findstr', 'findstr', 'set', ) 134 | command! -nargs=* -complete=file FindstrAdd 135 | \ call grep#runGrep('FindstrAdd', 'findstr', 'add', ) 136 | endif 137 | 138 | " Buffer list grep commands 139 | command! -nargs=* GrepBuffer 140 | \ call grep#runGrepSpecial('GrepBuffer', 'buffer', 'set', ) 141 | command! -nargs=* Bgrep 142 | \ call grep#runGrepSpecial('Bgrep', 'buffer', 'set', ) 143 | command! -nargs=* GrepBufferAdd 144 | \ call grep#runGrepSpecial('GrepBufferAdd', 'buffer', 'add', ) 145 | command! -nargs=* BgrepAdd 146 | \ call grep#runGrepSpecial('BgrepAdd', 'buffer', 'add', ) 147 | 148 | " Argument list grep commands 149 | command! -nargs=* GrepArgs 150 | \ call grep#runGrepSpecial('GrepArgs', 'args', 'set', ) 151 | command! -nargs=* GrepArgsAdd 152 | \ call grep#runGrepSpecial('GrepArgsAdd', 'args', 'add', ) 153 | 154 | " Add the Tools->Search Files menu 155 | if has('gui_running') 156 | anoremenu Tools.Search.Current\ Directory:Grep 157 | \ :Grep 158 | anoremenu Tools.Search.Recursively:Rgrep 159 | \ :Rgrep 160 | anoremenu Tools.Search.Buffer\ List:Bgrep 161 | \ :Bgrep 162 | anoremenu Tools.Search.Argument\ List:GrepArgs 163 | \ :GrepArgs 164 | endif 165 | 166 | " restore 'cpo' 167 | let &cpo = s:cpo_save 168 | unlet s:cpo_save 169 | 170 | --------------------------------------------------------------------------------