Last updated June 3, 2011. Created by eddie@oho.com on April 22, 2006.
Edited by semperos, a.ross, anarcat, Scott Reynolds. Log in to edit this page.
To enable syntax highlighting for PHP code, install PHP mode for Emacs. On Debian-based systems, try the following command:sudo apt-get install php-elisp
Alternatively, you can save the php-mode.el file from here, save it under your ~/.emacs.d folder (or some sub-folder of that, if you prefer), then add the following to your ~/.emacs file:
; make sure the target directory is on your load-path
(add-to-list 'load-path "~/.emacs.d")
(require 'php-mode)[UPDATED METHOD: The following major-mode for Drupal is a more robust solution than the original snippet. If you want to see the original code from this post, scroll further down.]
Then save the following code to a file called drupal-mode.el, put it in the same folder, and add (require 'drupal-mode) after the require statement for php-mode demonstrated above.
(Taken from Xen's comment below)
;;; drupal-mode.el --- major mode for Drupal coding
;;;###autoload
(define-derived-mode drupal-mode php-mode "Drupal"
"Major mode for Drupal coding.\n\n\\{drupal-mode-map}"
(setq c-basic-offset 2)
(setq indent-tabs-mode nil)
(setq fill-column 78)
(setq show-trailing-whitespace t)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(c-set-offset 'case-label '+)
(c-set-offset 'arglist-close 0)
(c-set-offset 'arglist-intro '+) ; for FAPI arrays and DBTNG
(c-set-offset 'arglist-cont-nonempty 'c-lineup-math) ; for DBTNG fields and values
(run-mode-hooks 'drupal-mode-hook)
)
(provide 'drupal-mode)You can then setup file associations in your ~/.emacs file. Here's an example that opens Drupal-specific file extensions with drupal-mode by default, but leaves *.php and *.inc files as php-mode by default. You can always explicitly switch major modes with M-x <name of mode>
(add-to-list 'auto-mode-alist '("\\.\\(module\\|test\\|install\\|theme\\)$" . drupal-mode))
(add-to-list 'auto-mode-alist '("\\.\\(php\\|inc\\)$" . php-mode))
(add-to-list 'auto-mode-alist '("\\.info" . conf-windows-mode))[ORIGINAL POST FOLLOWS]
This short snippet will extend the php-mode in Emacs to follow Drupal coding style. Add this to your $HOME/.emacs:
(defun drupal-mode ()
"Drupal php-mode."
(interactive)
(php-mode)
(message "Drupal mode activated.")
(set 'tab-width 2)
(set 'c-basic-offset 2)
(set 'indent-tabs-mode nil)
(c-set-offset 'case-label '+)
(c-set-offset 'arglist-intro '+) ; for FAPI arrays and DBTNG
(c-set-offset 'arglist-cont-nonempty 'c-lineup-math) ; for DBTNG fields and values
; More Drupal-specific customizations here
)
(defun setup-php-drupal ()
; Drupal
(add-to-list 'auto-mode-alist '("\\.\\(module\\|test\\|install\\|theme\\)$" . drupal-mode))
(add-to-list 'auto-mode-alist '("/drupal.*\\.\\(php\\|inc\\)$" . drupal-mode))
(add-to-list 'auto-mode-alist '("\\.info" . conf-windows-mode))
)
(setup-php-drupal)This was just for simplicity, in my system however, I replace the last line: ((setup-php)) with:
(provide 'setup-php-drupal)
(provide 'drupal-mode)And instead of putting that in my ~/.emacs directly I put in a separate file e.g. ~/.emacs.d/drupal-mode.el. Then in my .emacs I have:
(add-to-list 'load-path "~/.emacs.d")
; My PHP setup
(require 'setup-php-drupal)
(setup-php-drupal)This will automatically set you in drupal-mode if you load a .php, .module or .inc file from beneath a drupal* directory. You may also manually select drupal mode by hitting M-x drupal-mode.
Comments
array indentation
Thanks for posting this!
AFAIK the correct Drupal indentation for arrays looks like this:
<?php$a = array(
'foo' => 'bar',
'gaz' => 'gazonk',
) ;
?>
but for me, this mode results in
<?php$a = array(
'foo' => 'bar',
'gaz' => 'gazonk',
) ;
?>
Any tips for resolving this?
If my comments have helped you, please pay it forward!
Use issue queues to discuss module issues - this will help your questions assist others (including yourself!) in future.
http://twitter.com/grobot ● www.giantrobot.co.nz
Here is what works for me
I didn't want to edit the page unless someone confirms the following works for them too.
In your .emacs:
(defun drupal-mode ()
"Drupal php-mode."
(interactive)
(php-mode)
(message "Drupal mode activated.")
(set 'tab-width 2)
(set 'c-basic-offset 2)
(set 'indent-tabs-mode nil)
(c-set-offset 'case-label '+)
(c-set-offset 'arglist-intro '+) ; for FAPI arrays and DBTNG
(c-set-offset 'arglist-cont-nonempty 'c-lineup-math) ; for DBTNG fields and values
; More Drupal-specific customizations here
)
(defconst my-php-style
'((c-offsets-alist . (
(arglist-close . c-lineup-close-paren) ; correct arglist closing parenthesis
)))
"My PHP Programming style"
)
(c-add-style "my-php-style" my-php-style)
(defun my-php-mode ()
"My personal php-mode customizations."
(c-set-style "my-php-style")
; More generic PHP customizations here
)
(defun setup-php ()
; PHP
(add-hook 'php-mode-hook 'my-php-mode)
; Drupal
(add-to-list 'auto-mode-alist '("\\.\\(module\\|test\\|install\\|theme\\)$" . drupal-mode))
(add-to-list 'auto-mode-alist '("/drupal.*\\.\\(php\\|inc\\)$" . drupal-mode))
(add-to-list 'auto-mode-alist '("\\.info" . conf-windows-mode))
; More startup-setup for PHP customizations to work here
)
(setup-php)
This was just for simplicity, in my system however, I replace the last line: (
(setup-php)) with:(provide 'setup-php)(provide 'my-php-mode)
And instead of putting that in my
~/.emacsdirectly I put in a separate file e.g.~/.emacs.d/setup-php.el. Then in my.emacsI have:(add-to-list 'load-path "~/.emacs.d")
; My PHP setup
(require 'setup-php)
(setup-php)
--
Amr Mostafa (aka “alienbrain”)
array indentation issue seems fixed with this - thanks
Cheers AMR, that seems to have cleared up the array indentation issue nicely for me. Haven't given it extensive testing yet but will do so today :)
Thanks again!
If my comments have helped you, please pay it forward!
Use issue queues to discuss module issues - this will help your questions assist others (including yourself!) in future.
http://twitter.com/grobot ● www.giantrobot.co.nz
This fixes the major
This fixes the major indentation issues with arrays, except it also seems to reset the indentation width from 2 back to 4 (at least for me.)
I had the same issue using this snippet
My array formatting is fixed (after years of formatting arrays manually!), but my indentation is all 4 spaces, even though I've explicitly set it to 2 spaces.
Edit: I resolved this by commenting the following line:
; (set 'tab-width 2)It seems that specifying both tab-width and c-basic-offset as 2 makes it 4?
I've turned this into a
I've turned this into a proper major mode that extends php-mode, with all the advantages that gives:
;;; drupal-mode.el --- major mode for Drupal coding
;;;###autoload
(define-derived-mode drupal-mode php-mode "Drupal"
"Major mode for Drupal coding.\n\n\\{drupal-mode-map}"
(setq c-basic-offset 2)
(setq indent-tabs-mode nil)
(setq fill-column 78)
(setq show-trailing-whitespace t)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(c-set-offset 'case-label '+)
(c-set-offset 'arglist-close 0)
(c-set-offset 'arglist-intro '+) ; for FAPI arrays and DBTNG
(c-set-offset 'arglist-cont-nonempty 'c-lineup-math) ; for DBTNG fields and values
(run-hooks 'drupal-mode-hook)
)
(provide 'drupal-mode)
This can be put into a file and loaded with (load [filename]).
Then you can modify the keyboard binding with:
(define-key drupal-mode-map (kbd "C-c d h") 'drupal-hook-insert)(define-key drupal-mode-map (kbd "C-c d f") 'drupal-form-insert)
without mucking with the php-mode or global bindings. One should also be able to add more customizations to the drupal-mode-hook, but I haven't tested if that works.
forms break out of comment mode
In Emacs PHP-mode, the following code evaluates so that Emacs thinks the comment has closed at the end of first array entry:
<?php
/*
$form['back'] = array(
'#type' => 'submit',
'#value' => 'Cancel',
'#id' => 'new-contact-cancel'
) ;
*/
?>
This is because Emacs detects the '#' in the second line as another comment opening, and believes that this has an implicit closing comment at the end of the line. From the line starting '#value', the code is treated as though it's outside the comment.
Do others see the same issue with Emacs and PHP-mode?
This isn't specifically related to the config posted above, rather it is an issue with Emacs PHP mode which shows up with commented forms code using multi-line comments.
One workaround is to comment out code blocks using M-x comment-region (and M-x uncomment-region) rather than multi-line comment blocks, but it would be cool to figure a fix for PHP mode's comment detection regex.
If my comments have helped you, please pay it forward!
Use issue queues to discuss module issues - this will help your questions assist others (including yourself!) in future.
http://twitter.com/grobot ● www.giantrobot.co.nz
Indeed
I've had the same issue as well. I found this to be fixed in the latest version of php-mode though!
Now for the seasoned emacs-er this should have been enough instructions, for beginners like myself:
~/.emacs.ddirectory or wherever you stash your elisp ;)(add-to-list 'load-path "~/.emacs.d")at the top of your~/.emacsfile.Now that should do it! But If you want to make sure it was loaded and you are indeed running the latest and greatest:
M-:(that'sAlt-Shift-;) and evaluate the following lisp which will confirm which version of php-mode we are running:(condition-case nil php-mode-version-number ((error nil) php-version)). If you see 1.5.0 (which is the latest as of 4th of April, 2009) then you are all set! Anything lower means you are still running some old version. Perhaps the right thing to do in this case is to find the otherphp-mode.el, wherever it is, and replace it with the new one.Enjoy!
--
Amr Mostafa (aka “alienbrain”)
Window version help?...
Need help setting this up on a Windows Vista. I just download emacs-23.1, but don't have a clue how to set this config up. Can anyone help me out in what I need to do?
_____________________________________________
Coding is like a box of chocolates!...
Ubuntu 10.04 LTS
NVIDIA GeForce 9500 GT
Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
Cancel That! I found an
Cancel That! I found an excellent IDE in Netbeans. My style of an environment...
_____________________________________________
Coding is like a box of chocolates!...
Ubuntu 10.04 LTS
NVIDIA GeForce 9500 GT
Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
Cancel That! I found an
Cancel That! I found an excellent IDE in Netbeans. My style of an environment...
_____________________________________________
Coding is like a box of chocolates!...
Ubuntu 10.04 LTS
NVIDIA GeForce 9500 GT
Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
Additional Useful Functions
I use these for quickly generating some commonly-used snippets:
(defun drupal-module-name ()
"Return name of module"
(car (split-string (buffer-name) "\\.")))
(defun drupal-hook-insert (name)
"Insert template for a drupal hook"
(interactive "MEnter hook name:")
(insert (concat "/**\n* Implementation of hook_" name "().\n*/\nfunction " (drupal-module-name) "_" name "() {\n\n}\n")))
(defun drupal-form-insert (name)
"Insert templat for a drupal form"
(interactive "MEnter form name:")
(insert (concat "/**\n * Form builder for .\n */\nfunction " (drupal-module-name) "_" name "($form_state) {\n\n}\n"))
(insert (concat "\n\n/**\n * Form validation handler for " (drupal-module-name) "_" name "().\n */\nfunction " (drupal-module-name) "_" name "_validate($form, &$form_state) {\n\n}"))
(insert (concat "\n\n/**\n * Form submission handler for " (drupal-module-name) "_" name "().\n */\nfunction " (drupal-module-name) "_" name "_submit($form, &$form_state) {\n\n}")))
(global-set-key (kbd "C-c d h") 'drupal-hook-insert)
(global-set-key (kbd "C-c d f") 'drupal-form-insert)
Nothing really complicated here, just some basic filler, but it works and saves time!
Getting fill-paragraph to work in comment blocks.
Add to function body of drupal-mode to get fill-paragraph to work correctly in a doxygen comment block with lists of parameters.
(setq paragraph-start (concat paragraph-start "\\| \\* @[a-z]+")paragraph-separate "$")
.dir-settings.el - .dir-locals.el
Does no one here know about .dir-settings.el (Emacs <= 23) and .dir-locals.el (Emacs 24) ???
This is the example from the Emacs Wiki:
((nil . ((indent-tabs-mode . t)
(tab-width . 4)
(fill-column . 80)))
(c-mode . ((c-file-style . "BSD")))
(java-mode . ((c-file-style . "BSD")))
("src/imported"
. ((nil . ((change-log-default-name . "ChangeLog.local"))))))
I love these. They go, once you delete the projects folder. They are not loaded, unless you open a file in the same folder or below.
Make love not war! Pobbe net klobbe!
yasnippet hook for drupal
The story:
http://www.cestfait.ch/content/yasnippet-drupal
If you have yasnippet installed, juste add this mode for php:
http://www.cestfait.ch/sites/default/files/php-mode.zip
And if you don't have yasnippet :
http://code.google.com/p/yasnippet/
etags
etags supports PHP, but doesn't know about Drupal's extensions.
Run
etags -R --langmap=php:+.module.install.incin your Drupal root directory to generate a TAGS file which includes all .module, .install, and .inc files.Then use
M-x find-tag(normally bound toM-.) to use it.Use a prefix arg to find the next match, if there is more than one (
C-u M-., or something slightly easier to type, such asM-1 M-.).Old versions of etags may not accept those arguments, but you can achieve the same results with something like:
find . -type f | etags -find . -type f \( -name "*.module" -o -name "*.install" -o -name "*.inc" \) | etags -a --language=php -There's also a recent Stack Overflow question asking how to improve tagging for PHP, but no answers as yet:
http://stackoverflow.com/questions/2916423/is-there-an-intelligent-php-e...
Here's something kind of fun,
Here's something kind of fun, based on http://www.emacswiki.org/emacs/PhpMode#toc13
Press f1 to lookup a php function, M-f1 to open browser to php.net.
I've added some code to make M-f2 bring up api.drupal.org. I'd like to define my-drupal-function-lookup similar to my-php-function-lookup, but that's way beyond my elisp chops.
;; http://www.emacswiki.org/emacs/PhpMode#toc13
(add-hook 'php-mode-hook 'my-php-mode-stuff)
(defun my-php-mode-stuff ()
(local-set-key (kbd "<f1>") 'my-php-function-lookup)
(local-set-key (kbd "M-<f1>") 'my-php-symbol-lookup)
(local-set-key (kbd "<f2>") 'my-drupal-symbol-lookup)
(local-set-key (kbd "M-<f2>") 'my-drupal-symbol-lookup)
)
(defun my-php-symbol-lookup ()
(interactive)
(let ((symbol (symbol-at-point)))
(if (not symbol)
(message "No symbol at point.")
(browse-url (concat "http://php.net/manual-lookup.php?pattern="
(symbol-name symbol))))))
(defun my-drupal-symbol-lookup ()
(interactive)
(let ((symbol (symbol-at-point)))
(if (not symbol)
(message "No symbol at point.")
(browse-url (concat "http://api.drupal.org/api/function/"
(symbol-name symbol)
"/6")))))
(defun my-php-function-lookup ()
(interactive)
(let* ((function (symbol-name (or (symbol-at-point)
(error "No function at point."))))
(buf (url-retrieve-synchronously (concat "http://php.net/manual-lookup.php?pattern=" function))))
(with-current-buffer buf
(goto-char (point-min))
(let (desc)
(when (re-search-forward "<div class=\"methodsynopsis dc-description\">\\(\\(.\\|\n\\)*?\\)</div>" nil t)
(setq desc
(replace-regexp-in-string
" +" " "
(replace-regexp-in-string
"\n" ""
(replace-regexp-in-string "<.*?>" "" (match-string-no-properties 1)))))
(when (re-search-forward "<p class=\"para rdfs-comment\">\\(\\(.\\|\n\\)*?\\)</p>" nil t)
(setq desc
(concat desc "\n\n"
(replace-regexp-in-string
" +" " "
(replace-regexp-in-string
"\n" ""
(replace-regexp-in-string "<.*?>" "" (match-string-no-properties 1))))))))
(if desc
(message desc)
(message "Could not extract function info. Press M-F1 to go the description."))))
(kill-buffer buf)))
For those new to Emacs, I
For those new to Emacs, I recommend snagging your ~/.emacs.d from github. You can find a few repos that add PHP/Drupal-friendly presets (including the body of this post) and come with tons of libraries to ease the passage to Emacs. Some are:
updated php-mode
great tips all!
There are a few people who maintain an updated version of php-mode on github:
https://github.com/ejmr/php-mode
As far as I know this library plays better with current versions of PHP and contains other bug-fixes, etc.
better than geben?
Has anyone found anything better than geben for debugging Drupal in emacs?
I don't mean to dis geben, as I'm glad it exists. Still it always seems to open an unnecessary frame or steal focus. And if you leave it for a moment there's no easy way to find that buffer again.
I don't have the elisp chops to fix those things, so I'm wondering if anyone has an alternate xdebug setup via emacs.
Finding buffers
I can't help with an alternative Xdebug interface (I suppose it's feasible that emacs-eclim might work with the Xdebug plugin for Eclipse, but that sounds like quite a lot of hoops); however there's no reason that you should have difficulty finding a buffer in Emacs, so I would suggest reading this: http://stackoverflow.com/questions/3145332 (read all of the answers, not just the accepted answer; there's some really good info in there).
I also highly recommend using winner-mode, which lets you get back to any previous window configuration (buffers, window splits & sizes, etc) in a given frame in a jiffy. I'd hate to be without it.