Skip to content
jrockway edited this page Sep 13, 2010 · 19 revisions

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.

Clone this wiki locally