vim 的 grep 插件`Leaderf rg`:grep 和模糊匹配的完美结合
前言vim有很多著名的grep插件,我使用过的有ack.vim,ag.vim和ctrlsf.vim,它们应该也是目前用户最多的几个了。ack.vim起步比较早,早期后端grep工具是ack,后来也支持ag(the_silver_searcher),pt(the_platinum_searcher),rg(ripgrep)等工具了。它是一个比较传统的grep插件,不支持异步,要等到grep结束后才能显示结果,在大的项目中grep会卡好一阵子。它貌似也不再维护,我N久前提交的pull request还挂在那,它最近的代码更新在11个月前。ag.vim它其实是抄袭ack.vim,没错,是抄袭。在早期ack.vim还不支持ag时,它的作者在ack.vim代码的基础上稍微改了改,支持了ag。后来被ack.vim的作者给怼了,就放弃了对ag.vim的维护。目前功能上小于ack.vim。ctrlsf.vim这是国人开发的一个插件, 后端grep工具支持ack/ag/pt/rg,同时也支持异步,不过需要Vim 8.0.1039+或者NeoVim才支持异步。这个插件很好用,在我开发Leaderf rg之前一直使用的是它。Leaderf rg顾名思义,后端基于rg,由于是LeaderF的子功能,基因上就决定它完美支持异步。同时LeaderF又是一个非著名的模糊查找插件,这使它可以在grep结果的基础上再通过模糊匹配的方式进行二次过滤,来帮助用户更快地锁定目标,这是目前上面提到的插件所不具备的。为什么选择rg(ripgrep)快速grep工具目前有ag, rg, pt, sift, ucg等。 我选择rg有以下几点原因:速度比较快,rg的README上有作者的对比,我实测也是rg快点。Windows上bug少(bug到目前还没发现),ag和pt都遇到过bug。作者很活跃,提的issue能很快得到回复。rg功能相对多些,可以从rg –help 看出来。Leaderf rg 使用介绍Leaderf rg的使用也比较简单,只要Leaderf[!] + rg命令和选项(同命令行上一样)就可以了。具体使用方法可以用:Leaderf rg -h来查看。usage: Leaderf[!] rg [-h] [-e <PATTERN>…] [-F] [-i] [-L] [-P] [-S] [-s] [-v] [-w] [-x] [–hidden] [–no-config] [–no-ignore] [–no-ignore-global] [–no-ignore-parent] [–no-ignore-vcs] [–no-pcre2-unicode] [-E <ENCODING>] [-M <NUM>] [-m <NUM>] [–max-depth <NUM>] [–max-filesize <NUM+SUFFIX?>] [–path-separator <SEPARATOR>] [–sort <SORTBY>] [–sortr <SORTBY>] [-f <PATTERNFILE>…] [-g <GLOB>…] [–iglob <GLOB>…] [–ignore-file <PATH>…] [–type-add <TYPE_SPEC>…] [-t <TYPE>…] [-T <TYPE>…] [–current-buffer | –all-buffers] [–recall] [–append] [–reverse] [–stayOpen] [–input <INPUT> | –cword] [–top | –bottom | –left | –right | –belowright | –aboveleft | –fullScreen] [–nameOnly | –fullPath | –fuzzy | –regexMode] [–nowrap] [<PATH> [<PATH> …]]optional arguments: -h, –help show this help message and exitspecific arguments: -e <PATTERN>…, –regexp <PATTERN>… A pattern to search for. This option can be provided multiple times, where all patterns given are searched. -F, –fixed-strings Treat the pattern as a literal string instead of a regular expression. -i, –ignore-case Searches case insensitively. -L, –follow Follow symbolic links while traversing directories. -P, –pcre2 When this flag is present, rg will use the PCRE2 regex engine instead of its default regex engine. -S, –smart-case Searches case insensitively if the pattern is all lowercase, case sensitively otherwise. -s, –case-sensitive Searches case sensitively. -v, –invert-match Invert matching. Show lines that do not match the given patterns. -w, –word-regexp Only show matches surrounded by word boundaries. This is roughly equivalent to putting \b before and after all of the search patterns. -x, –line-regexp Only show matches surrounded by line boundaries. –hidden Search hidden files and directories. By default, hidden files and directories are skipped. –no-config Never read configuration files. When this flag is present, rg will not respect the RIPGREP_CONFIG_PATH environment variable. –no-ignore Don’t respect ignore files (.gitignore, .ignore, etc.). This implies –no-ignore-parent and –no-ignore-vcs. –no-ignore-global Don’t respect ignore files that come from ‘global’ sources such as git’s core.excludesFile configuration option (which defaults to $HOME/.config/git/ignore). –no-ignore-parent Don’t respect ignore files (.gitignore, .ignore, etc.) in parent directories. –no-ignore-vcs Don’t respect version control ignore files (.gitignore, etc.). –no-pcre2-unicode When PCRE2 matching is enabled, this flag will disable Unicode mode, which is otherwise enabled by default. -E <ENCODING>, –encoding <ENCODING> Specify the text encoding that rg will use on all files searched. -M <NUM>, –max-columns <NUM> Don’t print lines longer than this limit in bytes. -m <NUM>, –max-count <NUM> Limit the number of matching lines per file searched to NUM. –max-depth <NUM> Limit the depth of directory traversal to NUM levels beyond the paths given. –max-filesize <NUM+SUFFIX?> Ignore files larger than NUM in size. This does not apply to directories. –path-separator <SEPARATOR> Set the path separator to use when printing file paths. –sort <SORTBY> This flag enables sorting of results in ascending order. –sortr <SORTBY> This flag enables sorting of results in descending order. -f <PATTERNFILE>…, –file <PATTERNFILE>… Search for patterns from the given file, with one pattern per line. (This option can be provided multiple times.) -g <GLOB>…, –glob <GLOB>… Include or exclude files and directories for searching that match the given glob.(This option can be provided multiple times.) –iglob <GLOB>… Include or exclude files and directories for searching that match the given glob. Globs are matched case insensitively.(This option can be provided multiple times.) –ignore-file <PATH>… Specifies a path to one or more .gitignore format rules files. –type-add <TYPE_SPEC>… Add a new glob for a particular file type. -t <TYPE>…, –type <TYPE>… Only search files matching TYPE. Multiple type flags may be provided. -T <TYPE>…, –type-not <TYPE>… Do not search files matching TYPE. Multiple type-not flags may be provided. <PATH> A file or directory to search. Directories are searched recursively. Paths specified on the command line override glob and ignore rules. –current-buffer Searches in current buffer. –all-buffers Searches in all listed buffers. –recall Recall last search. If the result window is closed, reopen it. –append Append to the previous search results.common arguments: –reverse show results in bottom-up order –stayOpen don’t quit LeaderF after accepting an entry –input <INPUT> specifies INPUT as the pattern inputted in advance –cword current word under cursor is inputted in advance –top the LeaderF window is at the top of the screen –bottom the LeaderF window is at the bottom of the screen –left the LeaderF window is at the left of the screen –right the LeaderF window is at the right of the screen –belowright the LeaderF window is at the belowright of the screen –aboveleft the LeaderF window is at the aboveleft of the screen –fullScreen the LeaderF window takes up the full screen –nameOnly LeaderF is in NameOnly mode by default –fullPath LeaderF is in FullPath mode by default –fuzzy LeaderF is in Fuzzy mode by default –regexMode LeaderF is in Regex mode by default –nowrap long lines in the LeaderF window won’t wrapIf [!] is given, enter normal mode directly.注意:如果:Leaderf后面有感叹号,会直接进入normal模式;如果没有感叹号,则是输入模式,此时可以输入字符来进行模糊匹配过滤。可以用tab键在两个模式间来回切换。Leaderf rg基本支持rg所有的必要选项,用户如果对rg命令比较熟悉,可以在vim命令行内输入:Leaderf, 然后手敲rg命令,命令选项还可以通过tab来补全。当然,更聪明的做法是定义一些快捷键。例如:" search word under cursor, the pattern is treated as regex, and enter normal mode directlynoremap <C-F> :<C-U><C-R>=printf(“Leaderf! rg -e %s “, expand("<cword>”))<CR>” search word under cursor, the pattern is treated as regex," append the result to previous search results.noremap <C-G> :<C-U><C-R>=printf(“Leaderf! rg –append -e %s “, expand("<cword>”))<CR>” search word under cursor literally only in current buffernoremap <C-B> :<C-U><C-R>=printf(“Leaderf! rg -F –current-buffer -e %s “, expand("<cword>”))<CR>” search word under cursor literally in all listed buffersnoremap <C-D> :<C-U><C-R>=printf(“Leaderf! rg -F –all-buffers -e %s “, expand("<cword>”))<CR>” search visually selected text literally, don’t quit LeaderF after accepting an entryxnoremap gf :<C-U><C-R>=printf(“Leaderf! rg -F –stayOpen -e %s “, leaderf#Rg#visual())<CR>” recall last search. If the result window is closed, reopen it.noremap go :<C-U>Leaderf! rg –recall<CR>” search word under cursor in *.h and *.cpp files.noremap <Leader>a :<C-U><C-R>=printf(“Leaderf! rg -e %s -g *.h -g *.cpp”, expand("<cword>"))<CR>" the same as abovenoremap <Leader>a :<C-U><C-R>=printf(“Leaderf! rg -e %s -g *.{h,cpp}”, expand("<cword>"))<CR>" search word under cursor in cpp and java files.noremap <Leader>b :<C-U><C-R>=printf(“Leaderf! rg -e %s -t cpp -t java”, expand("<cword>"))<CR>" search word under cursor in cpp files, exclude the .hpp filesnoremap <Leader>c :<C-U><C-R>=printf(“Leaderf! rg -e %s -t cpp -g !.hpp”, expand("<cword>"))<CR>参考:rg的glob语法。顺便说一下,直接在vim命令行敲:Leaderf rg,就会有传说中的"grep on the fly"的功能哦,同时支持fuzzy和regex两种模式。会不会支持ag等其他grep工具不会。 首先,ripgrep已经足够强大,基本不存在别的工具有而ripgrep没有的功能。其次,ripgrep有编译好的Windows、Linux和MacOS上的binary,可以在这些平台上很容易安装。再者,由于作者比较懒,不想再实现重复的功能。 ...