In his article What’s new in Emacs 27.1? Mickey Petersen wrote that the built-in
project.el1 is a library “not widely used” and “about 20 years too late”,
concluding that it is “a missed opportunity”.
From what I can tell
project.el has been around since 2015. As everything else
in our Emacs world, it’s an effort from volunteers offered back to the
community. I see no reason to avoid it because it has been lacking the attention
of other well-known alternatives such as Projectile. On the contrary, I believe
that the more users try it and report what is missing back to the developers or
perhaps contribute with lines of code, the more chances this tiny library has to
grow and to get better.
Instead of replacing
project.el, I decided to leave Helm aside
for a moment and try my luck with Icomplete. I trust Protesilaos Stavrou’s
opinion on it, anyway, so that’s another good point to give it a shot. If you
want a detailed setup for Icomplete be sure to follow his lead. I limited myself
to installing icomplete-vertical and orderless to make my life easier.
The entry point in
project.el is the prefix C-x p. You can hit C-h after that to
see the available key bindings. If you press C-x p p a list of known projects
will appear. You will see that an option to select a new project is always
available, so it’s trivial to add new elements here.
Once you land on your candidate hit RET to be presented with a customizable list of commands to act on the selected project. The keys to activate the commands are highlighted so, for instance, you can press f to start exploring your project files.
The defaults key bindings provided by
project.el suit me well enough, but I did
apply some changes to tune its behaviour to my needs.
First, I don’t want to rely on
project--files-in-directory when the
faster fd is around the corner.
(el-patch-defun project--files-in-directory (dir ignores &optional files) (el-patch-remove (require 'find-dired) (require 'xref) (defvar find-name-arg)) (let* ((default-directory dir) ;; Make sure ~/ etc. in local directory name is ;; expanded and not left for the shell command ;; to interpret. (localdir (file-local-name (expand-file-name dir))) (command (el-patch-swap (format "%s %s %s -type f %s -print0" find-program localdir (xref--find-ignores-arguments ignores localdir) (if files (concat (shell-quote-argument "(") " " find-name-arg " " (mapconcat #'shell-quote-argument (split-string files) (concat " -o " find-name-arg " ")) " " (shell-quote-argument ")")) "")) (format "fd -t f -0 . %s" localdir)))) (project--remote-file-names (sort (split-string (shell-command-to-string command) "\0" t) #'string<))))
Then I had to tweak
project-kill-buffer-conditions for buffers in
cider-repl-mode to ensure
project-kill-buffers catches them.
(add-to-list 'project-kill-buffer-conditions '(major-mode . cider-repl-mode) t)
The last customization was adding quick keys for
project-switch-commands. You don’t need my Elisp for that.
As little and work-in-progress as it is,
project.el already covers everything
I usually need to handle my projects. It’s good to know that right within our
beloved text editor comes a tool like this. And no, Pat Benatar, this time is
not too little too late.