Coder.module for Emacs Users
For Drupal developers who don't already know, coder.module is a useful helper. It helps ensure your code obeys Drupal standards, and in many cases catches potential errors before they happen. Anyone maintaining a project on drupal.org should be using it.
Here's a trick for the lucky few Drupal devs who are also emacs users. I recently saw an informative post about emacs' compilation mode, specifically how to use a custom compiler. Emacs users should already be fans of compile mode, but if you only ever use PHP, you may not know it. It is worth learning. If you know it you probably see where this is going - we're going to use coder.module as our custom compiler. Then we're going to quickly and easily jump to every error/warning in the source code using
- Install coder.module on your Drupal site. To make this work smoothly, go to admin/people/permissions and allow Anonymous users to "View code review". This permissive setting should be OK on a developer site. (On a live site, don't even enable coder.module.)
- wget, or a similar tool. I'm personally using wget on a linux box and don't know what to recommend for other environments.
By default emacs' compile mode won't make heads or tails out of coder.module's output. We help it understand by adding to
compilation-error-regexp-alist. To do this, add to your .emacs file:
;; coder.module compilation errors.
;; These regexps parse the HTML output that coder displays in a browser.
'("<span class="fieldset-legend">\\(.+\\)</span>.*<h2>\\(.+\\)</h2>.*coder-warning .*Line \\([0-9]+\\): \\(.+\\) <pre>" 2 3))
; Identify line, same file as previous error.
'("coder-warning .*Line \\([0-9]+\\): \\(.+\\)<pre>" nil 1))
There are two regexps to read two kinds of errors displayed by coder.module. Some have a file name and line number, others just the line number. Rather than restart emacs, place cursor after the last paren and use
M-e to evaluate the expression.
First, let's test that coder.module is working. When administering Drupal an easy way to do this is from the admin/modules/list page. On that page, find the module that you are working with and click the "Code review" link. In my example, I'm working on fb.module a.k.a. Drupal for Facebook. When I click the code review link, I'm sent to a URL something like this:
Your URL for your server and chosen module will be different. Just note (copy) the URL as you will need it shortly.
Let's assume your code is not perfect and coder.module displayed some errors or warnings. To fix those, find your module code in emacs. In my case, I open profiles/custom/modules/fb/fb.module. Run emacs' compile command:
By default emacs doesn't know how to compile PHP (.module) files. So it will prompt for a command to run. This is time for our little trick, we run wget and pass in the coder URL from above. Here's the command I tell emacs to use:
wget --no-check-certificate -qO- https://USER:PASSWORD@example.com/path/to/drupal/admin/config/development/coder/review/fb
Note I've included --no-check-certificate (needed for my https cert) and a USER:PASSWORD because my dev server has htaccess protection. You may not need those. You may just need
wget -qO- http://....
That should do it! Your *compilation* buffer will be filled with HTML originally intended for a browser. Click the familiar (it should be)
C-x ` to bring you to the first compilation error. You should see one of your emacs frames showing the exact line of the error/warning. Make changes as needed, then again press
C-x ` to see the next error/warning.
After fixing one or more errors, you can run
M-x recompile to refresh the *compilation* buffer. You don't have to re-enter the complicated wget command.
I consider this a useful trick, but by no means ideal. I'm hoping someone out there has better emacs skills than I do, and can help me address several shortcomings.
- The compilation buffer is filled with HTML markup. It's hard to read exactly what the error is, even when you're viewing the line of the error. I'm sure there's a way to strip some of the tags to make this more legible, I just haven't figured it out yet.
- We depend on wget, not necessarily available on all platforms. It would be better to use an emacs built-in (does one exist?) Or even better, is there a way to run PHP directly without going through a web server?
- We have to pass a complex URL to wget. It would be better to somehow automatically compute that URL based on the location of the file being "compiled". I'm not sure how best to do that.
- The regexps I use to parse coder output might be theme-dependent. I'm not convinced they are the best regexps. I'm stil fine-tuning this.
If you can help address any of those issues, or any I haven't thought of, please leave a comment or drop me a line. Thanks!