Skip to content
mowen edited this page Aug 14, 2011 · 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