using Geany as an editor for Drupal development

Drupal API function argument list
Drupal API function name auto-completion

In general I'm a happy vim user, but now and again I am asked why I'm using such an antiquated environment. Editor preference is of course a topic over which many long and pointless arguments have been waged - often from intractable dug-in positions of dogma. I think it's good to poke your head above the trench occasionally and see what else is available.

I suppose the other end of the spectrum to something as lightweight (albeit extensible) as vim is a full IDE such as Eclipse. There are undoubtedly many great things about the Eclipse environment, but I just can't get over the annoyance of my rhythm being interrupted as I type; it feels like it's just trying to do too much for me.

It was in this spirit that I recently gave Geany a try. It's a lightweight cross-platform editor based on GTK, with some basic IDE features.

As a Drupal developer one of the first pleasant surprises was that I didn't need to tell it to treat .module and .install files as PHP scripts - it's smart enough to see the opening <?php tag and give me syntax highlighting etc... straight away.

It does a few simple things which make life easier - code folding if you want, a list of functions in the current file, and the facility to jump to the definition of a given function or constant, or search for the usage of whatever your cursor is over within the current document, or all open documents. It also does simple code completion, auto indentation, and has a tag library of PHP's built in functions. For PHP files, the compile button checks the syntax of the current file using php -l which is particularly useful when working on install or update hooks in Drupal.

Working with Drupal we're often not using built-in PHP functions, but rather those from the Drupal API. It's possible to get some help from Geany here too. Whilst I've seen this done with Eclipse and other IDEs before, this is one of the areas where they can become very cumbersome - for example as they try to re-index a few mb of source files for the project in the background while you're typing. The approach I'm trying out with Geany is more along the lines of using ctags with vim (or emacs).

The idea is to scan through the source code of the project (Drupal core in this case) just once, and make a list of all the function names (and constants if you like) with a few helpful details such as the argument lists. Rather annoyingly Geany uses the slightly obscure tagmanager format for its tags. The docs suggest that you can use Geany itself to generate your list of tags:

So, inside a freshly drushed copy of Drupal6 core, I tried

geany -g /tmp/drupal6.php.tags $(find . -type f -name '*.php' -o -name '*.module' -o -name '*.inc' -o -name '*.install' -o -name '*.engine')

...(using the unix find command to provide geany with a list of all the files with the common file extensions Drupal uses for PHP files).

This produced a file in tagmanager format, which geany was happy to use. This gave me auto-completion for Drupal function names, but it was missing a very useful feature - the argument list (which are provided for PHP's built-in functions).

Luckily Geany supports an alternative tag format - pipe-delimited - which is easier to manipulate than the tagmanager format. There is a contributed tags file available for Drupal which includes basic argument lists, but from the timestamp on the file I think this is probably for Drupal 5.

So how about rolling our own? Looking at the tags file which exuberent ctags produces for Drupal core, and at what we need to provide in the basic pipe-delimited tags file, ctags does most of the work for us.

ctags output

drupal_set_message  includes/  /^function drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE) {$/
drupal_set_title  includes/ /^function drupal_set_title($title = NULL) {$/

geany pipe-delimited format

function_name|return_type|argument, list|

I'm sure someone could come up with an awk one-liner to do this, but I resorted to a quick php cli script.

$lines = file('tags');
foreach ($lines as $line) {
  if (preg_match_all('[function (.*)\((.*)\) ]U', $line, $matches)) {
    print $matches[1][0] . '||' . $matches[2][0] . "|\n";

Unfortunately ctags is not clever enough to give us the return type, which might be there in doxygen-style comments (as will better info about the arguments), but this gives us:

drupal_set_message||$message = NULL, $type = 'status', $repeat = TRUE|
drupal_set_title||$title = NULL|

...which is pretty useful as a quick reminder.

With the addition of the Drupal tags file, I'm finding Geany a really good compromise between the light-weight speed of something like vim whilst offering some really useful IDE-type features for Drupal development. Why not help yourself to the tags file and give it a go.

added after some comments and feedback on IRC:
You can enable the tag files (it only really makes sense to use one of them at a time) by placing them in:

~/.config/geany/tags will also have to rename the files to remove the underscore, as otherwise geany will refuse to use them.

If you have any problems, try launching geany from the commandline with the -v ( --verbose) option.

drupal6.php_.tags75.68 KB
drupal7.php_.tags185.38 KB