前言
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 ...] [-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 ]
[-M ] [-m ] [--max-depth ]
[--max-filesize ]
[--path-separator ] [--sort ]
[--sortr ] [-f ...] [-g ...]
[--iglob ...] [--ignore-file ...]
[--type-add ...] [-t ...] [-T ...]
[--current-buffer | --all-buffers] [--recall] [--append]
[--reverse] [--stayOpen] [--input | --cword]
[--top | --bottom | --left | --right | --belowright | --aboveleft | --fullScreen]
[--nameOnly | --fullPath | --fuzzy | --regexMode] [--nowrap]
[ [ ...]]
optional arguments:
-h, --help show this help message and exit
specific arguments:
-e ..., --regexp ...
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
Specify the text encoding that rg will use on all files searched.
-M , --max-columns
Don't print lines longer than this limit in bytes.
-m , --max-count
Limit the number of matching lines per file searched to NUM.
--max-depth Limit the depth of directory traversal to NUM levels beyond the paths given.
--max-filesize
Ignore files larger than NUM in size. This does not apply to directories.
--path-separator
Set the path separator to use when printing file paths.
--sort This flag enables sorting of results in ascending order.
--sortr This flag enables sorting of results in descending order.
-f ..., --file ...
Search for patterns from the given file, with one pattern per line.
(This option can be provided multiple times.)
-g ..., --glob ...
Include or exclude files and directories for searching that match the given
glob.(This option can be provided multiple times.)
--iglob ... 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 ...
Specifies a path to one or more .gitignore format rules files.
--type-add ...
Add a new glob for a particular file type.
-t ..., --type ...
Only search files matching TYPE. Multiple type flags may be provided.
-T ..., --type-not ...
Do not search files matching TYPE. Multiple type-not flags may be provided.
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 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 wrap
If [!] 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 directly
noremap :=printf("Leaderf! rg -e %s ", expand(""))
" search word under cursor, the pattern is treated as regex,
" append the result to previous search results.
noremap :=printf("Leaderf! rg --append -e %s ", expand(""))
" search word under cursor literally only in current buffer
noremap :=printf("Leaderf! rg -F --current-buffer -e %s ", expand(""))
" search word under cursor literally in all listed buffers
noremap :=printf("Leaderf! rg -F --all-buffers -e %s ", expand(""))
" search visually selected text literally, don't quit LeaderF after accepting an entry
xnoremap gf :=printf("Leaderf! rg -F --stayOpen -e %s ", leaderf#Rg#visual())
" recall last search. If the result window is closed, reopen it.
noremap go :Leaderf! rg --recall
" search word under cursor in *.h and *.cpp files.
noremap a :=printf("Leaderf! rg -e %s -g *.h -g *.cpp", expand(""))
" the same as above
noremap a :=printf("Leaderf! rg -e %s -g *.{h,cpp}", expand(""))
" search word under cursor in cpp and java files.
noremap b :=printf("Leaderf! rg -e %s -t cpp -t java", expand(""))
" search word under cursor in cpp files, exclude the *.hpp files
noremap c :=printf("Leaderf! rg -e %s -t cpp -g !*.hpp", expand(""))
参考:rg的glob语法。
顺便说一下,直接在vim命令行敲:Leaderf rg
,就会有传说中的"grep on the fly"
的功能哦,同时支持fuzzy和regex两种模式。
会不会支持ag等其他grep工具
不会。
首先,ripgrep已经足够强大,基本不存在别的工具有而ripgrep没有的功能。其次,ripgrep有编译好的Windows、Linux和MacOS上的binary,可以在这些平台上很容易安装。再者,由于作者比较懒,不想再实现重复的功能。