-
Notifications
You must be signed in to change notification settings - Fork 41
Eproject for Perl
Here’s what my Perl support looks like right now:
(define-project-type perl (generic)
(or (look-for "Makefile.PL") (look-for "Build.PL"))
:relevant-files ("\\.pm$" "\\.t$" "\\.pl$" "\\.PL$")
:irrelevant-files ("inc/" "blib/" "cover_db/")
:mxdeclare-project-p (lambda (root)
(file-exists-p (concat root ".mxdeclare_project")))
:file-name-map (lambda (root)
(lambda (root file)
(cond ((string-match "^lib/\\(.+\\)[.]pm$" file)
(let ((m (match-string 1 file)))
(while (string-match "/" m)
(setf m (replace-match "::" nil nil m)))
m))
(t file))))
:main-file "Makefile.PL")
(defun cperl-mxdeclare-project-p ()
"Determine if this project should use MooseX::Declare class definitions."
(ignore-errors
(eproject-attribute :is-mxdeclare-project)))
This does a bunch of stuff.
The :relevant-files
are regexps matching extensions of files I want to easily navigate among via eproject-find-file. The
:irrelevant-files
are files that match the :relevant-files
regexps, but are actually not relevant. The :file-name-map
is a mapping between filename and a pretty string for eproject-find-file. This lets me navigate to .pm files by its module name (Foo::Bar) instead of its filename (lib/Foo/Bar.pm). It’s just a little bit of sugar that I find nice.
I use the cperl-mxdelcare-project-p
predicate in my auto-inserts to automatically generate the right code. (“package Foo; use Moose” if it’s not MX::Declare, “class Foo” if it is.) Before eproject, I manually searched for the project root and the .mxdeclare_project file; now this is all handled for me. I could also write :is-mxdeclare-project t
in a .eproject@ file, which is what I do for new projects.
Someone mentioned that all those lambdas can be kind of confusing.
In the case of a single lambda, like :mxdeclare-project-p
; this lets eproject compute and remember a per-project value for that attribute when the first project file is opened. If you want it to update after you add or delete the mxdeclare_project file, go to a project buffer and say M-x eproject-reinitialize-project
.
The lambda around :file-name-map
is just a workaround to return a constant function.