乐趣区

一些在Emacs中搜索文本的方法

在 Emacs 中写代码的时候,常常需要查找一个函数、方法,或者变量的定义。如果是正在写 Common Lisp,那么 SLIME 已经配置好了相应的快捷键 M -.,只需要将光标移动到要查看的函数、方法,或者变量的名字上,按下 M -. 便可以跳转过去——再按一下 M -, 还能回到原来的位置。
如果是写其它语言的代码,很多时候都没办法方便地跳转过去,这时候就需要依赖于文本搜索了,这也是本篇所要讲述的主题。
通常情况下,用 C - s 和 C - r 就足够了——一个负责“往下”搜索一个负责“往上”搜索。尤其在安装了 Emacs 的插件 swiper 之后,只需使用 C - s 便可以同时查看到上下两个方向的匹配文本。

但 C - s 也有其局限性。例如,它不能跨文件搜索,如果要查看的函数、方法,或者变量的定义不在当前 buffer 中,就不得不手动在多个 buffer 间切换并频繁按下 C - s 了。
有多种办法可以解决上面这种问题。例如,可以用 Emacs 的 projectile-ag。通常,如果代码散布在多个源文件中,那么它们多半是放在一个项目中——比如一个 Git 仓库。打开位于项目中的文件时,Emacs 的 projectile-mode 就会启动。此时,按下 C -c C-p s s 这套组合键,会调用 projectile-ag 函数。projectile-ag 会在 minibuffer 中等候输入要搜索的内容,按下回车后,Emacs 会调用命令行工具 ag 来搜索这个项目下的所有文件,找出匹配关键字的行并显示。
projectile-ag 函数会打开另一个 buffer 来展示搜索结果,一个示例如下
ag –literal –group –line-number –column –color –color-match 30\;43 –color-path 1\;32 –smart-case –stats — emacs .
0 matches
0 files contained matches
36 files searched
111365 bytes searched
0.007795 seconds
使用 projectile-ag 的前提是要搜索的文件都在同一个一个项目中,但并非所有时候都满足这个要求。这时,可以用 Emacs 的 find-grep 函数。
find-grep 函数调起后同样要求使用者在 minibuffer 输入内容,但它更原始一点

光标会定位在 - e 选项之后,需要填补交给 grep 的正则表达式。由于 minibuffer 中给出的是完整的、将会被运行的命令,因此可以也给 find 命令添加一些选项和参数,来改变搜索行为。
如果是在一个 Node.js 项目中搜索,一般还要让 find 忽略一些文件,如 node_modules 目录下的大量依赖,或者构建产生出来的.css 和.js 文件。这些文件中的行不仅很可能会命中输入的正则表达式,还极可能成片地出现,占据搜索结果中的半壁江山。
除了 grep 之外,还有许多命令行的文本搜索工具,例如 ack 和 rg,并且它们都称自己更快。要在 Emacs 中使用它们也很简单,尤其是后者还有相应的插件 rg.el 可以方便调起。
如果经常要控制 find 来忽略 node_modules,可以考虑用 git-grep。man git-grep 中说到,它只会搜索 tracked 的文件

node_modules 一般都不会被 git 跟踪,自然也就不会被搜索。
全文完

退出移动版