;;; php-mode.el --- major mode for editing PHP3 code ;; Copyright (C) 1999, 2000 Turadg Aleahmad ;; Maintainer: Turadg Aleahmad ;; Keywords: php languages oop ;; Created: 1999-05-17 ;; Modified: 2001-01-08 ;; X-URL: http://aleahmad.net/turadg/software/ (defconst php-version "0.9.4" "PHP Mode version number.") ;; This program 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 ;; of the License, or (at your option) any later version. ;; This program 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 this program; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;;; Usage ;; Place this file in your Emacs lisp path (eg. site-lisp) ;; and add to your .emacs file: ;; (require 'php-mode) ;; Many options available under Help:Customize ;; Options specific to php-mode are in ;; Programming/Languages/Php ;; Since it inherits much functionality from c-mode, look there too ;; Programming/Languages/C ;;; Commentary: ;; PHP mode is a major mode for editing PHP3 source code. It inherits ;; the functionality of C mode. The key difference is that it will ;; font-lock according to the PHP3 grammar. ;;; Known problems ;; Difficulties with XEmacs ;; There has been a `font-lock-pre-idle-hook' error in XEmacs. I think ;; this is fixed. Please let me know. ;; Commenting ;; #-marked comments are not parsed as comments at all. I've tried ;; everything I can think of and several submissions. Please e-mail ;; me if you have a solution. ;;; Changelog: ;; 0.9.4 2001-01-08 ;; Search documentation command ;; Browse manual function ;; Simplified file patterns for which to load php-mode ;; PHP awareness in Speedbar ;; Customization options for all of the above ;; 0.9.3 2000-11-12 ;; imenu support for classes and functions (Rex McMaster) ;; Dramatically improved regexps (Kevin Blake) ;; Fix for XEmacs font-lock-pre-idle-hook problem? (Doug Marcey) ;; Progress on PHP3 menu functions (Sean Champ) ;; Added "foreach" to list of keywords (Sean Champ) ;; More file suffixes observed (Vinai Kopp) ;; 0.9.2 2000-03-08 ;; Fixed bug with 1-character identifiers ;; Fixed bug with class declaration coloring ;; Added coloring for true, false, null ;; Officially not supporting XEmacs ;; 0.9.1 2000-02-21 ;; Disabled keywords in XEmacs for compatibility ;; Added usage info to comments ;; 0.9 2000-01-09 ;; Clarified bug with XEmacs (Juanjo) ;; Fixed minor bug with comment highlighting (Juanjo) ;; Syntax parsing from PHP3 lexical scanner (Torsten Martinsen) ;; Highlights function and method names now ;; Highlights "this" as keyword when used as an object in variable names ;; 0.8 1999-05-17 ;; Initial release. ;;; Code: (require 'font-lock) (require 'regexp-opt) (require 'cc-mode) (require 'custom) ;; Local variables (defgroup php nil "Major mode for editing PHP3 code." :prefix "php-" :group 'languages) (defcustom php-speedbar-config nil "*When set to true automatically configures Speedbar to observe PHP files. (Ignores php-file patterns option; fixed to expression \"\\.php?)" :type 'boolean :group 'php) (defcustom php-manual-url "http://php.net/manual/" "*URL at which to find PHP manual." :type 'string :group 'php) (defcustom php-search-url "http://php.net/search?" "*URL at which to search for a word using GET." :type 'string :group 'php) (defcustom php-file-patterns (list "\\.php?\\'" "\\.phtml\\'") "*List of file patterns for which to automatically invoke php-mode." :type '(repeat (regexp :tag "Pattern")) :group 'php) (defconst php-comment-start-regexp "#\|\(/[/*]\)") ;;;###autoload (define-derived-mode php-mode c-mode "PHP" "Major mode for editing PHP3 code.\n\n{php-mode-map}" (turn-on-font-lock) (setq font-lock-maximum-decoration t case-fold-search t ; PHP vars are case-sensitive imenu-generic-expression cc-imenu-php-generic-expression c-comment-start-regexp php-comment-start-regexp )) ;; Make php-mode the default mode for PHP source code buffers. ;;;###autoload (let ((php-file-patterns-temp php-file-patterns)) (while php-file-patterns-temp (setq auto-mode-alist (cons (cons (car php-file-patterns-temp) 'php-mode) auto-mode-alist) ) (setq php-file-patterns-temp (cdr php-file-patterns-temp)))) ;; Load Speedbar (if (and php-speedbar-config (symbolp 'speedbar)) (progn (speedbar -1) (speedbar-add-supported-extension ".php?") )) ;; Make a menu keymap (with a prompt string) ;; and make it the menu bar item's definition. (define-key php-mode-map [menu-bar] (make-sparse-keymap)) (define-key php-mode-map [menu-bar php] (cons "PHP3" (make-sparse-keymap "PHP3"))) ;; Define specific subcommands in this menu. (define-key php-mode-map [menu-bar php complete-function] '("Complete function name" . php-complete-function)) (define-key php-mode-map [menu-bar php search-documentation] '("View function documentation" . php-search-documentation)) (define-key php-mode-map [menu-bar php browse-manual] '("Browse manual" . php-browse-manual)) ;; Define function name completion function (defun php-complete-function () "Complete the function name at the point from known PHP3 functions." (interactive) (message "php-complete-function not implemented yet") ;; how to read the list of functions from a separate file? ) ;; Define function documentation function (defun php-search-documentation () "Search PHP documentation for the word at the point." (interactive) (message (concat php-search-url (current-word t))) ) ;; Define function for browsing manual (defun php-browse-manual () "Bring up manual for PHP3." (interactive) (browse-url php-manual-url) ) ;; Define abbreviations and their expansions (define-abbrev php-mode-abbrev-table "ex" "extends") (define-abbrev php-mode-abbrev-table "fu" "function") (define-abbrev php-mode-abbrev-table "GL" "GLOBAL") (define-abbrev php-mode-abbrev-table "req" "require(") (define-abbrev php-mode-abbrev-table "ret" "return") ;; Set up font locking (defconst php-font-lock-keywords-1 nil "Subdued level highlighting for PHP mode.") (defconst php-font-lock-keywords-2 nil "Medium level highlighting for PHP mode.") (defconst php-font-lock-keywords-3 nil "Gauchy level highlighting for PHP mode.") (defconst php-keywords (eval-when-compile (regexp-opt '("break" "continue" "do" "else" "for" "foreach" "if" "return" "switch" "while" "super" "new" "extends" "php" ) t)) "PHP keywords.") (defconst php-types (eval-when-compile (regexp-opt '("static" "const" "int" "integer" "real" "double" "float" "string" "array" "object" "var" "GLOBAL" "function") t)) "PHP types.") (defconst php-builtins (eval-when-compile (regexp-opt '("echo" "print" "require" "include") t)) "PHP builtins.") (defconst php-identifier "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" "Characters in a PHP identifier.") (setq php-font-lock-keywords-1 (list ;; Fontify type specifiers. (cons (concat "\\<" php-types "\\>") 'font-lock-type-face) (list (concat "\\<" php-builtins "\\>") '(1 font-lock-builtin-face t t)) )) (setq php-font-lock-keywords-2 (append php-font-lock-keywords-1 (list ;; Fontify keywords (except case, default and goto; see below). (list (concat "\\<" php-keywords "\\>") '(1 font-lock-keyword-face nil t)) ;; Fontify case/goto keywords and targets, and case default/goto tags. (list "\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?" '(1 font-lock-keyword-face nil t) '(2 font-lock-constant-face nil t)) ;; Fontify all constants. (list "\\<\\(false\\|null\\|true\\)\\>" '(1 font-lock-constant-face nil t)) ;; Fontify function declarations (list "\\<\\(function\\)\\s-+\\(\\sw+\\)\\s-*(" '(1 font-lock-keyword-face nil t) '(2 font-lock-function-name-face nil t)) ))) (setq php-font-lock-keywords-3 (append php-font-lock-keywords-2 (list ;; Fontify function and method names (list (concat "\\<\\(\\$\\(" php-identifier "\\)->\\)?" "\\(" php-identifier "\\)\\s-*(") '(2 font-lock-variable-name-face t t) '(3 font-lock-function-name-face nil t)) ;; Fontify variable name references. (list (concat "\\(\\$\\(" php-identifier "->\\)?" "\\(" php-identifier "\\)\\)") '(1 font-lock-variable-name-face t t) '(2 font-lock-variable-name-face t t)) (list "\\<\\$\\(this\\)->" '(1 font-lock-keyword-face t t)) ;; "this" as keyword ;; Fontify class names (list (concat "\\<\\(class\\)\\s-+\\(" php-identifier "\\)" "\\(\\(\\s-+extends\\s-+\\)\\(" php-identifier "\\)\\)?\\s-*{") '(1 font-lock-keyword-face t t) ;; class keyword '(2 font-lock-type-face t t) ;; class name '(4 font-lock-keyword-face t t) ;; extend keyword '(5 font-lock-type-face t t)) ;; super class name ))) (defvar php-font-lock-keywords nil "Default expressions to highlight in PHP mode.") (setq php-font-lock-keywords php-font-lock-keywords-3) ;; Handle GNU Emacs and XEmacs differences (if (not (string-match "GNU.*" (emacs-version))) (progn (make-face 'font-lock-constant-face) (set-face-foreground 'font-lock-constant-face "Deeppink") ; optional ) (font-lock-add-keywords 'php-mode php-font-lock-keywords) ) ;; imenu- from c-mode (defvar cc-imenu-php-generic-expression (` (("class" (, (concat "^" ; beginning of line is required "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>" "class[ \t]+" "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get "\\([ \t]+extends[ \t]+[a-zA-Z0-9_]+\\)?" ; may be inherited "[ \t\n]*[:{]" )) 2) ("function" (, (concat "^" ; beginning of line is required "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>" "[ \t]*function[ \t\n]+" "\\([a-zA-Z0-9_]+\\)[ \t\n]*(.*)" ; this is the string we want to get "[ \t\n]*[:{]" )) 2) )) ) (provide 'php-mode) ;;; php-mode.el ends here