Emacs递归项目搜索

20

我正在从TextMate转换到Emacs。TextMate中我想要拥有的一个功能是“在项目中查找”搜索框,它使用模糊匹配。Emacs有点像这个功能,使用ido,但ido不会递归搜索子目录。它只在一个目录内搜索。

有没有办法给ido一个根目录,并在其下搜索所有内容?

更新:

下面的问题涉及Michał Marczyk答案中的find-file-in-project.el。

如果这条消息中的任何内容听起来很显然,那是因为我才用Emacs不到一周。 :-)

据我了解,project-local-variables允许我在我的项目根目录中定义一个.emacs-project文件中的内容。

如何将find-file-in-project指向我的项目根目录?

我不熟悉Emacs Lisp中的正则表达式语法。 ffip-regexp的默认值是:

".*\\.\\(rb\\|js\\|css\\|yml\\|yaml\\|rhtml\\|erb\\|html\\|el\\)"

我认为我只需要将扩展名切换到适合我的项目的扩展名即可。

能否解释一下ffip-find-options?源文件中的内容如下:

(defvar ffip-find-options "" "使用find-file-in-project时传递给“find”的额外选项。

使用它来排除您项目的部分:“-not -regex \\".vendor.\\"\"")

这具体是什么意思,以及如何使用它来排除文件/目录?

你可以分享一个.emacs-project文件的例子吗?


关于textmate.el怎么样:https://github.com/defunkt/textmate.el - pesho hristov
8个回答

15

我使用M-x rgrep来进行这项操作。它会自动跳过许多你不需要的东西,比如.svn目录。


2
几乎...但您仍然需要手动指定搜索应该从哪里开始。 - jrockway
2
“rgrep”很棒,但正如jrockaway所说,完全绕过一些交互提示会更好。 - David J.

11

(主要更新是为了包含实际设置指令,以便与RINARI发行版中提到的find-file-in-project.el一起使用。原始答案保持不变;新内容在第二个水平线之后。)


请查看EmacsWiki的TextMate页面。他们提到的最有前途的东西可能是这个Emacs Lisp脚本,它提供了由一些变量引导的“项目目录”下的递归搜索。该文件以广泛的注释部分开始,描述如何使用它。

特别有前途的是以下部分:

;; If `ido-mode' is enabled, the menu will use `ido-completing-read'
;; instead of `completing-read'.

注意,我自己没有使用过它...但既然我找到了它,我很可能会尝试一下!:-)

希望有所帮助。

(顺便说一句,这个脚本是 Rinari 的一部分 -- 引用自 GitHub 的描述 -- "Rinari 不是 Rails IDE(它是一个针对 Rails 的 Emacs minor mode)"。如果你正在进行任何 Rails 开发,你可能想要查看整个东西。)


在继续之前,请配置 ido.el。认真地说,它本身就是必备的,而且它会改善你使用 find-file-in-project 的体验。观看 Stuart Halloway 的 这个视频演示(我已经在这个答案的评论中提到过)以了解为什么需要使用它。此外,Stu 通过自己的方式模拟 TextMate 的项目范围文件查找功能,展示了 ido 有多灵活;如果他的函数适合你的需求,那么就不需要再读下去了。

好的,现在来介绍如何设置 RINARI 的 find-file-in-project.el

  1. 从 RINARI 发布中获取 find-file-in-project.elproject-local-variables.el,并将它们放在 Emacs 可以找到的某个地方 (也就是load-path变量中的一个目录; 您可以使用(add-to-list 'load-path "/path/to/some/directory")将新目录添加到其中)。

  2. (require 'find-file-in-project)添加到您的.emacs文件中。还要添加以下内容,使C-x C-M-f序列带出查找文件在项目提示:(global-set-key (kbd "C-x C-M-f") 'find-file-in-project)

  3. 在您的项目根目录下创建一个名为.emacs-project的文件。至少应该包含像这样的内容:(setl ffip-regexp ".*\\.\\(clj\\|py\\)$")。这将使只有文件名和在cljpy中的文件才会被搜索; 请根据您的需求调整正则表达式。(注意,这个正则表达式将传递给 Unix 的find实用程序,应使用find首选的正则表达式语法。在 Emacs 中仍然必须双倍反斜杠在正则表达式中; 是否还需要在括号/管道(|)之前加上反斜杠,如果您想使用它们的“魔术”正则表达式含义,则取决于您的find的期望。上面给出的示例对我在 Ubuntu 上有效。如有疑问,请查阅有关正则表达式的其他信息。) (注意:在最后一次编辑中修正了一些有关正则表达式语法的混淆。)

  4. C-x C-M-f进行查找。

有许多可能的自定义设置; 特别是,您可以使用(setl ffip-find-options "...")将其他选项传递给 Unix 的find命令,在幕后调用find-file-in-project.el

如果发现有问题,请检查和仔细检查您的拼写--我曾经做过这样的事情:(setl ffip-regex ...)一次 (注意变量名称中缺少最后一个'p'),最初很困惑地发现没有找到任何文件。


实际上你错了。这不是一个“所有文件”的列表——它使用正则表达式,用户可以配置,以确定搜索什么。此外,它理解“项目根目录”概念以进行搜索,并且在与ido一起使用时具有模糊完成功能。顺便说一下,这似乎正是OP所要求的,也是你个人项目所声称正在做的事情。 - Michał Marczyk
谢谢你的回答,Michał。我还有一些关于如何使用find-file-in-project的问题。我已经把它们放到了原始问题中。 - hekevintran
我已经编辑了一些基本的设置说明--如果这有帮助,请告诉我。如果不行,一旦我制作出更有趣的.emacs-project(可能是明天),我会进行另一个编辑。(显然,我还没有发现需要更高级选项的情况。)另外,请考虑描述您感兴趣的实际场景(即项目目录布局、文件扩展名等),也许我或其他人将能够提供相匹配的配置。 - Michał Marczyk
好的,我已经澄清了答案中相关的部分。希望这就是问题所在;我不知道还有什么可能出错,因为我自己也在使用同样类型的表达式。如果你需要调试它,请尝试在终端中使用与find-file-in-project相同选项的find命令(-type f -regex + 你的正则表达式 + 任何其他要放在ffip-find-options中的选项)。 - Michał Marczyk
我已经安装了GNU find。有没有办法告诉Emacs,当它使用shell命令“find”时,应该运行/opt/local/bin/gfind而不是/usr/bin/find? - hekevintran
显示剩余10条评论

4

这非常接近CtrlP的功能...我一直在寻找像这样的东西...永远:D... (现在,只需使用“Alt+T”而不是“Ctrl+P”:)...) - pesho hristov

3

eproject有一个名为eproject-grep的工具,可以完美地满足你的需求。

只需要正确定义项目,它就会仅搜索项目文件;忽略版本控制、构建产物、生成文件等。唯一的缺点是需要在您的系统上安装grep命令;不过这个依赖很快就会被消除。


你刚刚给其他几个答案点了踩,但实际上它们都没有错,其中一个甚至提供了与你链接的这个项目非常相似的功能... 你为什么要这样做呢? - Michał Marczyk
已安装23.1版本(eproject所需)。eproject可以正常工作!但需要注意的是,您必须配置每种语言/项目文件,以便eproject可以搜索到。最终,eproject在搜索完所有它认为在您的项目中的文件后,会运行一个grep命令。 - Justin Tanner
贡献你使用的编程语言,这样其他人就不必再配置它们了。我一直想收集一堆这样的东西。(维基上有Scala、Haskell和Perl。) - jrockway

2

对于纯粹、无杂质的速度,我强烈推荐使用命令行工具The Silver Searcher(也称为“ag”)和ag.el的组合。如果你正在使用git、hg或svn,并且搜索整个项目,ag-project交互函数将会对你的项目根目录进行教育性的猜测。


2
您可以使用GNU Global或IDUtils来实现所需效果。它们不是专门为Emacs设计的,但它们有Emacs脚本来集成该效果。(我自己对它们了解不多。)
您还可以选择使用CEDET和EDE项目系统。EDE可能有点重,但它有一种方法可以标记项目的顶部。如果您还将GNU Global或IDUtils索引文件与项目一起保存,EDE可以使用它来按名称在任何地方查找文件,或者您可以使用“semantic-symref”在源文件中查找符号的引用。CEDET位于http://cedet.sf.net

0

FileCache 也是一个选择。但是你需要手动使用 file-cache-add-directory-recursively 添加你的项目目录。


0

关于如何使用Icicles,请参考以下链接:

Icicles完成匹配可以是子字符串、正则表达式、模糊匹配(各种类型)或这些的组合。您还可以结合简单的模式,交叉匹配或补充(减去)其中的子集。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接