global search里用helm grep 搜索多个字的顺序问题

各位好,我使用的helm grep,不过比如说我想搜索含有first和second两个单词的行, 原文中的文本是“first word second word…"。 在pattern中搜”first second"是可以搜到结果的,但是如果我把两个单词调换顺序比如 说搜“second first"就搜不到结果。 但是按照下面链接的说法应该是可以搜到结果的。

https://emacs.stackexchange.com/questions/51449/does-grepping-via-helm-support-searching-for-multiple-words-in-any-order-like-ot

不知道有没有人遇到类似的情况?

匹配结果取决于搜索的方式,1)背后到底用了哪个命令?Grep、Git-Grep 等等,不同命令都不一样;2)怎么处理你的输入的?会不会预处理,比如有的会把 first second 拆解成二次 grep,有的不会。

你得结合自己使用的命令来调查,helm + grep 类工具有 N 种不同的命令和包,每个都有自己的解释。

以 helm-find-files 的 Grep Action (helm-ff-run-grep) 为例,它不会有你提到的问题。

背后用的就是grep,比如说搜索的字符是 test,如果搜索不到结果它会显示command line的命令是

grep -a -r …(各种–exclude和–exclude-dir) -niH -e test .

但是我不知道为什么如果搜索两个单词它搜索不到结果就不会显示command line是什么。

奇怪的是如果用helm-find-files的Grep File(s) Action (因为我没有找到一个只叫Grep的Action), 关键词的顺序又不再影响搜索结果。如果搜索一个单词(比如说test)不到结果,显示的command line是

grep --color=always -a -r skip …(各种–exclude和–exclude-dir) -niH -e test path/to/the/select/file

当然我也可以每次先搜一个单词,然后再Save results in grep buffer,再在这个buffer里面找,不过这样好麻烦啊。

背后用的就是grep,比如说搜索的字符是 test,如果搜索不到结果它会显示command line的命令是

grep -a -r …(各种–exclude和–exclude-dir) -niH -e test .

但是我不知道为什么如果搜索两个单词它搜索不到结果就不会显示command line是什么。

奇怪的是如果用helm-find-files的Grep File(s) Action (因为我没有找到一个只叫Grep的Action), 关键词的顺序又不再影响搜索结果。如果搜索一个单词(比如说test)不到结果,显示的command line是

grep --color=always -a -r skip …(各种–exclude和–exclude-dir) -niH -e test path/to/the/select/file

当然我也可以每次先搜一个单词,然后再Save results in grep buffer,再在这个buffer里面找,不过这样好麻烦啊。

此 Grep 彼 Grep 不一样,helm-find-files 的 Grep File(s) Action 会把 foo bar 解释成 grep foo | grep bar,但不要假设其它的 Grep Action 也会这么做,调用 grep 两次很可能比调用一次慢,假如要我来写个 Grep Action,我首先想到的是 grep foo.*bar,这样顺序就有影响了。

好吧,那就是虽然都被翻译到ubuntu里面的grep了,但是具体的实现可能有区别。

我平时对spacemacs的经验基本限于使用,请问你有什么建议让默认的global search能忽略顺序吗?或者怎么做才知道具体是什么命令被调用了呢?

就算是同一个 Grep,grep 'foo bar'grep foo | grep bar 也不是一个意思,你所使用的 Grep Action 决定了你的输入是如何解释的,你没有说你用的到底是哪个命令,我说 helm-find-files 的 Grep Files(s) Action 会把 foo bar 解释成 grep foo | bar,我没说其它的 Grep Action 亦如此,而且更有可能它们并不会这样做。

我用的就是spacemacs默认的search project命令,快捷键是SPC /,但是它具体是怎么实现多个关键字的搜索我就不知道了。

所以说你得先确认这个命令有没有说 foo bar 和 bar foo 搜索结果一样,如果没有的话,就不要假设有同样结果,而且根据你之前得描述,这个命令本来就区分 foo bar 和 bar foo,你看到的是预期结果,也就没「问题」可言。

试一下 counsel-etags-grep 来自 GitHub - redguardtoo/counsel-etags: Fast, energy-saving, and powerful code navigation solution 基本思路是两步法,

  • 第一步,用户输入第一个关键字给命令行程序grep。
  • 第二步,用户输入第二个关键字,用Emacs Lisp做进一步的过滤

优点是,

  • 原生就去除第一个和第二个关键字的顺序依赖
  • 性能在所有操作系统上都很稳定
  • 反模式很可靠(counsel/ivy官方插件极不可靠)
  • 第二步甚至可以用文件路径过滤

这个方法我认为是上策,给counsel/ivy的作者也推荐过,不过没有被采用

谢谢你的建议。但是官方文档里面就只有非常简短的介绍 https://www.spacemacs.org/doc/DOCUMENTATION.html#searching-in-a-project SPC / or SPC s p search with the first found tool。 所以根本不知道它本来的预期结果是什么,只能从直觉上判断。

谢谢你的建议。但是如果两步的话不用安装counsel-etags-grep也能实现啊,就是 第一步先搜一个单词,然后再Save results in grep buffer,再在这个buffer里面找。

不过你说的反模式是什么啊?

在显示可选项前需要两步,目的是把启动进程数量控制在一个,之后的过滤用lisp来做。我谈的都是后台进程和Lisp编程。是你能看到任何UI之前的处理。

你所说的在ivy的UI里输入单词每输入一个字符,ivy就要启动一个命令行程序进程。这也是Windows下性能差的原因。

反模式是指的感叹号之后的关键字都是excluded keyword。符合反模式的都过滤掉不显示。ivy一直有这个界面,但是实现不稳定,作者对这个功能也没有上心。对我来说这是最常用的功能。

1 个赞

尝试了下你推荐的counsel-etags,确实很好用。谢谢啦