-
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.