diff options
Diffstat (limited to 'emacs.d/lisp/multi-mode/html-php.el')
-rw-r--r-- | emacs.d/lisp/multi-mode/html-php.el | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/emacs.d/lisp/multi-mode/html-php.el b/emacs.d/lisp/multi-mode/html-php.el new file mode 100644 index 0000000..22cc210 --- /dev/null +++ b/emacs.d/lisp/multi-mode/html-php.el @@ -0,0 +1,91 @@ +;;; html-php.el --- multi-mode PHP embedded in HTML + +;; Copyright (C) 2008 Dave Love + +;; Author: Dave Love <fx@gnu.org> +;; Keywords: languages +;; $Revision: 2$ +;; URL: http://www.loveshack.ukfsn.org/emacs + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Multiple-mode editing of PHP embedded in HTML. Subject to the +;; limitations of multi-mode.el. Note that there's no attempt to deal +;; with commented processing instructions markup. Note also that this +;; only works properly with the basic HTML mode -- not PSGML or NXML. +;; Tested with the PHP mode from the hacked CC mode at the above URL. + +;;; Code: + +(require 'multi-mode) + +(defun html-php-mode () + "Mode for editing PHP embedded in HTML, using multi-mode." + (interactive) + (set (make-local-variable 'multi-alist) + '((html-mode) + (php-mode . html-php-chunk-region))) + (multi-mode-install-modes)) + +(defun html-php-chunk-region (pos) + "Mode-selecting function for PHP embedded in HTML. +See `multi-alist'." + (let ((case-fold-search t) + pi-start pi-end next-pi) + (save-excursion + (save-restriction + (widen) + (goto-char pos) + (save-excursion + (let* ((p1 (save-excursion + ;; Check whether we're on the processing + ;; instruction start. Skip definitely clear of + ;; it and then search backwards. + (goto-char (min (point-max) (+ (point) 5))) + (search-backward "<?php" (- (point) 9) t))) + (match-end (if p1 (match-end 0))) + ;; Otherwise search backwards simply. + (p2 (unless p1 (search-backward "<?php" nil t)))) + (if p2 (setq match-end (match-end 0))) + (setq pi-start (or p1 p2)) + ;; Ready to search for matching terminator or next + ;; processing instruction. + (goto-char (or match-end pos))) + (if pi-start + ;; Look forward for the PI terminator. + (let* ((p1 (save-excursion + ;; Check whether we're on the terminator. + (backward-char 1) + (search-backward "?>" (- (point) 2) t))) + (p2 (unless p1 (search-forward "?>" nil t)))) + (setq pi-end (or p1 p2 (point-max)))) + (goto-char pos)) + (if (and pi-start pi-end (< pos pi-end)) + ;; We were between PI start and terminator. + (list 'php-mode pi-start pi-end) + ;; Otherwise, look forward for a PI to delimit the HTML + ;; region. + (setq next-pi (if (search-forward "<?php" nil t) + (match-beginning 0) + (point-max))) + (if pi-start + (list 'html-mode (or pi-end (point-min)) next-pi) + (list 'html-mode (point-min) next-pi)))))))) + +(provide 'html-php) +;;; html-php.el ends here |