在之前的文章中就多次提到过 28 版本的 project.el 是如何好用,但一直没去详细介绍,这篇文章就来填上这个坑。一句话总结,project.el 完全可以替换 projectile[1]。
下载
直接编译 28 版本或者在 elpa[2] 下载最新版。project 相关命令绑定在 C-x p
。
根目录
在日常编程中,Emacs 的很多包都依赖一个功能:查找当前项目的根目录,比如 lsp-mode、citre 等。在 project.el 中,默认只支持 VC[3] 中的 Git,即 project-try-vc,但可以自定义找根目录的方式,配置如下:
代码语言:javascript复制(defun my/project-try-local (dir)
"Determine if DIR is a non-Git project."
(catch 'ret
(let ((pr-flags '((".project" "pom.xml" "go.mod" "Cargo.toml" "project.clj") ;; higher priority
("Makefile" "README.org" "README.md"))))
(dolist (current-level pr-flags)
(dolist (f current-level)
(when-let ((root (locate-dominating-file dir f)))
(throw 'ret (cons 'local root))))))))
(setq project-find-functions '(my/project-try-local project-try-vc))
my/project-try-local
函数定义了常用编程语言的依赖描述文件,只要有这些文件,都可以看作项目根目录。作为额外的补充,可以通过创建一个名为 .project
的文件,用作根目录的标识,与 .projectile
类似
该函数返回一个 cons,car 为项目类型,这里定义为 local,cdr 为根目录。
查找文件
查找文件是非常高频的操作,可以使用 Rust 编写的 fd[4] 来代替 find,速度更快。配置如下:
代码语言:javascript复制(defun my/project-files-in-directory (dir)
"Use `fd' to list files in DIR."
(let* ((default-directory dir)
(localdir (file-local-name (expand-file-name dir)))
(command (format "fd -H -t f -0 . %s" localdir)))
(project--remote-file-names
(sort (split-string (shell-command-to-string command) "