X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/2273c36b4ed5c18c65d7912d5b4453c33ec6b854..ba976213c358271b653ae2a8fec9d09c6692a7fd:/lisp/font-lock.el diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 43a3029625..db1db26254 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1,8 +1,9 @@ ;;; font-lock.el --- Electric font lock mode -;; Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. +;; Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999, 2000 +;; Free Software Foundation, Inc. -;; Author: jwz, then rms, then sm +;; Author: jwz, then rms, then sm ;; Maintainer: FSF ;; Keywords: languages, faces @@ -60,16 +61,40 @@ ;; properties appropriately. ;; ;; Fontification normally involves syntactic (i.e., strings and comments) and -;; regexp (i.e., keywords and everything else) passes. The syntactic pass -;; involves a syntax table and a syntax parsing function to determine the -;; context of different parts of a region of text. It is necessary because -;; generally strings and/or comments can span lines, and so the context of a -;; given region is not necessarily apparent from the content of that region. -;; Because the regexp pass only works within a given region, it is not -;; generally appropriate for syntactic fontification. The regexp pass involves -;; searching for given regexps (or calling given functions) within the given -;; region. For each match of the regexp (or non-nil value of the called -;; function), `face' text properties are added appropriately. +;; regexp (i.e., keywords and everything else) passes. There are actually +;; three passes; (a) the syntactic keyword pass, (b) the syntactic pass and (c) +;; the keyword pass. Confused? +;; +;; The syntactic keyword pass places `syntax-table' text properties in the +;; buffer according to the variable `font-lock-syntactic-keywords'. It is +;; necessary because Emacs' syntax table is not powerful enough to describe all +;; the different syntactic constructs required by the sort of people who decide +;; that a single quote can be syntactic or not depending on the time of day. +;; (What sort of person could decide to overload the meaning of a quote?) +;; Obviously the syntactic keyword pass must occur before the syntactic pass. +;; +;; The syntactic pass places `face' text properties in the buffer according to +;; syntactic context, i.e., according to the buffer's syntax table and buffer +;; text's `syntax-table' text properties. It involves using a syntax parsing +;; function to determine the context of different parts of a region of text. A +;; syntax parsing function is necessary because generally strings and/or +;; comments can span lines, and so the context of a given region is not +;; necessarily apparent from the content of that region. Because the keyword +;; pass only works within a given region, it is not generally appropriate for +;; syntactic fontification. This is the first fontification pass that makes +;; changes visible to the user; it fontifies strings and comments. +;; +;; The keyword pass places `face' text properties in the buffer according to +;; the variable `font-lock-keywords'. It involves searching for given regexps +;; (or calling given search functions) within the given region. This is the +;; second fontification pass that makes changes visible to the user; it +;; fontifies language reserved words, etc. +;; +;; Oh, and the answer is, "Yes, obviously just about everything should be done +;; in a single syntactic pass, but the only syntactic parser available +;; understands only strings and comments." Perhaps one day someone will write +;; some syntactic parsers for common languages and a son-of-font-lock.el could +;; use them rather then relying so heavily on the keyword (regexp) pass. ;;; How Font Lock mode supports modes or is supported by modes: @@ -92,10 +117,9 @@ ;; See the documentation for the variable `font-lock-keywords'. ;; -;; Nasty regexps of the form "bar\\(\\|lo\\)\\|f\\(oo\\|u\\(\\|bar\\)\\)\\|lo" -;; are made thusly: (make-regexp '("foo" "fu" "fubar" "bar" "barlo" "lo")) for -;; efficiency. See /pub/gnu/emacs/elisp-archive/functions/make-regexp.el.Z on -;; archive.cis.ohio-state.edu for this and other functions not just by sm. +;; Efficient regexps for use as MATCHERs for `font-lock-keywords' and +;; `font-lock-syntactic-keywords' can be generated via the function +;; `regexp-opt'. ;;; Adding patterns for modes that already support Font Lock: @@ -162,7 +186,7 @@ ;; doesn't work. Or maybe it allows you to think less and drift off to sleep. ;; ;; So, here are my opinions/advice/guidelines: -;; +;; ;; - Highlight conceptual objects, such as function and variable names, and ;; different objects types differently, i.e., (a) and (b) above, highlight ;; function names differently to variable names. @@ -187,6 +211,7 @@ (defgroup font-lock nil "Font Lock mode text highlighting package." :link '(custom-manual "(emacs)Font Lock") + :link '(custom-manual "(elisp)Font Lock Mode") :group 'faces) (defgroup font-lock-highlighting-faces nil @@ -198,7 +223,7 @@ "Extra mode-specific type names for highlighting declarations." :group 'font-lock) -;; Define support mode groups here for nicer `font-lock' group order. +;; Define support mode groups here to impose `font-lock' group order. (defgroup fast-lock nil "Font Lock support mode to cache fontification." :link '(custom-manual "(emacs)Support Modes") @@ -210,15 +235,36 @@ :link '(custom-manual "(emacs)Support Modes") :load 'lazy-lock :group 'font-lock) + +(defgroup jit-lock nil + "Font Lock support mode to fontify just-in-time." + :link '(custom-manual "(emacs)Support Modes") + :version "21.1" + :load 'jit-lock + :group 'font-lock) ;; User variables. -(defcustom font-lock-verbose (* 0 1024) - "*If non-nil, means show status messages for buffer fontification. -If a number, only buffers greater than this size have fontification messages." - :type '(choice (const :tag "never" nil) - (const :tag "always" t) - (integer :tag "size")) +(defcustom font-lock-maximum-size 256000 + "*Maximum size of a buffer for buffer fontification. +Only buffers less than this can be fontified when Font Lock mode is turned on. +If nil, means size is irrelevant. +If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE), +where MAJOR-MODE is a symbol or t (meaning the default). For example: + ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576)) +means that the maximum size is 250K for buffers in C or C++ modes, one megabyte +for buffers in Rmail mode, and size is irrelevant otherwise." + :type '(choice (const :tag "none" nil) + (integer :tag "size") + (repeat :menu-tag "mode specific" :tag "mode specific" + :value ((t . nil)) + (cons :tag "Instance" + (radio :tag "Mode" + (const :tag "all" t) + (symbol :tag "name")) + (radio :tag "Size" + (const :tag "none" nil) + (integer :tag "size"))))) :group 'font-lock) (defcustom font-lock-maximum-decoration t @@ -242,37 +288,63 @@ decoration for buffers in C++ mode, and level 1 decoration otherwise." (symbol :tag "name")) (radio :tag "Decoration" (const :tag "default" nil) - (const :tag "maximum" t) + (const :tag "maximum" t) (integer :tag "level" 1))))) :group 'font-lock) -(defcustom font-lock-maximum-size (* 250 1024) - "*Maximum size of a buffer for buffer fontification. -Only buffers less than this can be fontified when Font Lock mode is turned on. -If nil, means size is irrelevant. -If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE), -where MAJOR-MODE is a symbol or t (meaning the default). For example: - ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576)) -means that the maximum size is 250K for buffers in C or C++ modes, one megabyte -for buffers in Rmail mode, and size is irrelevant otherwise." - :type '(choice (const :tag "none" nil) - (integer :tag "size") - (repeat :menu-tag "mode specific" :tag "mode specific" - :value ((t . nil)) - (cons :tag "Instance" - (radio :tag "Mode" - (const :tag "all" t) - (symbol :tag "name")) - (radio :tag "Size" - (const :tag "none" nil) - (integer :tag "size"))))) +(defcustom font-lock-verbose 0 + "*If non-nil, means show status messages for buffer fontification. +If a number, only buffers greater than this size have fontification messages." + :type '(choice (const :tag "never" nil) + (other :tag "always" t) + (integer :tag "size")) :group 'font-lock) + +;; Originally these variable values were face names such as `bold' etc. +;; Now we create our own faces, but we keep these variables for compatibility +;; and they give users another mechanism for changing face appearance. +;; We now allow a FACENAME in `font-lock-keywords' to be any expression that +;; returns a face. So the easiest thing is to continue using these variables, +;; rather than sometimes evaling FACENAME and sometimes not. sm. +(defvar font-lock-comment-face 'font-lock-comment-face + "Face name to use for comments.") + +(defvar font-lock-string-face 'font-lock-string-face + "Face name to use for strings.") + +(defvar font-lock-doc-face 'font-lock-doc-face + "Face name to use for documentation.") + +(defvar font-lock-keyword-face 'font-lock-keyword-face + "Face name to use for keywords.") + +(defvar font-lock-builtin-face 'font-lock-builtin-face + "Face name to use for builtins.") + +(defvar font-lock-function-name-face 'font-lock-function-name-face + "Face name to use for function names.") + +(defvar font-lock-variable-name-face 'font-lock-variable-name-face + "Face name to use for variable names.") + +(defvar font-lock-type-face 'font-lock-type-face + "Face name to use for type and class names.") + +(defvar font-lock-constant-face 'font-lock-constant-face + "Face name to use for constant and label names.") + +(defvar font-lock-warning-face 'font-lock-warning-face + "Face name to use for things that should stand out.") + +(defvar font-lock-reference-face 'font-lock-constant-face + "This variable is obsolete. Use `font-lock-constant-face'.") + ;; Fontification variables: (defvar font-lock-keywords nil - "*A list of the keywords to highlight. -Each element should be of the form: + "A list of the keywords to highlight. +Each element should have one of these forms: MATCHER (MATCHER . MATCH) @@ -287,20 +359,23 @@ FORM is an expression, whose value should be a keyword element, evaluated when the keyword is (first) used in a buffer. This feature can be used to provide a keyword that can only be generated when Font Lock mode is actually turned on. -For highlighting single items, typically only MATCH-HIGHLIGHT is required. +For highlighting single items, for example each instance of the word \"foo\", +typically only MATCH-HIGHLIGHT is required. However, if an item or (typically) items are to be highlighted following the -instance of another item (the anchor) then MATCH-ANCHORED may be required. +instance of another item (the anchor), for example each instance of the +word \"bar\" following the word \"anchor\" then MATCH-ANCHORED may be required. MATCH-HIGHLIGHT should be of the form: (MATCH FACENAME OVERRIDE LAXMATCH) -Where MATCHER can be either the regexp to search for, or the function name to -call to make the search (called with one argument, the limit of the search). -MATCH is the subexpression of MATCHER to be highlighted. MATCH can be -calculated via the function `font-lock-keyword-depth'. FACENAME is an -expression whose value is the face name to use. FACENAME's default attributes -can be modified via \\[customize]. +where MATCHER can be either the regexp to search for, or the function name to +call to make the search (called with one argument, the limit of the search) and +return non-nil if it succeeds (and set `match-data' appropriately). +MATCHER regexps can be generated via the function `regexp-opt'. MATCH is +the subexpression of MATCHER to be highlighted. FACENAME is an expression +whose value is the face name to use. Face default attributes can be +modified via \\[customize]. OVERRIDE and LAXMATCH are flags. If OVERRIDE is t, existing fontification can be overwritten. If `keep', only parts not already fontified are highlighted. @@ -310,20 +385,25 @@ If LAXMATCH is non-nil, no error is signaled if there is no MATCH in MATCHER. For example, an element of the form highlights (if not already highlighted): - \"\\\\\\=\" Discrete occurrences of \"foo\" in the value of the + \"\\\\\\=\" discrete occurrences of \"foo\" in the value of the variable `font-lock-keyword-face'. - (\"fu\\\\(bar\\\\)\" . 1) Substring \"bar\" within all occurrences of \"fubar\" in + (\"fu\\\\(bar\\\\)\" . 1) substring \"bar\" within all occurrences of \"fubar\" in the value of `font-lock-keyword-face'. (\"fubar\" . fubar-face) Occurrences of \"fubar\" in the value of `fubar-face'. (\"foo\\\\|bar\" 0 foo-bar-face t) - Occurrences of either \"foo\" or \"bar\" in the value + occurrences of either \"foo\" or \"bar\" in the value of `foo-bar-face', even if already highlighted. + (fubar-match 1 fubar-face) + the first subexpression within all occurrences of + whatever the function `fubar-match' finds and matches + in the value of `fubar-face'. MATCH-ANCHORED should be of the form: (MATCHER PRE-MATCH-FORM POST-MATCH-FORM MATCH-HIGHLIGHT ...) -Where MATCHER is as for MATCH-HIGHLIGHT with one exception; see below. +where MATCHER is a regexp to search for or the function name to call to make +the search, as for MATCH-HIGHLIGHT above, but with one exception; see below. PRE-MATCH-FORM and POST-MATCH-FORM are evaluated before the first, and after the last, instance MATCH-ANCHORED's MATCHER is used. Therefore they can be used to initialise before, and cleanup after, MATCHER is used. Typically, @@ -335,7 +415,7 @@ For example, an element of the form highlights (if not already highlighted): (\"\\\\\\=\" (0 anchor-face) (\"\\\\\\=\" nil nil (0 item-face))) - Discrete occurrences of \"anchor\" in the value of `anchor-face', and subsequent + discrete occurrences of \"anchor\" in the value of `anchor-face', and subsequent discrete occurrences of \"item\" (on the same line) in the value of `item-face'. (Here PRE-MATCH-FORM and POST-MATCH-FORM are nil. Therefore \"item\" is initially searched for starting from the end of the match of \"anchor\", and @@ -349,12 +429,10 @@ PRE-MATCH-FORM is evaluated, that position is used as the limit of the search. It is generally a bad idea to return a position greater than the end of the line, i.e., cause the MATCHER search to span lines. -Note that the MATCH-ANCHORED feature is experimental; in the future, we may -replace it with other ways of providing this functionality. - -These regular expressions should not match text which spans lines. While -\\[font-lock-fontify-buffer] handles multi-line patterns correctly, updating -when you edit the buffer does not, since it considers text one line at a time. +These regular expressions can match text which spans lines, although +it is better to avoid it if possible since updating them while editing +text is slower, and it is not guaranteed to be always correct when using +support modes like jit-lock or lazy-lock. This variable is set by major modes via the variable `font-lock-defaults'. Be careful when composing regexps for this list; a poorly written pattern can @@ -400,10 +478,14 @@ Typical values are `mark-defun' for programming modes or `mark-paragraph' for textual modes (i.e., the mode-dependent function is known to put point and mark around a text block relevant to that mode). -Other variables include those for buffer-specialised fontification functions, +Other variables include that for syntactic keyword fontification, +`font-lock-syntactic-keywords' +and those for buffer-specialised fontification functions, `font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function', `font-lock-fontify-region-function', `font-lock-unfontify-region-function', `font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.") +;;;###autoload +(make-variable-buffer-local 'font-lock-defaults) ;; This variable is used where font-lock.el itself supplies the keywords. (defvar font-lock-defaults-alist @@ -414,80 +496,57 @@ Other variables include those for buffer-specialised fontification functions, '((c-font-lock-keywords c-font-lock-keywords-1 c-font-lock-keywords-2 c-font-lock-keywords-3) nil nil ((?_ . "w")) beginning-of-defun - ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP. - ;(font-lock-comment-start-regexp . "/[*/]") (font-lock-mark-block-function . mark-defun))) (c++-mode-defaults - '((c++-font-lock-keywords c++-font-lock-keywords-1 + '((c++-font-lock-keywords c++-font-lock-keywords-1 c++-font-lock-keywords-2 c++-font-lock-keywords-3) nil nil ((?_ . "w")) beginning-of-defun - ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP. - ;(font-lock-comment-start-regexp . "/[*/]") (font-lock-mark-block-function . mark-defun))) (objc-mode-defaults '((objc-font-lock-keywords objc-font-lock-keywords-1 objc-font-lock-keywords-2 objc-font-lock-keywords-3) nil nil ((?_ . "w") (?$ . "w")) nil - ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP. - ;(font-lock-comment-start-regexp . "/[*/]") (font-lock-mark-block-function . mark-defun))) (java-mode-defaults '((java-font-lock-keywords java-font-lock-keywords-1 java-font-lock-keywords-2 java-font-lock-keywords-3) - nil nil ((?_ . "w") (?$ . "w") (?. . "w")) nil - ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP. - ;(font-lock-comment-start-regexp . "/[*/]") + nil nil ((?_ . "w") (?$ . "w")) nil (font-lock-mark-block-function . mark-defun))) (lisp-mode-defaults '((lisp-font-lock-keywords lisp-font-lock-keywords-1 lisp-font-lock-keywords-2) nil nil (("+-*/.<>=!?$%_&~^:" . "w")) beginning-of-defun - ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP. - ;(font-lock-comment-start-regexp . ";") - (font-lock-mark-block-function . mark-defun))) - (scheme-mode-defaults - '(scheme-font-lock-keywords - nil t (("+-*/.<>=!?$%_&~^:" . "w")) beginning-of-defun - ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP. - ;(font-lock-comment-start-regexp . ";") - (font-lock-mark-block-function . mark-defun))) - ;; For TeX modes we could use `backward-paragraph' for the same reason. - ;; But we don't, because paragraph breaks are arguably likely enough to - ;; occur within a genuine syntactic block to make it too risky. - ;; However, we do specify a MARK-BLOCK function as that cannot result - ;; in a mis-fontification even if it might not fontify enough. --sm. - (tex-mode-defaults - '(tex-font-lock-keywords nil nil ((?$ . "\"")) nil - ;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP. - ;(font-lock-comment-start-regexp . "%") - (font-lock-mark-block-function . mark-paragraph))) - ) + (font-lock-mark-block-function . mark-defun)))) (list (cons 'c-mode c-mode-defaults) (cons 'c++-mode c++-mode-defaults) (cons 'objc-mode objc-mode-defaults) (cons 'java-mode java-mode-defaults) (cons 'emacs-lisp-mode lisp-mode-defaults) - (cons 'inferior-scheme-mode scheme-mode-defaults) - (cons 'latex-mode tex-mode-defaults) (cons 'lisp-mode lisp-mode-defaults) - (cons 'lisp-interaction-mode lisp-mode-defaults) - (cons 'plain-tex-mode tex-mode-defaults) - (cons 'scheme-mode scheme-mode-defaults) - (cons 'scheme-interaction-mode scheme-mode-defaults) - (cons 'slitex-mode tex-mode-defaults) - (cons 'tex-mode tex-mode-defaults))) + (cons 'lisp-interaction-mode lisp-mode-defaults))) "Alist of fall-back Font Lock defaults for major modes. + +This variable should not be used any more. +Set the buffer-local `font-lock-keywords' in the major mode instead. + Each item should be a list of the form: (MAJOR-MODE . FONT-LOCK-DEFAULTS) where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default settings. See the variable `font-lock-defaults', which takes precedence.") +(make-obsolete-variable 'font-lock-defaults-alist 'font-lock-defaults) (defvar font-lock-keywords-alist nil "*Alist of `font-lock-keywords' local to a `major-mode'. -This is normally set via `font-lock-add-keywords'.") +This is normally set via `font-lock-add-keywords' and +`font-lock-remove-keywords'.") + +(defvar font-lock-removed-keywords-alist nil + "*Alist of `font-lock-keywords' removed from `major-mode'. +This is normally set via `font-lock-add-keywords' and +`font-lock-remove-keywords'.") (defvar font-lock-keywords-only nil "*Non-nil means Font Lock should not fontify comments or strings. @@ -497,6 +556,54 @@ This is normally set via `font-lock-defaults'.") "*Non-nil means the patterns in `font-lock-keywords' are case-insensitive. This is normally set via `font-lock-defaults'.") +(defvar font-lock-syntactically-fontified 0 + "Point up to which `font-lock-syntactic-keywords' has been applied. +If nil, this is ignored, in which case the syntactic fontification may +sometimes be slightly incorrect.") +(make-variable-buffer-local 'font-lock-syntactically-fontified) + +(defvar font-lock-syntactic-face-function + (lambda (state) + (if (nth 3 state) font-lock-string-face font-lock-comment-face)) + "Function to determine which face to use when fontifying syntactically. +The function is called with a single parameter (the state as returned by +`parse-partial-sexp' at the beginning of the region to highlight) and +should return a face.") + +(defvar font-lock-syntactic-keywords nil + "A list of the syntactic keywords to highlight. +Can be the list or the name of a function or variable whose value is the list. +See `font-lock-keywords' for a description of the form of this list; +the differences are listed below. MATCH-HIGHLIGHT should be of the form: + + (MATCH SYNTAX OVERRIDE LAXMATCH) + +where SYNTAX can be a string (as taken by `modify-syntax-entry'), a syntax +table, a cons cell (as returned by `string-to-syntax') or an expression whose +value is such a form. OVERRIDE cannot be `prepend' or `append'. + +For example, an element of the form highlights syntactically: + + (\"\\\\$\\\\(#\\\\)\" 1 \".\") + + a hash character when following a dollar character, with a SYNTAX of + \".\" (meaning punctuation syntax). Assuming that the buffer syntax table does + specify hash characters to have comment start syntax, the element will only + highlight hash characters that do not follow dollar characters as comments + syntactically. + + (\"\\\\('\\\\).\\\\('\\\\)\" + (1 \"\\\"\") + (2 \"\\\"\")) + + both single quotes which surround a single character, with a SYNTAX of + \"\\\"\" (meaning string quote syntax). Assuming that the buffer syntax table + does not specify single quotes to have quote syntax, the element will only + highlight single quotes of the form 'c' as strings syntactically. + Other forms, such as foo'bar or 'fubar', will not be highlighted as strings. + +This is normally set via `font-lock-defaults'.") + (defvar font-lock-syntax-table nil "Non-nil means use this syntax table for fontifying. If this is nil, the major mode's syntax table is used. @@ -517,14 +624,6 @@ When called with no args it should leave point at the beginning of any enclosing textual block and mark at the end. This is normally set via `font-lock-defaults'.") -;; Obsoleted by Emacs 19.35 parse-partial-sexp's COMMENTSTOP. -;(defvar font-lock-comment-start-regexp nil -; "*Regexp to match the start of a comment. -;This need not discriminate between genuine comments and quoted comment -;characters or comment characters within strings. -;If nil, `comment-start-skip' is used instead; see that variable for more info. -;This is normally set via `font-lock-defaults'.") - (defvar font-lock-fontify-buffer-function 'font-lock-default-fontify-buffer "Function to use for fontifying the buffer. This is normally set via `font-lock-defaults'.") @@ -547,15 +646,17 @@ This is normally set via `font-lock-defaults'.") (defvar font-lock-inhibit-thing-lock nil "List of Font Lock mode related modes that should not be turned on. -Currently, valid mode names as `fast-lock-mode' and `lazy-lock-mode'. -This is normally set via `font-lock-defaults'.") +Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and +`lazy-lock-mode'. This is normally set via `font-lock-defaults'.") -(defvar font-lock-mode nil) ; Whether we are turned on/modeline. -(defvar font-lock-fontified nil) ; Whether we have fontified the buffer. +(defvar font-lock-multiline 'undecided + "Whether font-lock should cater to multiline keywords. +If nil, don't try to handle multiline patterns. +If t, always handle multiline patterns. +If `undecided', don't try to handle multiline patterns until you see one. +Major/minor modes can set this variable if they know which option applies.") -;;;###autoload -(defvar font-lock-mode-hook nil - "Function or functions to run on entry to Font Lock mode.") +(defvar font-lock-fontified nil) ; Whether we have fontified the buffer. ;; Font Lock mode. @@ -568,20 +669,25 @@ This is normally set via `font-lock-defaults'.") ;; We use this to preserve or protect things when modifying text properties. (defmacro save-buffer-state (varlist &rest body) "Bind variables according to VARLIST and eval BODY restoring buffer state." - (` (let* ((,@ (append varlist - '((modified (buffer-modified-p)) (buffer-undo-list t) - (inhibit-read-only t) (inhibit-point-motion-hooks t) - before-change-functions after-change-functions - deactivate-mark buffer-file-name buffer-file-truename)))) - (,@ body) - (when (and (not modified) (buffer-modified-p)) - (set-buffer-modified-p nil))))) - (put 'save-buffer-state 'lisp-indent-function 1)) + `(let* ,(append varlist + '((modified (buffer-modified-p)) (buffer-undo-list t) + (inhibit-read-only t) (inhibit-point-motion-hooks t) + before-change-functions after-change-functions + deactivate-mark buffer-file-name buffer-file-truename)) + ,@body + (when (and (not modified) (buffer-modified-p)) + (set-buffer-modified-p nil)))) + (put 'save-buffer-state 'lisp-indent-function 1) + (def-edebug-spec save-buffer-state let) + ;; + ;; Shut up the byte compiler. + (defvar font-lock-face-attributes)) ; Obsolete but respected if set. ;;;###autoload -(defun font-lock-mode (&optional arg) +(define-minor-mode font-lock-mode "Toggle Font Lock mode. With arg, turn Font Lock mode on if and only if arg is positive. +\(Font Lock is also known as \"syntax highlighting\".) When Font Lock mode is enabled, text is fontified as you type it: @@ -590,6 +696,9 @@ When Font Lock mode is enabled, text is fontified as you type it: - Certain other expressions are displayed in other faces according to the value of the variable `font-lock-keywords'. +To customize the faces (colors, fonts, etc.) used by Font Lock for +fontifying different parts of buffer text, use \\[customize-face]. + You can enable Font Lock mode in any major mode automatically by turning on in the major mode's hook. For example, put in your ~/.emacs: @@ -628,49 +737,43 @@ syntactic change on other lines, you can use \\[font-lock-fontify-block]. See the variable `font-lock-defaults-alist' for the Font Lock mode default settings. You can set your own default settings for some mode, by setting a buffer local value for `font-lock-defaults', via its mode hook." - (interactive "P") + nil nil nil ;; Don't turn on Font Lock mode if we don't have a display (we're running a ;; batch job) or if the buffer is invisible (the name starts with a space). - (let ((on-p (and (not noninteractive) - (not (eq (aref (buffer-name) 0) ?\ )) - (if arg - (> (prefix-numeric-value arg) 0) - (not font-lock-mode))))) - (set (make-local-variable 'font-lock-mode) on-p) - ;; Turn on Font Lock mode. - (when on-p - (make-local-hook 'after-change-functions) - (add-hook 'after-change-functions 'font-lock-after-change-function nil t) - (font-lock-set-defaults) - (font-lock-turn-on-thing-lock) - (run-hooks 'font-lock-mode-hook) - ;; Fontify the buffer if we have to. - (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size))) - (cond (font-lock-fontified - nil) - ((or (null max-size) (> max-size (buffer-size))) - (font-lock-fontify-buffer)) - (font-lock-verbose - (message "Fontifying %s...buffer too big" (buffer-name)))))) - ;; Turn off Font Lock mode. - (unless on-p - (remove-hook 'after-change-functions 'font-lock-after-change-function t) - (font-lock-unfontify-buffer) - (font-lock-turn-off-thing-lock) - (font-lock-unset-defaults)) - (force-mode-line-update))) + (when (or noninteractive (eq (aref (buffer-name) 0) ?\ )) + (setq font-lock-mode nil)) + + ;; Turn on Font Lock mode. + (when font-lock-mode + (add-hook 'after-change-functions 'font-lock-after-change-function nil t) + (font-lock-set-defaults) + (font-lock-turn-on-thing-lock) + ;; Fontify the buffer if we have to. + (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size))) + (cond (font-lock-fontified + nil) + ((or (null max-size) (> max-size (buffer-size))) + (font-lock-fontify-buffer)) + (font-lock-verbose + (message "Fontifying %s...buffer size greater than font-lock-maximum-size" + (buffer-name)))))) + ;; Turn off Font Lock mode. + (unless font-lock-mode + (remove-hook 'after-change-functions 'font-lock-after-change-function t) + (font-lock-unfontify-buffer) + (font-lock-turn-off-thing-lock) + (font-lock-unset-defaults))) ;;;###autoload (defun turn-on-font-lock () - "Turn on Font Lock mode conditionally. -Turn on only if the terminal can display it." - (when (and (not font-lock-mode) window-system) + "Turn on Font Lock mode (only if the terminal can display it)." + (unless font-lock-mode (font-lock-mode))) ;;;###autoload -(defun font-lock-add-keywords (major-mode keywords &optional append) - "Add highlighting KEYWORDS for MAJOR-MODE. -MAJOR-MODE should be a symbol, the major mode command name, such as `c-mode' +(defun font-lock-add-keywords (mode keywords &optional append) + "Add highlighting KEYWORDS for MODE. +MODE should be a symbol, the major mode command name, such as `c-mode' or nil. If nil, highlighting keywords are added for the current buffer. KEYWORDS should be a list; see the variable `font-lock-keywords'. By default they are added at the beginning of the current highlighting list. @@ -690,23 +793,126 @@ comments, and to fontify `and', `or' and `not' words as keywords. Note that some modes have specialised support for additional patterns, e.g., see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types', `objc-font-lock-extra-types' and `java-font-lock-extra-types'." - (cond (major-mode - ;; If MAJOR-MODE is non-nil, add the KEYWORDS and APPEND spec to + (cond (mode + ;; If MODE is non-nil, add the KEYWORDS and APPEND spec to ;; `font-lock-keywords-alist' so `font-lock-set-defaults' uses them. (let ((spec (cons keywords append)) cell) - (if (setq cell (assq major-mode font-lock-keywords-alist)) - (setcdr cell (append (cdr cell) (list spec))) - (push (list major-mode spec) font-lock-keywords-alist)))) - (font-lock-mode - ;; Otherwise if Font Lock mode is on, set or add the keywords now. - (if (eq append 'set) - (setq font-lock-keywords keywords) + (if (setq cell (assq mode font-lock-keywords-alist)) + (if (eq append 'set) + (setcdr cell (list spec)) + (setcdr cell (append (cdr cell) (list spec)))) + (push (list mode spec) font-lock-keywords-alist))) + ;; Make sure that `font-lock-removed-keywords-alist' does not + ;; contain the new keywords. + (font-lock-update-removed-keyword-alist mode keywords append)) + (t + ;; Otherwise set or add the keywords now. + (font-lock-set-defaults) + (if (eq append 'set) + (setq font-lock-keywords keywords) + (font-lock-remove-keywords nil keywords) ;to avoid duplicates (let ((old (if (eq (car-safe font-lock-keywords) t) (cdr font-lock-keywords) font-lock-keywords))) (setq font-lock-keywords (if append (append old keywords) (append keywords old)))))))) + +(defun font-lock-update-removed-keyword-alist (mode keywords append) + ;; Update `font-lock-removed-keywords-alist' when adding new + ;; KEYWORDS to MODE. + ;; + ;; When font-lock is enabled first all keywords in the list + ;; `font-lock-keywords-alist' are added, then all keywords in the + ;; list `font-lock-removed-keywords-alist' are removed. If a + ;; keyword was once added, removed, and then added again it must be + ;; removed from the removed-keywords list. Otherwise the second add + ;; will not take effect. + (let ((cell (assq mode font-lock-removed-keywords-alist))) + (if cell + (if (eq append 'set) + ;; A new set of keywords is defined. Forget all about + ;; our old keywords that should be removed. + (setq font-lock-removed-keywords-alist + (delq cell font-lock-removed-keywords-alist)) + ;; Delete all previously removed keywords. + (dolist (kword keywords) + (setcdr cell (delete kword (cdr cell)))) + ;; Delete the mode cell if empty. + (if (null (cdr cell)) + (setq font-lock-removed-keywords-alist + (delq cell font-lock-removed-keywords-alist))))))) + +;; Written by Anders Lindgren . +;; +;; Case study: +;; (I) The keywords are removed from a major mode. +;; In this case the keyword could be local (i.e. added earlier by +;; `font-lock-add-keywords'), global, or both. +;; +;; (a) In the local case we remove the keywords from the variable +;; `font-lock-keywords-alist'. +;; +;; (b) The actual global keywords are not known at this time. +;; All keywords are added to `font-lock-removed-keywords-alist', +;; when font-lock is enabled those keywords are removed. +;; +;; Note that added keywords are taken out of the list of removed +;; keywords. This ensure correct operation when the same keyword +;; is added and removed several times. +;; +;; (II) The keywords are removed from the current buffer. +;;;###autoload +(defun font-lock-remove-keywords (mode keywords) + "Remove highlighting KEYWORDS for MODE. + +MODE should be a symbol, the major mode command name, such as `c-mode' +or nil. If nil, highlighting keywords are removed for the current buffer." + (cond (mode + ;; Remove one keyword at the time. + (dolist (keyword keywords) + (let ((top-cell (assq mode font-lock-keywords-alist))) + ;; If MODE is non-nil, remove the KEYWORD from + ;; `font-lock-keywords-alist'. + (when top-cell + (dolist (keyword-list-append-pair (cdr top-cell)) + ;; `keywords-list-append-pair' is a cons with a list of + ;; keywords in the car top-cell and the original append + ;; argument in the cdr top-cell. + (setcar keyword-list-append-pair + (delete keyword (car keyword-list-append-pair)))) + ;; Remove keyword list/append pair when the keyword list + ;; is empty and append doesn't specify `set'. (If it + ;; should be deleted then previously deleted keywords + ;; would appear again.) + (let ((cell top-cell)) + (while (cdr cell) + (if (and (null (car (car (cdr cell)))) + (not (eq (cdr (car (cdr cell))) 'set))) + (setcdr cell (cdr (cdr cell))) + (setq cell (cdr cell))))) + ;; Final cleanup, remove major mode cell if last keyword + ;; was deleted. + (if (null (cdr top-cell)) + (setq font-lock-keywords-alist + (delq top-cell font-lock-keywords-alist)))) + ;; Remember the keyword in case it is not local. + (let ((cell (assq mode font-lock-removed-keywords-alist))) + (if cell + (unless (member keyword (cdr cell)) + (nconc cell (list keyword))) + (push (cons mode (list keyword)) + font-lock-removed-keywords-alist)))))) + (t + ;; Otherwise remove it immediately. + (font-lock-set-defaults) + (setq font-lock-keywords (copy-sequence font-lock-keywords)) + (dolist (keyword keywords) + (setq font-lock-keywords + (delete keyword + ;; The keywords might be compiled. + (delete (font-lock-compile-keyword keyword) + font-lock-keywords))))))) ;;; Global Font Lock mode. @@ -761,12 +967,9 @@ see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types', ;; loading a file tells you nothing about the feature or how to control it. It ;; would also be contrary to the Principle of Least Surprise. sm. -(defvar font-lock-buffers nil) ; For remembering buffers. -(defvar global-font-lock-mode nil) - (defcustom font-lock-global-modes t "*Modes for which Font Lock mode is automagically turned on. -Global Font Lock mode is controlled by the `global-font-lock-mode' command. +Global Font Lock mode is controlled by the command `global-font-lock-mode'. If nil, means no modes have Font Lock mode automatically turned on. If t, all modes that support Font Lock mode have it automatically turned on. If a list, it should be a list of `major-mode' symbol names for which Font Lock @@ -782,60 +985,20 @@ means that Font Lock mode is turned on for buffers in C and C++ modes only." (repeat :inline t (symbol :tag "mode")))) :group 'font-lock) -;;;###autoload -(defun global-font-lock-mode (&optional arg message) - "Toggle Global Font Lock mode. -With prefix ARG, turn Global Font Lock mode on if and only if ARG is positive. -Displays a message saying whether the mode is on or off if MESSAGE is non-nil. -Returns the new status of Global Font Lock mode (non-nil means on). - -When Global Font Lock mode is enabled, Font Lock mode is automagically -turned on in a buffer if its major mode is one of `font-lock-global-modes'." - (interactive "P\np") - (let ((off-p (if arg - (<= (prefix-numeric-value arg) 0) - global-font-lock-mode))) - (if off-p - (remove-hook 'find-file-hooks 'turn-on-font-lock-if-enabled) - (add-hook 'find-file-hooks 'turn-on-font-lock-if-enabled) - (add-hook 'post-command-hook 'turn-on-font-lock-if-enabled) - (setq font-lock-buffers (buffer-list))) - (when message - (message "Global Font Lock mode is now %s." (if off-p "OFF" "ON"))) - (setq global-font-lock-mode (not off-p)))) - -(defun font-lock-change-major-mode () - ;; Turn off Font Lock mode if it's on. - (when font-lock-mode - (font-lock-mode)) - ;; Gross hack warning: Delicate readers should avert eyes now. - ;; Something is running `kill-all-local-variables', which generally means the - ;; major mode is being changed. Run `turn-on-font-lock-if-enabled' after the - ;; file is visited or the current command has finished. - (when global-font-lock-mode - (add-hook 'post-command-hook 'turn-on-font-lock-if-enabled) - (add-to-list 'font-lock-buffers (current-buffer)))) - (defun turn-on-font-lock-if-enabled () - ;; Gross hack warning: Delicate readers should avert eyes now. - ;; Turn on Font Lock mode if it's supported by the major mode and enabled by - ;; the user. - (remove-hook 'post-command-hook 'turn-on-font-lock-if-enabled) - (while font-lock-buffers - (when (buffer-live-p (car font-lock-buffers)) - (save-excursion - (set-buffer (car font-lock-buffers)) - (when (and (or font-lock-defaults - (assq major-mode font-lock-defaults-alist)) - (or (eq font-lock-global-modes t) - (if (eq (car-safe font-lock-global-modes) 'not) - (not (memq major-mode (cdr font-lock-global-modes))) - (memq major-mode font-lock-global-modes)))) - (let (inhibit-quit) - (turn-on-font-lock))))) - (setq font-lock-buffers (cdr font-lock-buffers)))) - -(add-hook 'change-major-mode-hook 'font-lock-change-major-mode) + (when (and (or font-lock-defaults + (assq major-mode font-lock-defaults-alist)) + (or (eq font-lock-global-modes t) + (if (eq (car-safe font-lock-global-modes) 'not) + (not (memq major-mode (cdr font-lock-global-modes))) + (memq major-mode font-lock-global-modes)))) + (let (inhibit-quit) + (turn-on-font-lock)))) + +;;;###autoload +(easy-mmode-define-global-mode + global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled + :extra-args (dummy)) ;;; End of Global Font Lock mode. @@ -847,11 +1010,12 @@ turned on in a buffer if its major mode is one of `font-lock-global-modes'." ;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer' ;; themselves. -(defcustom font-lock-support-mode nil +(defcustom font-lock-support-mode 'jit-lock-mode "*Support mode for Font Lock mode. Support modes speed up Font Lock mode by being choosy about when fontification -occurs. Known support modes are Fast Lock mode (symbol `fast-lock-mode') and -Lazy Lock mode (symbol `lazy-lock-mode'). See those modes for more info. +occurs. Known support modes are Fast Lock mode (symbol `fast-lock-mode'), +Lazy Lock mode (symbol `lazy-lock-mode'), and Just-in-time Lock mode (symbol +`jit-lock-mode'. See those modes for more info. If nil, means support for Font Lock mode is never performed. If a symbol, use that support mode. If a list, each element should be of the form (MAJOR-MODE . SUPPORT-MODE), @@ -864,43 +1028,74 @@ The value of this variable is used when Font Lock mode is turned on." :type '(choice (const :tag "none" nil) (const :tag "fast lock" fast-lock-mode) (const :tag "lazy lock" lazy-lock-mode) + (const :tag "jit lock" jit-lock-mode) (repeat :menu-tag "mode specific" :tag "mode specific" - :value ((t . lazy-lock-mode)) + :value ((t . jit-lock-mode)) (cons :tag "Instance" (radio :tag "Mode" (const :tag "all" t) (symbol :tag "name")) - (radio :tag "Decoration" + (radio :tag "Support" + (const :tag "none" nil) (const :tag "fast lock" fast-lock-mode) - (const :tag "lazy lock" lazy-lock-mode))) + (const :tag "lazy lock" lazy-lock-mode) + (const :tag "JIT lock" jit-lock-mode))) )) + :version "21.1" :group 'font-lock) (defvar fast-lock-mode nil) (defvar lazy-lock-mode nil) +(defvar jit-lock-mode nil) (defun font-lock-turn-on-thing-lock () (let ((thing-mode (font-lock-value-in-major-mode font-lock-support-mode))) (cond ((eq thing-mode 'fast-lock-mode) (fast-lock-mode t)) ((eq thing-mode 'lazy-lock-mode) - (lazy-lock-mode t))))) + (lazy-lock-mode t)) + ((eq thing-mode 'jit-lock-mode) + ;; Prepare for jit-lock + (remove-hook 'after-change-functions + 'font-lock-after-change-function t) + (set (make-local-variable 'font-lock-fontify-buffer-function) + 'jit-lock-refontify) + ;; Don't fontify eagerly (and don't abort is the buffer is large). + (set (make-local-variable 'font-lock-fontified) t) + ;; Use jit-lock. + (jit-lock-register 'font-lock-fontify-region + (not font-lock-keywords-only)))))) (defun font-lock-turn-off-thing-lock () (cond (fast-lock-mode - (fast-lock-mode nil)) + (fast-lock-mode -1)) + (jit-lock-mode + (jit-lock-unregister 'font-lock-fontify-region) + ;; Reset local vars to the non-jit-lock case. + (kill-local-variable 'font-lock-fontify-buffer-function)) (lazy-lock-mode - (lazy-lock-mode nil)))) + (lazy-lock-mode -1)))) (defun font-lock-after-fontify-buffer () (cond (fast-lock-mode (fast-lock-after-fontify-buffer)) + ;; Useless now that jit-lock intercepts font-lock-fontify-buffer. -sm + ;; (jit-lock-mode + ;; (jit-lock-after-fontify-buffer)) (lazy-lock-mode (lazy-lock-after-fontify-buffer)))) (defun font-lock-after-unfontify-buffer () (cond (fast-lock-mode (fast-lock-after-unfontify-buffer)) + ;; Useless as well. It's only called when: + ;; - turning off font-lock: it does not matter if we leave spurious + ;; `fontified' text props around since jit-lock-mode is also off. + ;; - font-lock-default-fontify-buffer fails: this is not run + ;; any more anyway. -sm + ;; + ;; (jit-lock-mode + ;; (jit-lock-after-unfontify-buffer)) (lazy-lock-mode (lazy-lock-after-unfontify-buffer)))) @@ -949,7 +1144,7 @@ The value of this variable is used when Font Lock mode is turned on." ;;;###autoload (defun font-lock-fontify-buffer () - "Fontify the current buffer the way `font-lock-mode' would." + "Fontify the current buffer the way the function `font-lock-mode' would." (interactive) (let ((font-lock-verbose (or font-lock-verbose (interactive-p)))) (funcall font-lock-fontify-buffer-function))) @@ -967,27 +1162,26 @@ The value of this variable is used when Font Lock mode is turned on." (let ((verbose (if (numberp font-lock-verbose) (> (buffer-size) font-lock-verbose) font-lock-verbose))) - (when verbose - (message "Fontifying %s..." (buffer-name))) - ;; Make sure we have the right `font-lock-keywords' etc. - (unless font-lock-mode - (font-lock-set-defaults)) - ;; Make sure we fontify etc. in the whole buffer. - (save-restriction - (widen) - (condition-case nil - (save-excursion - (save-match-data - (font-lock-fontify-region (point-min) (point-max) verbose) - (font-lock-after-fontify-buffer) - (setq font-lock-fontified t))) - ;; We don't restore the old fontification, so it's best to unfontify. - (quit (font-lock-unfontify-buffer)))) - ;; Make sure we undo `font-lock-keywords' etc. - (unless font-lock-mode - (font-lock-unset-defaults)) - (if verbose (message "Fontifying %s...%s" (buffer-name) - (if font-lock-fontified "done" "quit"))))) + (with-temp-message + (when verbose + (format "Fontifying %s..." (buffer-name))) + ;; Make sure we have the right `font-lock-keywords' etc. + (unless font-lock-mode + (font-lock-set-defaults)) + ;; Make sure we fontify etc. in the whole buffer. + (save-restriction + (widen) + (condition-case nil + (save-excursion + (save-match-data + (font-lock-fontify-region (point-min) (point-max) verbose) + (font-lock-after-fontify-buffer) + (setq font-lock-fontified t))) + ;; We don't restore the old fontification, so it's best to unfontify. + (quit (font-lock-unfontify-buffer)))) + ;; Make sure we undo `font-lock-keywords' etc. + (unless font-lock-mode + (font-lock-unset-defaults))))) (defun font-lock-default-unfontify-buffer () ;; Make sure we unfontify etc. in the whole buffer. @@ -998,15 +1192,34 @@ The value of this variable is used when Font Lock mode is turned on." (setq font-lock-fontified nil))) (defun font-lock-default-fontify-region (beg end loudly) - (save-buffer-state ((old-syntax-table (syntax-table))) + (save-buffer-state + ((parse-sexp-lookup-properties font-lock-syntactic-keywords) + (old-syntax-table (syntax-table))) (unwind-protect (save-restriction (widen) ;; Use the fontification syntax table, if any. (when font-lock-syntax-table (set-syntax-table font-lock-syntax-table)) + ;; check to see if we should expand the beg/end area for + ;; proper multiline matches + (when (and (> beg (point-min)) + (get-text-property (1- beg) 'font-lock-multiline)) + ;; We are just after or in a multiline match. + (setq beg (or (previous-single-property-change + beg 'font-lock-multiline) + (point-min))) + (goto-char beg) + (setq beg (line-beginning-position))) + (setq end (or (text-property-any end (point-max) + 'font-lock-multiline nil) + (point-max))) + (goto-char end) + (setq end (line-beginning-position 2)) ;; Now do the fontification. (font-lock-unfontify-region beg end) + (when font-lock-syntactic-keywords + (font-lock-fontify-syntactic-keywords-region beg end)) (unless font-lock-keywords-only (font-lock-fontify-syntactically-region beg end loudly)) (font-lock-fontify-keywords-region beg end loudly)) @@ -1016,23 +1229,27 @@ The value of this variable is used when Font Lock mode is turned on." ;; The following must be rethought, since keywords can override fontification. ; ;; Now scan for keywords, but not if we are inside a comment now. ; (or (and (not font-lock-keywords-only) -; (let ((state (parse-partial-sexp beg end nil nil +; (let ((state (parse-partial-sexp beg end nil nil ; font-lock-cache-state))) ; (or (nth 4 state) (nth 7 state)))) ; (font-lock-fontify-keywords-region beg end)) (defun font-lock-default-unfontify-region (beg end) (save-buffer-state nil - (remove-text-properties beg end '(face nil)))) + (remove-text-properties beg end + (if font-lock-syntactic-keywords + '(face nil syntax-table nil font-lock-multiline nil) + '(face nil font-lock-multiline nil))))) ;; Called when any modification is made to buffer text. (defun font-lock-after-change-function (beg end old-len) - (save-excursion - (save-match-data - ;; Rescan between start of lines enclosing the region. - (font-lock-fontify-region - (progn (goto-char beg) (beginning-of-line) (point)) - (progn (goto-char end) (forward-line 1) (point)))))) + (let ((inhibit-point-motion-hooks t)) + (save-excursion + (save-match-data + ;; Rescan between start of lines enclosing the region. + (font-lock-fontify-region + (progn (goto-char beg) (beginning-of-line) (point)) + (progn (goto-char end) (forward-line 1) (point))))))) (defun font-lock-fontify-block (&optional arg) "Fontify some lines the way `font-lock-fontify-buffer' would. @@ -1042,7 +1259,8 @@ no ARG is given and `font-lock-mark-block-function' is nil. If `font-lock-mark-block-function' non-nil and no ARG is given, it is used to delimit the region to fontify." (interactive "P") - (let (font-lock-beginning-of-syntax-function deactivate-mark) + (let ((inhibit-point-motion-hooks t) font-lock-beginning-of-syntax-function + deactivate-mark) ;; Make sure we have the right `font-lock-keywords' etc. (if (not font-lock-mode) (font-lock-set-defaults)) (save-excursion @@ -1061,67 +1279,6 @@ delimit the region to fontify." ;;; End of Fontification functions. -;;; Syntactic fontification functions. - -;; These record the parse state at a particular position, always the start of a -;; line. Used to make `font-lock-fontify-syntactically-region' faster. -;; Previously, `font-lock-cache-position' was just a buffer position. However, -;; under certain situations, this occasionally resulted in mis-fontification. -;; I think the "situations" were deletion with Lazy Lock mode's deferral. sm. -(defvar font-lock-cache-state nil) -(defvar font-lock-cache-position nil) - -(defun font-lock-fontify-syntactically-region (start end &optional loudly) - "Put proper face on each string and comment between START and END. -START should be at the beginning of a line." - (let ((cache (marker-position font-lock-cache-position)) - state string beg) - (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name))) - (goto-char start) - ;; - ;; Find the state at the `beginning-of-line' before `start'. - (if (eq start cache) - ;; Use the cache for the state of `start'. - (setq state font-lock-cache-state) - ;; Find the state of `start'. - (if (null font-lock-beginning-of-syntax-function) - ;; Use the state at the previous cache position, if any, or - ;; otherwise calculate from `point-min'. - (if (or (null cache) (< start cache)) - (setq state (parse-partial-sexp (point-min) start)) - (setq state (parse-partial-sexp cache start nil nil - font-lock-cache-state))) - ;; Call the function to move outside any syntactic block. - (funcall font-lock-beginning-of-syntax-function) - (setq state (parse-partial-sexp (point) start))) - ;; Cache the state and position of `start'. - (setq font-lock-cache-state state) - (set-marker font-lock-cache-position start)) - ;; - ;; If the region starts inside a string or comment, show the extent of it. - (when (or (nth 3 state) (nth 4 state)) - (setq string (nth 3 state) beg (point)) - (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table)) - (put-text-property beg (point) 'face - (if string - font-lock-string-face - font-lock-comment-face))) - ;; - ;; Find each interesting place between here and `end'. - (while (and (< (point) end) - (progn - (setq state (parse-partial-sexp (point) end nil nil state - 'syntax-table)) - (or (nth 3 state) (nth 4 state)))) - (setq string (nth 3 state) beg (nth 8 state)) - (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table)) - (put-text-property beg (point) 'face - (if string - font-lock-string-face - font-lock-comment-face))))) - -;;; End of Syntactic fontification functions. - ;;; Additional text property functions. ;; The following text property functions should be builtins. This means they @@ -1203,7 +1360,163 @@ Optional argument OBJECT is the string or buffer containing the text." ;;; End of Additional text property functions. -;;; Regexp fontification functions. +;;; Syntactic regexp fontification functions. + +;; These syntactic keyword pass functions are identical to those keyword pass +;; functions below, with the following exceptions; (a) they operate on +;; `font-lock-syntactic-keywords' of course, (b) they are all `defun' as speed +;; is less of an issue, (c) eval of property value does not occur JIT as speed +;; is less of an issue, (d) OVERRIDE cannot be `prepend' or `append' as it +;; makes no sense for `syntax-table' property values, (e) they do not do it +;; LOUDLY as it is not likely to be intensive. + +(defun font-lock-apply-syntactic-highlight (highlight) + "Apply HIGHLIGHT following a match. +HIGHLIGHT should be of the form MATCH-HIGHLIGHT, +see `font-lock-syntactic-keywords'." + (let* ((match (nth 0 highlight)) + (start (match-beginning match)) (end (match-end match)) + (value (nth 1 highlight)) + (override (nth 2 highlight))) + (when (and (consp value) (not (numberp (car value)))) + (setq value (eval value))) + (when (stringp value) (setq value (string-to-syntax value))) + (cond ((not start) + ;; No match but we might not signal an error. + (or (nth 3 highlight) + (error "No match %d in highlight %S" match highlight))) + ((not override) + ;; Cannot override existing fontification. + (or (text-property-not-all start end 'syntax-table nil) + (put-text-property start end 'syntax-table value))) + ((eq override t) + ;; Override existing fontification. + (put-text-property start end 'syntax-table value)) + ((eq override 'keep) + ;; Keep existing fontification. + (font-lock-fillin-text-property start end 'syntax-table value))))) + +(defun font-lock-fontify-syntactic-anchored-keywords (keywords limit) + "Fontify according to KEYWORDS until LIMIT. +KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords', +LIMIT can be modified by the value of its PRE-MATCH-FORM." + (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights + ;; Evaluate PRE-MATCH-FORM. + (pre-match-value (eval (nth 1 keywords)))) + ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line. + (if (and (numberp pre-match-value) (> pre-match-value (point))) + (setq limit pre-match-value) + (setq limit (line-end-position))) + (save-match-data + ;; Find an occurrence of `matcher' before `limit'. + (while (if (stringp matcher) + (re-search-forward matcher limit t) + (funcall matcher limit)) + ;; Apply each highlight to this instance of `matcher'. + (setq highlights lowdarks) + (while highlights + (font-lock-apply-syntactic-highlight (car highlights)) + (setq highlights (cdr highlights))))) + ;; Evaluate POST-MATCH-FORM. + (eval (nth 2 keywords)))) + +(defun font-lock-fontify-syntactic-keywords-region (start end) + "Fontify according to `font-lock-syntactic-keywords' between START and END. +START should be at the beginning of a line." + ;; Ensure the beginning of the file is properly syntactic-fontified. + (when (and font-lock-syntactically-fontified + (< font-lock-syntactically-fontified start)) + (setq start (max font-lock-syntactically-fontified (point-min))) + (setq font-lock-syntactically-fontified end)) + ;; If `font-lock-syntactic-keywords' is a symbol, get the real keywords. + (when (symbolp font-lock-syntactic-keywords) + (setq font-lock-syntactic-keywords (font-lock-eval-keywords + font-lock-syntactic-keywords))) + ;; If `font-lock-syntactic-keywords' is not compiled, compile it. + (unless (eq (car font-lock-syntactic-keywords) t) + (setq font-lock-syntactic-keywords (font-lock-compile-keywords + font-lock-syntactic-keywords))) + ;; Get down to business. + (let ((case-fold-search font-lock-keywords-case-fold-search) + (keywords (cdr font-lock-syntactic-keywords)) + keyword matcher highlights) + (while keywords + ;; Find an occurrence of `matcher' from `start' to `end'. + (setq keyword (car keywords) matcher (car keyword)) + (goto-char start) + (while (if (stringp matcher) + (re-search-forward matcher end t) + (funcall matcher end)) + ;; Apply each highlight to this instance of `matcher', which may be + ;; specific highlights or more keywords anchored to `matcher'. + (setq highlights (cdr keyword)) + (while highlights + (if (numberp (car (car highlights))) + (font-lock-apply-syntactic-highlight (car highlights)) + (font-lock-fontify-syntactic-anchored-keywords (car highlights) + end)) + (setq highlights (cdr highlights)))) + (setq keywords (cdr keywords))))) + +;;; End of Syntactic regexp fontification functions. + +;;; Syntactic fontification functions. + +;; These record the parse state at a particular position, always the start of a +;; line. Used to make `font-lock-fontify-syntactically-region' faster. +;; Previously, `font-lock-cache-position' was just a buffer position. However, +;; under certain situations, this occasionally resulted in mis-fontification. +;; I think the "situations" were deletion with Lazy Lock mode's deferral. sm. +(defvar font-lock-cache-state nil) +(defvar font-lock-cache-position nil) + +(defun font-lock-fontify-syntactically-region (start end &optional loudly) + "Put proper face on each string and comment between START and END. +START should be at the beginning of a line." + (let ((cache (marker-position font-lock-cache-position)) + state face beg) + (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name))) + (goto-char start) + ;; + ;; Find the state at the `beginning-of-line' before `start'. + (if (eq start cache) + ;; Use the cache for the state of `start'. + (setq state font-lock-cache-state) + ;; Find the state of `start'. + (if (null font-lock-beginning-of-syntax-function) + ;; Use the state at the previous cache position, if any, or + ;; otherwise calculate from `point-min'. + (if (or (null cache) (< start cache)) + (setq state (parse-partial-sexp (point-min) start)) + (setq state (parse-partial-sexp cache start nil nil + font-lock-cache-state))) + ;; Call the function to move outside any syntactic block. + (funcall font-lock-beginning-of-syntax-function) + (setq state (parse-partial-sexp (point) start))) + ;; Cache the state and position of `start'. + (setq font-lock-cache-state state) + (set-marker font-lock-cache-position start)) + ;; + ;; If the region starts inside a string or comment, show the extent of it. + (when (or (nth 3 state) (nth 4 state)) + (setq face (funcall font-lock-syntactic-face-function state) beg (point)) + (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table)) + (put-text-property beg (point) 'face face)) + ;; + ;; Find each interesting place between here and `end'. + (while (and (< (point) end) + (progn + (setq state (parse-partial-sexp (point) end nil nil state + 'syntax-table)) + (or (nth 3 state) (nth 4 state)))) + (setq face (funcall font-lock-syntactic-face-function state) + beg (nth 8 state)) + (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table)) + (put-text-property beg (point) 'face face)))) + +;;; End of Syntactic fontification functions. + +;;; Keyword regexp fontification functions. (defsubst font-lock-apply-highlight (highlight) "Apply HIGHLIGHT following a match. @@ -1237,17 +1550,27 @@ HIGHLIGHT should be of the form MATCH-HIGHLIGHT, see `font-lock-keywords'." KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords', LIMIT can be modified by the value of its PRE-MATCH-FORM." (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights + (lead-start (match-beginning 0)) ;; Evaluate PRE-MATCH-FORM. (pre-match-value (eval (nth 1 keywords)))) ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line. - (if (and (numberp pre-match-value) (> pre-match-value (point))) - (setq limit pre-match-value) - (save-excursion (end-of-line) (setq limit (point)))) + (if (not (and (numberp pre-match-value) (> pre-match-value (point)))) + (setq limit (line-end-position)) + (setq limit pre-match-value) + (when (and font-lock-multiline (>= limit (line-beginning-position 2))) + ;; this is a multiline anchored match + ;; (setq font-lock-multiline t) + (put-text-property (if (= limit (line-beginning-position 2)) + (1- limit) + (min lead-start (point))) + limit + 'font-lock-multiline t))) (save-match-data ;; Find an occurrence of `matcher' before `limit'. - (while (if (stringp matcher) - (re-search-forward matcher limit t) - (funcall matcher limit)) + (while (and (< (point) limit) + (if (stringp matcher) + (re-search-forward matcher limit t) + (funcall matcher limit))) ;; Apply each highlight to this instance of `matcher'. (setq highlights lowdarks) (while highlights @@ -1259,7 +1582,7 @@ LIMIT can be modified by the value of its PRE-MATCH-FORM." (defun font-lock-fontify-keywords-region (start end &optional loudly) "Fontify according to `font-lock-keywords' between START and END. START should be at the beginning of a line." - (unless (eq (car-safe font-lock-keywords) t) + (unless (eq (car font-lock-keywords) t) (setq font-lock-keywords (font-lock-compile-keywords font-lock-keywords))) (let ((case-fold-search font-lock-keywords-case-fold-search) (keywords (cdr font-lock-keywords)) @@ -1274,9 +1597,25 @@ START should be at the beginning of a line." ;; Find an occurrence of `matcher' from `start' to `end'. (setq keyword (car keywords) matcher (car keyword)) (goto-char start) - (while (if (stringp matcher) - (re-search-forward matcher end t) - (funcall matcher end)) + (while (and (< (point) end) + (if (stringp matcher) + (re-search-forward matcher end t) + (funcall matcher end))) + (when (and font-lock-multiline + (match-beginning 0) + (>= (point) + (save-excursion (goto-char (match-beginning 0)) + (forward-line 1) (point)))) + ;; this is a multiline regexp match + ;; (setq font-lock-multiline t) + (put-text-property (if (= (point) + (save-excursion + (goto-char (match-beginning 0)) + (forward-line 1) (point))) + (1- (point)) + (match-beginning 0)) + (point) + 'font-lock-multiline t)) ;; Apply each highlight to this instance of `matcher', which may be ;; specific highlights or more keywords anchored to `matcher'. (setq highlights (cdr keyword)) @@ -1287,13 +1626,14 @@ START should be at the beginning of a line." (setq highlights (cdr highlights)))) (setq keywords (cdr keywords))))) -;;; End of Regexp fontification functions. +;;; End of Keyword regexp fontification functions. ;; Various functions. (defun font-lock-compile-keywords (keywords) - ;; Compile KEYWORDS into the form (t KEYWORD ...) where KEYWORD is of the - ;; form (MATCHER HIGHLIGHT ...) as shown in `font-lock-keywords' doc string. + "Compile KEYWORDS into the form (t KEYWORD ...). +Here KEYWORD is of the form (MATCHER HIGHLIGHT ...) as shown in the +`font-lock-keywords' doc string." (if (eq (car-safe keywords) t) keywords (cons t (mapcar 'font-lock-compile-keyword keywords)))) @@ -1317,17 +1657,26 @@ START should be at the beginning of a line." (t ; (MATCHER HIGHLIGHT ...) keyword))) +(defun font-lock-eval-keywords (keywords) + "Evalulate KEYWORDS if a function (funcall) or variable (eval) name." + (if (listp keywords) + keywords + (font-lock-eval-keywords (if (fboundp keywords) + (funcall keywords) + (eval keywords))))) + (defun font-lock-value-in-major-mode (alist) - ;; Return value in ALIST for `major-mode', or ALIST if it is not an alist. - ;; Structure is ((MAJOR-MODE . VALUE) ...) where MAJOR-MODE may be t. + "Return value in ALIST for `major-mode', or ALIST if it is not an alist. +Structure is ((MAJOR-MODE . VALUE) ...) where MAJOR-MODE may be t." (if (consp alist) (cdr (or (assq major-mode alist) (assq t alist))) alist)) (defun font-lock-choose-keywords (keywords level) - ;; Return LEVELth element of KEYWORDS. A LEVEL of nil is equal to a - ;; LEVEL of 0, a LEVEL of t is equal to (1- (length KEYWORDS)). - (cond ((symbolp keywords) + "Return LEVELth element of KEYWORDS. +A LEVEL of nil is equal to a LEVEL of 0, a LEVEL of t is equal to +\(1- (length KEYWORDS))." + (cond ((not (and (listp keywords) (symbolp (car keywords)))) keywords) ((numberp level) (or (nth level keywords) (car (reverse keywords)))) @@ -1342,26 +1691,30 @@ START should be at the beginning of a line." "Set fontification defaults appropriately for this mode. Sets various variables using `font-lock-defaults' (or, if nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." - ;; Set fontification defaults. - (make-local-variable 'font-lock-fontified) - ;; Set iff not previously set. + ;; Set fontification defaults iff not previously set. (unless font-lock-set-defaults (set (make-local-variable 'font-lock-set-defaults) t) (set (make-local-variable 'font-lock-cache-state) nil) (set (make-local-variable 'font-lock-cache-position) (make-marker)) + (make-local-variable 'font-lock-fontified) + (make-local-variable 'font-lock-multiline) (let* ((defaults (or font-lock-defaults (cdr (assq major-mode font-lock-defaults-alist)))) (keywords (font-lock-choose-keywords (nth 0 defaults) (font-lock-value-in-major-mode font-lock-maximum-decoration))) - (local (cdr (assq major-mode font-lock-keywords-alist)))) + (local (cdr (assq major-mode font-lock-keywords-alist))) + (removed-keywords + (cdr-safe (assq major-mode font-lock-removed-keywords-alist)))) ;; Regexp fontification? (set (make-local-variable 'font-lock-keywords) - (if (fboundp keywords) (funcall keywords) (eval keywords))) + (font-lock-compile-keywords (font-lock-eval-keywords keywords))) ;; Local fontification? (while local (font-lock-add-keywords nil (car (car local)) (cdr (car local))) (setq local (cdr local))) + (when removed-keywords + (font-lock-remove-keywords nil removed-keywords)) ;; Syntactic fontification? (when (nth 1 defaults) (set (make-local-variable 'font-lock-keywords-only) t)) @@ -1380,8 +1733,7 @@ Sets various variables using `font-lock-defaults' (or, if nil, using (mapcar 'identity (car (car slist))))) (syntax (cdr (car slist)))) (while chars - (modify-syntax-entry (car chars) syntax - font-lock-syntax-table) + (modify-syntax-entry (car chars) syntax font-lock-syntax-table) (setq chars (cdr chars))) (setq slist (cdr slist)))))) ;; Syntax function for syntactic fontification? @@ -1389,16 +1741,14 @@ Sets various variables using `font-lock-defaults' (or, if nil, using (set (make-local-variable 'font-lock-beginning-of-syntax-function) (nth 4 defaults))) ;; Variable alist? - (let ((alist (nthcdr 5 defaults))) - (while alist - (let ((variable (car (car alist))) (value (cdr (car alist)))) - (unless (boundp variable) - (setq variable nil)) - (set (make-local-variable variable) value) - (setq alist (cdr alist)))))))) + (dolist (x (nthcdr 5 defaults)) + (let ((variable (car x)) (value (cdr x))) + (unless (boundp variable) + (set variable nil)) ;why ? + (set (make-local-variable variable) value)))))) (defun font-lock-unset-defaults () - "Unset fontification defaults. See `font-lock-set-defaults'." + "Unset fontification defaults. See function `font-lock-set-defaults'." (setq font-lock-set-defaults nil font-lock-keywords nil font-lock-keywords-only nil @@ -1414,41 +1764,8 @@ Sets various variables using `font-lock-defaults' (or, if nil, using ;;; Colour etc. support. -;; Originally these variable values were face names such as `bold' etc. -;; Now we create our own faces, but we keep these variables for compatibility -;; and they give users another mechanism for changing face appearance. -;; We now allow a FACENAME in `font-lock-keywords' to be any expression that -;; returns a face. So the easiest thing is to continue using these variables, -;; rather than sometimes evaling FACENAME and sometimes not. sm. -(defvar font-lock-comment-face 'font-lock-comment-face - "Face name to use for comments.") - -(defvar font-lock-string-face 'font-lock-string-face - "Face name to use for strings.") - -(defvar font-lock-keyword-face 'font-lock-keyword-face - "Face name to use for keywords.") - -(defvar font-lock-builtin-face 'font-lock-builtin-face - "Face name to use for builtins.") - -(defvar font-lock-function-name-face 'font-lock-function-name-face - "Face name to use for function names.") - -(defvar font-lock-variable-name-face 'font-lock-variable-name-face - "Face name to use for variable names.") - -(defvar font-lock-type-face 'font-lock-type-face - "Face name to use for type names.") - -(defvar font-lock-reference-face 'font-lock-reference-face - "Face name to use for reference names.") - -(defvar font-lock-warning-face 'font-lock-warning-face - "Face name to use for things that should stand out.") - ;; Originally face attributes were specified via `font-lock-face-attributes'. -;; Users then changed the default face attributes by setting this variable. +;; Users then changed the default face attributes by setting that variable. ;; However, we try and be back-compatible and respect its value if set except ;; for faces where M-x customize has been used to save changes for the face. (when (boundp 'font-lock-face-attributes) @@ -1479,18 +1796,21 @@ Sets various variables using `font-lock-defaults' (or, if nil, using ;; But now we do it the custom way. Note that `defface' will not overwrite any ;; faces declared above via `custom-declare-face'. (defface font-lock-comment-face - '((((class grayscale) (background light)) + '((((type tty pc) (class color) (background light)) (:foreground "red")) + (((type tty pc) (class color) (background dark)) (:foreground "lightred")) + (((class grayscale) (background light)) (:foreground "DimGray" :bold t :italic t)) (((class grayscale) (background dark)) (:foreground "LightGray" :bold t :italic t)) (((class color) (background light)) (:foreground "Firebrick")) - (((class color) (background dark)) (:foreground "OrangeRed")) + (((class color) (background dark)) (:foreground "chocolate1")) (t (:bold t :italic t))) "Font Lock mode face used to highlight comments." :group 'font-lock-highlighting-faces) (defface font-lock-string-face - '((((class grayscale) (background light)) (:foreground "DimGray" :italic t)) + '((((type tty) (class color)) (:foreground "green")) + (((class grayscale) (background light)) (:foreground "DimGray" :italic t)) (((class grayscale) (background dark)) (:foreground "LightGray" :italic t)) (((class color) (background light)) (:foreground "RosyBrown")) (((class color) (background dark)) (:foreground "LightSalmon")) @@ -1498,8 +1818,14 @@ Sets various variables using `font-lock-defaults' (or, if nil, using "Font Lock mode face used to highlight strings." :group 'font-lock-highlighting-faces) +(defface font-lock-doc-face + '((t :inherit font-lock-string-face)) + "Font Lock mode face used to highlight documentation." + :group 'font-lock-highlighting-faces) + (defface font-lock-keyword-face - '((((class grayscale) (background light)) (:foreground "LightGray" :bold t)) + '((((type tty) (class color)) (:foreground "cyan" :weight bold)) + (((class grayscale) (background light)) (:foreground "LightGray" :bold t)) (((class grayscale) (background dark)) (:foreground "DimGray" :bold t)) (((class color) (background light)) (:foreground "Purple")) (((class color) (background dark)) (:foreground "Cyan")) @@ -1508,7 +1834,8 @@ Sets various variables using `font-lock-defaults' (or, if nil, using :group 'font-lock-highlighting-faces) (defface font-lock-builtin-face - '((((class grayscale) (background light)) (:foreground "LightGray" :bold t)) + '((((type tty) (class color)) (:foreground "blue" :weight light)) + (((class grayscale) (background light)) (:foreground "LightGray" :bold t)) (((class grayscale) (background dark)) (:foreground "DimGray" :bold t)) (((class color) (background light)) (:foreground "Orchid")) (((class color) (background dark)) (:foreground "LightSteelBlue")) @@ -1517,16 +1844,16 @@ Sets various variables using `font-lock-defaults' (or, if nil, using :group 'font-lock-highlighting-faces) (defface font-lock-function-name-face - ;; Currently, Emacs/Custom does not support a :reverse or :invert spec. - '((((class color) (background light)) (:foreground "Blue")) + '((((type tty) (class color)) (:foreground "blue" :weight bold)) + (((class color) (background light)) (:foreground "Blue")) (((class color) (background dark)) (:foreground "LightSkyBlue")) - (t ;(:reverse t :bold t) - (:italic t :bold t))) + (t (:inverse-video t :bold t))) "Font Lock mode face used to highlight function names." :group 'font-lock-highlighting-faces) (defface font-lock-variable-name-face - '((((class grayscale) (background light)) + '((((type tty) (class color)) (:foreground "yellow" :weight light)) + (((class grayscale) (background light)) (:foreground "Gray90" :bold t :italic t)) (((class grayscale) (background dark)) (:foreground "DimGray" :bold t :italic t)) @@ -1537,31 +1864,32 @@ Sets various variables using `font-lock-defaults' (or, if nil, using :group 'font-lock-highlighting-faces) (defface font-lock-type-face - '((((class grayscale) (background light)) (:foreground "Gray90" :bold t)) + '((((type tty) (class color)) (:foreground "green")) + (((class grayscale) (background light)) (:foreground "Gray90" :bold t)) (((class grayscale) (background dark)) (:foreground "DimGray" :bold t)) - (((class color) (background light)) (:foreground "DarkOliveGreen")) + (((class color) (background light)) (:foreground "ForestGreen")) (((class color) (background dark)) (:foreground "PaleGreen")) (t (:bold t :underline t))) - "Font Lock mode face used to highlight types." + "Font Lock mode face used to highlight type and classes." :group 'font-lock-highlighting-faces) -(defface font-lock-reference-face - '((((class grayscale) (background light)) +(defface font-lock-constant-face + '((((type tty) (class color)) (:foreground "magenta")) + (((class grayscale) (background light)) (:foreground "LightGray" :bold t :underline t)) (((class grayscale) (background dark)) (:foreground "Gray50" :bold t :underline t)) (((class color) (background light)) (:foreground "CadetBlue")) (((class color) (background dark)) (:foreground "Aquamarine")) (t (:bold t :underline t))) - "Font Lock mode face used to highlight references." + "Font Lock mode face used to highlight constants and labels." :group 'font-lock-highlighting-faces) (defface font-lock-warning-face - ;; Currently, Emacs/Custom does not support a :reverse or :invert spec. - '((((class color) (background light)) (:foreground "Red" :bold t)) + '((((type tty) (class color)) (:foreground "red")) + (((class color) (background light)) (:foreground "Red" :bold t)) (((class color) (background dark)) (:foreground "Pink" :bold t)) - (t ;(:reverse t :bold t) - (:italic t :bold t))) + (t (:inverse-video t :bold t))) "Font Lock mode face used to highlight warnings." :group 'font-lock-highlighting-faces) @@ -1576,7 +1904,7 @@ Sets various variables using `font-lock-defaults' (or, if nil, using ;; the entry for "Text Properties" something like: ;; ;; (define-key menu-bar-edit-menu [font-lock] -;; '("Syntax Highlighting" . font-lock-menu)) +;; (cons "Syntax Highlighting" font-lock-menu)) ;; ;; and remove a single ";" from the beginning of each line in the rest of this ;; section. Probably the mechanism for telling the menu code what are menu @@ -1609,7 +1937,7 @@ Sets various variables using `font-lock-defaults' (or, if nil, using ; (put 'font-lock-fontify-less 'menu-enable '(identity))) ; ;;; Put the appropriate symbol property values on now. See above. -;(put 'global-font-lock-mode 'menu-selected 'global-font-lock-mode)) +;(put 'global-font-lock-mode 'menu-selected 'global-font-lock-mode) ;(put 'font-lock-mode 'menu-selected 'font-lock-mode) ;(put 'font-lock-fontify-more 'menu-enable '(nth 2 font-lock-fontify-level)) ;(put 'font-lock-fontify-less 'menu-enable '(nth 1 font-lock-fontify-level)) @@ -1682,10 +2010,11 @@ Sets various variables using `font-lock-defaults' (or, if nil, using Matches after point, but ignores leading whitespace and `*' characters. Does not move further than LIMIT. -The expected syntax of a declaration/definition item is `word', possibly ending -with optional whitespace and a `('. Everything following the item (but -belonging to it) is expected to by skip-able by `scan-sexps', and items are -expected to be separated with a `,' and to be terminated with a `;'. +The expected syntax of a declaration/definition item is `word' (preceded by +optional whitespace and `*' characters and proceeded by optional whitespace) +optionally followed by a `('. Everything following the item (but belonging to +it) is expected to by skip-able by `scan-sexps', and items are expected to be +separated with a `,' and to be terminated with a `;'. Thus the regexp matches after point: word ( ^^^^ ^ @@ -1707,15 +2036,8 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item." (goto-char (or (scan-sexps (point) 1) (point-max)))) (goto-char (match-end 2))) (error t))))) - -(defun font-lock-keyword-depth (keyword) - "Return the depth of KEYWORD regexp. -This means the number of parenthesized expressions." - (let ((count 0) start) - (while (string-match "\\\\(" keyword start) - (setq count (1+ count) start (match-end 0))) - count)) - + +;; Lisp. (defconst lisp-font-lock-keywords-1 (eval-when-compile @@ -1724,27 +2046,27 @@ This means the number of parenthesized expressions." ;; Definitions. (list (concat "(\\(def\\(" ;; Function declarations. - "\\(advice\\|alias\\|" - "ine-\\(derived-mode\\|function\\|skeleton\\|widget\\)\\|" - "macro\\|subst\\|un\\)\\|" + "\\(advice\\|alias\\|generic\\|macro\\*?\\|method\\|" + "setf\\|subst\\*?\\|un\\*?\\|" + "ine-\\(condition\\|\\(?:derived\\|minor\\)-mode\\|" + "method-combination\\|setf-expander\\|skeleton\\|widget\\|" + "function\\|\\(compiler\\|modify\\|symbol\\)-macro\\)\\)\\|" ;; Variable declarations. - "\\(const\\|custom\\|face\\|var\\)\\|" + "\\(const\\(ant\\)?\\|custom\\|face\\|parameter\\|var\\)\\|" ;; Structure declarations. - "\\(class\\|group\\|struct\\|type\\)" + "\\(class\\|group\\|package\\|struct\\|type\\)" "\\)\\)\\>" ;; Any whitespace and defined object. "[ \t'\(]*" - "\\(\\sw+\\)?") + "\\(setf[ \t]+\\sw+)\\|\\sw+\\)?") '(1 font-lock-keyword-face) - '(7 (cond ((match-beginning 3) font-lock-function-name-face) - ((match-beginning 5) font-lock-variable-name-face) + '(9 (cond ((match-beginning 3) font-lock-function-name-face) + ((match-beginning 6) font-lock-variable-name-face) (t font-lock-type-face)) nil t)) ;; ;; Emacs Lisp autoload cookies. - '("^;;;\\(###\\)\\(autoload\\)\\>" - (1 font-lock-reference-face prepend) - (2 font-lock-warning-face prepend)) + '("^;;;###\\(autoload\\)" 1 font-lock-warning-face prepend) )) "Subdued level highlighting for Lisp modes.") @@ -1754,146 +2076,66 @@ This means the number of parenthesized expressions." (list ;; ;; Control structures. Emacs Lisp forms. - (cons (concat "(\\(" -; (make-regexp -; '("cond" "if" "while" "let\\*?" "prog[nv12*]?" "catch" "throw" -; "inline" "save-restriction" "save-excursion" "save-window-excursion" -; "save-selected-window" "save-match-data" "save-current-buffer" -; "unwind-protect" "condition-case" "track-mouse" "dont-compile" -; "eval-after-load" "eval-and-compile" "eval-when" "eval-when-compile" -; "with-output-to-temp-buffer" "with-timeout" "with-current-buffer" -; "with-temp-buffer" "with-temp-file")) - "c\\(atch\\|ond\\(\\|ition-case\\)\\)\\|dont-compile\\|" - "eval-\\(a\\(fter-load\\|nd-compile\\)\\|" - "when\\(\\|-compile\\)\\)\\|" - "i\\(f\\|nline\\)\\|let\\*?\\|prog[nv12*]?\\|" - "save-\\(current-buffer\\|excursion\\|match-data\\|" - "restriction\\|selected-window\\|window-excursion\\)\\|" - "t\\(hrow\\|rack-mouse\\)\\|unwind-protect\\|" - "w\\(hile\\|ith-\\(current-buffer\\|" - "output-to-temp-buffer\\|" - "t\\(emp-\\(buffer\\|file\\)\\|imeout\\)\\)\\)" - "\\)\\>") + (cons (concat + "(" (regexp-opt + '("cond" "if" "while" "let" "let*" + "prog" "progn" "progv" "prog1" "prog2" "prog*" + "inline" "lambda" "save-restriction" "save-excursion" + "save-window-excursion" "save-selected-window" + "save-match-data" "save-current-buffer" "unwind-protect" + "condition-case" "track-mouse" + "eval-after-load" "eval-and-compile" "eval-when-compile" + "eval-when" + "with-current-buffer" "with-electric-help" + "with-output-to-string" "with-output-to-temp-buffer" + "with-temp-buffer" "with-temp-file" "with-temp-message" + "with-timeout") t) + "\\>") 1) ;; ;; Control structures. Common Lisp forms. - (cons (concat "(\\(" -; (make-regexp -; '("when" "unless" "case" "ecase" "typecase" "etypecase" -; "loop" "do\\*?" "dotimes" "dolist" -; "proclaim" "declaim" "declare" -; "lexical-let\\*?" "flet" "labels" "return" "return-from")) - "case\\|d\\(ecla\\(im\\|re\\)\\|o\\(\\*?\\|" - "list\\|times\\)\\)\\|e\\(case\\|typecase\\)\\|flet\\|" - "l\\(abels\\|exical-let\\*?\\|oop\\)\\|proclaim\\|" - "return\\(\\|-from\\)\\|typecase\\|unless\\|when" - "\\)\\>") + (cons (concat + "(" (regexp-opt + '("when" "unless" "case" "ecase" "typecase" "etypecase" + "ccase" "ctypecase" "handler-case" "handler-bind" + "restart-bind" "restart-case" "in-package" + "cerror" "break" "ignore-errors" + "loop" "do" "do*" "dotimes" "dolist" "the" "locally" + "proclaim" "declaim" "declare" "symbol-macrolet" + "lexical-let" "lexical-let*" "flet" "labels" "compiler-let" + "destructuring-bind" "macrolet" "tagbody" "block" + "return" "return-from") t) + "\\>") 1) ;; - ;; Feature symbols as references. - '("(\\(featurep\\|provide\\|require\\)\\>[ \t']*\\(\\sw+\\)?" - (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) + ;; Exit/Feature symbols as constants. + (list (concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\>" + "[ \t']*\\(\\sw+\\)?") + '(1 font-lock-keyword-face) + '(2 font-lock-constant-face nil t)) + ;; + ;; Erroneous structures. + '("(\\(abort\\|assert\\|error\\|signal\\)\\>" 1 font-lock-warning-face) ;; ;; Words inside \\[] tend to be for `substitute-command-keys'. - '("\\\\\\\\\\[\\(\\sw+\\)]" 1 font-lock-reference-face prepend) + '("\\\\\\\\\\[\\(\\sw+\\)]" 1 font-lock-constant-face prepend) ;; ;; Words inside `' tend to be symbol names. - '("`\\(\\sw\\sw+\\)'" 1 font-lock-reference-face prepend) + '("`\\(\\sw\\sw+\\)'" 1 font-lock-constant-face prepend) ;; - ;; CLisp `:' keywords as builtins. + ;; Constant values. '("\\<:\\sw\\sw+\\>" 0 font-lock-builtin-face) ;; ;; ELisp and CLisp `&' keywords as types. - '("\\<\\&\\sw+\\>" . font-lock-type-face) + '("\\&\\sw+\\>" . font-lock-type-face) + ;; + ;; CL `with-' and `do-' constructs + '("(\\(\\(do-\\|with-\\)\\(\\s_\\|\\w\\)*\\)" 1 font-lock-keyword-face) ))) "Gaudy level highlighting for Lisp modes.") - (defvar lisp-font-lock-keywords lisp-font-lock-keywords-1 "Default expressions to highlight in Lisp modes.") - - -(defvar scheme-font-lock-keywords - (eval-when-compile - (list - ;; - ;; Declarations. Hannes Haug says - ;; this works for SOS, STklos, SCOOPS, Meroon and Tiny CLOS. - (list (concat "(\\(define\\(" - ;; Function names. - "\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)\\|" - ;; Macro names, as variable names. A bit dubious, this. - "\\(-syntax\\)\\|" - ;; Class names. - "-class" - "\\)\\)\\>" - ;; Any whitespace and declared object. - "[ \t]*(?" - "\\(\\sw+\\)?") - '(1 font-lock-keyword-face) - '(7 (cond ((match-beginning 3) font-lock-function-name-face) - ((match-beginning 6) font-lock-variable-name-face) - (t font-lock-type-face)) - nil t)) - ;; - ;; Control structures. -;(make-regexp '("begin" "call-with-current-continuation" "call/cc" -; "call-with-input-file" "call-with-output-file" "case" "cond" -; "do" "else" "for-each" "if" "lambda" -; "let\\*?" "let-syntax" "letrec" "letrec-syntax" -; ;; Hannes Haug wants: -; "and" "or" "delay" -; ;; Stefan Monnier says don't bother: -; ;;"quasiquote" "quote" "unquote" "unquote-splicing" -; "map" "syntax" "syntax-rules")) - (cons - (concat "(\\(" - "and\\|begin\\|c\\(a\\(ll\\(-with-\\(current-continuation\\|" - "input-file\\|output-file\\)\\|/cc\\)\\|se\\)\\|ond\\)\\|" - "d\\(elay\\|o\\)\\|else\\|for-each\\|if\\|" - "l\\(ambda\\|et\\(-syntax\\|\\*?\\|rec\\(\\|-syntax\\)\\)\\)\\|" - "map\\|or\\|syntax\\(\\|-rules\\)" - "\\)\\>") 1) - ;; - ;; David Fox for SOS/STklos class specifiers. - '("\\<<\\sw+>\\>" . font-lock-type-face) - ;; - ;; Scheme `:' keywords as references. - '("\\<:\\sw+\\>" . font-lock-reference-face) - )) - "Default expressions to highlight in Scheme modes.") - - -(defvar tex-font-lock-keywords -; ;; Regexps updated with help from Ulrik Dickow . -; '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}" -; 2 font-lock-function-name-face) -; ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}" -; 2 font-lock-reference-face) -; ;; It seems a bit dubious to use `bold' and `italic' faces since we might -; ;; not be able to display those fonts. -; ("{\\\\bf\\([^}]+\\)}" 1 'bold keep) -; ("{\\\\\\(em\\|it\\|sl\\)\\([^}]+\\)}" 2 'italic keep) -; ("\\\\\\([a-zA-Z@]+\\|.\\)" . font-lock-keyword-face) -; ("^[ \t\n]*\\\\def[\\\\@]\\(\\w+\\)" 1 font-lock-function-name-face keep)) - ;; Rewritten and extended for LaTeX2e by Ulrik Dickow . - '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}" - 2 font-lock-function-name-face) - ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}" - 2 font-lock-reference-face) - ("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" 1 font-lock-function-name-face) - "\\\\\\([a-zA-Z@]+\\|.\\)" - ;; It seems a bit dubious to use `bold' and `italic' faces since we might - ;; not be able to display those fonts. - ;; LaTeX2e: \emph{This is emphasized}. - ("\\\\emph{\\([^}]+\\)}" 1 'italic keep) - ;; LaTeX2e: \textbf{This is bold}, \textit{...}, \textsl{...} - ("\\\\text\\(\\(bf\\)\\|it\\|sl\\){\\([^}]+\\)}" - 3 (if (match-beginning 2) 'bold 'italic) keep) - ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for good tables. - ("\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)" - 3 (if (match-beginning 2) 'bold 'italic) keep)) - "Default expressions to highlight in TeX modes.") ;;; User choices. @@ -1905,10 +2147,9 @@ This means the number of parenthesized expressions." "Widget `:type' for members of the custom group `font-lock-extra-types'. Members should `:load' the package `font-lock' to use this widget." :args '((const :tag "none" nil) - (repeat :tag "types" - (string :tag "regexp")))) + (repeat :tag "types" regexp))) -(defcustom c-font-lock-extra-types '("FILE" "\\sw+_t") +(defcustom c-font-lock-extra-types '("FILE" "\\sw+_t" "Lisp_Object") "*List of extra types to fontify in C mode. Each list item should be a regexp not containing word-delimiters. For example, a value of (\"FILE\" \"\\\\sw+_t\") means the word FILE and words @@ -1918,7 +2159,19 @@ The value of this variable is used when Font Lock mode is turned on." :type 'font-lock-extra-types-widget :group 'font-lock-extra-types) -(defcustom c++-font-lock-extra-types '("string") +(defcustom c++-font-lock-extra-types + '("\\sw+_t" + "\\([iof]\\|str\\)+stream\\(buf\\)?" "ios" + "string" "rope" + "list" "slist" + "deque" "vector" "bit_vector" + "set" "multiset" + "map" "multimap" + "hash\\(_\\(m\\(ap\\|ulti\\(map\\|set\\)\\)\\|set\\)\\)?" + "stack" "queue" "priority_queue" + "type_info" + "iterator" "const_iterator" "reverse_iterator" "const_reverse_iterator" + "reference" "const_reference") "*List of extra types to fontify in C++ mode. Each list item should be a regexp not containing word-delimiters. For example, a value of (\"string\") means the word string is treated as a type @@ -1938,10 +2191,11 @@ The value of this variable is used when Font Lock mode is turned on." :type 'font-lock-extra-types-widget :group 'font-lock-extra-types) -(defcustom java-font-lock-extra-types '("[A-Z\300-\326\330-\337]\\sw+") +(defcustom java-font-lock-extra-types + '("[A-Z\300-\326\330-\337]\\sw*[a-z]\\sw*") "*List of extra types to fontify in Java mode. Each list item should be a regexp not containing word-delimiters. -For example, a value of (\"[A-Z\300-\326\330-\337]\\\\sw+\") means capitalised +For example, a value of (\"[A-Z\300-\326\330-\337]\\\\sw*[a-z]\\\\sw*\") means capitalised words (and words conforming to the Java id spec) are treated as type names. The value of this variable is used when Font Lock mode is turned on." @@ -1976,22 +2230,37 @@ See also `c-font-lock-extra-types'.") See also `c-font-lock-extra-types'.") (let* ((c-keywords -; ("break" "continue" "do" "else" "for" "if" "return" "switch" "while") - "break\\|continue\\|do\\|else\\|for\\|if\\|return\\|switch\\|while") - (c-type-types -; ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum" -; "signed" "unsigned" "short" "long" "int" "char" "float" "double" -; "void" "volatile" "const") + (eval-when-compile + (regexp-opt '("break" "continue" "do" "else" "for" "if" "return" + "switch" "while" "sizeof" + ;; Type related, but we don't do anything special. + "typedef" "extern" "auto" "register" "static" + "volatile" "const" + ;; Dan Nicolaescu says this is new. + "restrict")))) + (c-type-specs + (eval-when-compile + (regexp-opt '("enum" "struct" "union")))) + (c-type-specs-depth + (regexp-opt-depth c-type-specs)) + (c-type-names `(mapconcat 'identity - (cons - (,@ (concat "auto\\|c\\(har\\|onst\\)\\|double\\|" - "e\\(num\\|xtern\\)\\|float\\|int\\|long\\|register\\|" - "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|typedef\\|" - "un\\(ion\\|signed\\)\\|vo\\(id\\|latile\\)")) + (cons + ,(eval-when-compile + (regexp-opt + '("char" "short" "int" "long" "signed" "unsigned" + "float" "double" "void" "complex"))) c-font-lock-extra-types) "\\|")) - (c-type-depth `(font-lock-keyword-depth (,@ c-type-types))) - ) + (c-type-names-depth + `(regexp-opt-depth ,c-type-names)) + (c-preprocessor-directives + (eval-when-compile + (regexp-opt + '("define" "elif" "else" "endif" "error" "file" "if" "ifdef" + "ifndef" "include" "line" "pragma" "undef")))) + (c-preprocessor-directives-depth + (regexp-opt-depth c-preprocessor-directives))) (setq c-font-lock-keywords-1 (list ;; @@ -2005,7 +2274,7 @@ See also `c-font-lock-extra-types'.") '("^#[ \t]*error[ \t]+\\(.+\\)" 1 font-lock-warning-face prepend) ;; ;; Fontify filenames in #include <...> preprocessor directives as strings. - '("^#[ \t]*\\(import\\|include\\)[ \t]+\\(<[^>\"\n]*>?\\)" + '("^#[ \t]*\\(import\\|include\\)[ \t]*\\(<[^>\"\n]*>?\\)" 2 font-lock-string-face) ;; ;; Fontify function macro names. @@ -2014,12 +2283,15 @@ See also `c-font-lock-extra-types'.") ;; Fontify symbol names in #elif or #if ... defined preprocessor directives. '("^#[ \t]*\\(elif\\|if\\)\\>" ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil - (1 font-lock-reference-face) (2 font-lock-variable-name-face nil t))) + (1 font-lock-builtin-face) (2 font-lock-variable-name-face nil t))) ;; ;; Fontify otherwise as symbol names, and the preprocessor directive names. - '("^#[ \t]*\\(\\sw+\\)\\>[ \t]*\\(\\sw+\\)?" - (1 font-lock-reference-face) (2 font-lock-variable-name-face nil t)) - )) + (list + (concat "^#[ \t]*\\(" c-preprocessor-directives + "\\)\\>[ \t!]*\\(\\sw+\\)?") + '(1 font-lock-builtin-face) + (list (+ 2 c-preprocessor-directives-depth) + 'font-lock-variable-name-face nil t)))) (setq c-font-lock-keywords-2 (append c-font-lock-keywords-1 @@ -2027,21 +2299,27 @@ See also `c-font-lock-extra-types'.") ;; ;; Simple regexps for speed. ;; - ;; Fontify all type specifiers. + ;; Fontify all type names. `(eval . - (cons (concat "\\<\\(" (,@ c-type-types) "\\)\\>") 'font-lock-type-face)) + (cons (concat "\\<\\(" ,c-type-names "\\)\\>") 'font-lock-type-face)) ;; ;; Fontify all builtin keywords (except case, default and goto; see below). - (concat "\\<\\(" c-keywords "\\)\\>") + (concat "\\<\\(" c-keywords "\\|" c-type-specs "\\)\\>") ;; ;; Fontify case/goto keywords and targets, and case default/goto tags. - '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?" - (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) - ;; Anders Lindgren points out that it is quicker to use - ;; MATCH-ANCHORED to effectively anchor the regexp on the left. - '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:" + '("\\<\\(case\\|goto\\)\\>" + (1 font-lock-keyword-face) + ("\\(-[0-9]+\\|\\sw+\\)" + ;; Return limit of search. + (save-excursion (skip-chars-forward "^:\n") (point)) + nil + (1 font-lock-constant-face nil t))) + ;; Anders Lindgren points out that it is quicker to + ;; use MATCH-ANCHORED to effectively anchor the regexp on the left. + ;; This must come after the one for keywords and targets. + '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$" (beginning-of-line) (end-of-line) - (1 font-lock-reference-face))) + (1 font-lock-constant-face))) ))) (setq c-font-lock-keywords-3 @@ -2051,15 +2329,16 @@ See also `c-font-lock-extra-types'.") ;; We still have to fontify type specifiers individually, as C is so hairy. (list ;; - ;; Fontify all storage classes and type specifiers, plus their items. + ;; Fontify all storage types, plus their items. `(eval . - (list (concat "\\<\\(" (,@ c-type-types) "\\)\\>" + (list (concat "\\<\\(" ,c-type-names "\\)\\>" "\\([ \t*&]+\\sw+\\>\\)*") ;; Fontify each declaration item. (list 'font-lock-match-c-style-declaration-item-and-skip-to-next ;; Start with point after all type specifiers. - (list 'goto-char (list 'or (list 'match-beginning - (+ (,@ c-type-depth) 2)) + (list 'goto-char (list 'or + (list 'match-beginning + (+ ,c-type-names-depth 2)) '(match-end 1))) ;; Finish with point after first type specifier. '(goto-char (match-end 1)) @@ -2068,13 +2347,24 @@ See also `c-font-lock-extra-types'.") font-lock-function-name-face font-lock-variable-name-face))))) ;; + ;; Fontify all storage specs and types, plus their items. + `(eval . + (list (concat "\\<\\(" ,c-type-specs "\\)\\>" + "[ \t]*\\(\\sw+\\)?") + (list 1 'font-lock-keyword-face) + (list ,(+ c-type-specs-depth 2) 'font-lock-type-face nil t) + (list 'font-lock-match-c-style-declaration-item-and-skip-to-next + nil nil + ;; Fontify as a variable or function name. + '(1 (if (match-beginning 2) + font-lock-function-name-face + font-lock-variable-name-face) nil t)))) + ;; ;; Fontify structures, or typedef names, plus their items. '("\\(}\\)[ \t*]*\\sw" (font-lock-match-c-style-declaration-item-and-skip-to-next (goto-char (match-end 1)) nil - (1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face)))) + (1 font-lock-type-face))) ;; ;; Fontify anything at beginning of line as a declaration or definition. '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*" @@ -2119,8 +2409,8 @@ See also `c++-font-lock-extra-types'.") "[ \t*&]*" ;; This is `c++-type-spec' from below. (Hint hint!) "\\(\\sw+\\)" ; The instance? - "\\(<\\(\\sw+\\)[ \t*&]*>\\)?" ; Or template? - "\\([ \t]*::[ \t*~]*\\(\\sw+\\)\\)?" ; Or member? + "\\([ \t]*<\\([^>\n]+\\)[ \t*&]*>\\)?" ; Or template? + "\\([ \t]*::[ \t*~]*\\(\\sw+\\)\\)*" ; Or member? ;; Match any trailing parenthesis. "[ \t]*\\((\\)?"))) (save-match-data @@ -2135,56 +2425,80 @@ See also `c++-font-lock-extra-types'.") (goto-char (match-end 2))) (error t))))) +(defun font-lock-match-c++-structor-declaration (limit) + ;; Match C++ constructors and destructors inside class declarations. + (let ((res nil) + (regexp (concat "^\\s-+\\(\\(virtual\\|explicit\\)\\s-+\\)*~?\\(\\<" + (mapconcat 'identity + c++-font-lock-extra-types "\\|") + "\\>\\)\\s-*(" + ;; Don't match function pointer declarations, e.g.: + ;; Foo (*fptr)(); + "\\s-*[^*( \t]"))) + (while (progn (setq res (re-search-forward regexp limit t)) + (and res + (save-excursion + (beginning-of-line) + (save-match-data + (not (vectorp (c-at-toplevel-p)))))))) + res)) + (let* ((c++-keywords -; ("break" "continue" "do" "else" "for" "if" "return" "switch" "while" -; "asm" "catch" "delete" "new" "operator" "sizeof" "this" "throw" "try" -; ;; Eric Hopper says these are new. -; "static_cast" "dynamic_cast" "const_cast" "reinterpret_cast") - (concat "asm\\|break\\|c\\(atch\\|on\\(st_cast\\|tinue\\)\\)\\|" - "d\\(elete\\|o\\|ynamic_cast\\)\\|else\\|for\\|if\\|new\\|" - "operator\\|re\\(interpret_cast\\|turn\\)\\|" - "s\\(izeof\\|tatic_cast\\|" - "witch\\)\\|t\\(h\\(is\\|row\\)\\|ry\\)\\|while")) + (eval-when-compile + (regexp-opt + '("break" "continue" "do" "else" "for" "if" "return" "switch" + "while" "asm" "catch" "delete" "new" "sizeof" "this" "throw" "try" + "typeid" + ;; Branko Cibej says this is new. + "export" + ;; Mark Mitchell says these are new. + "mutable" "explicit" + ;; Alain Picard suggests treating these + ;; as keywords not types. + "typedef" "template" + "extern" "auto" "register" "const" "volatile" "static" + "inline" "friend" "virtual")))) (c++-operators - (mapconcat 'identity - (mapcar 'regexp-quote - ;; Taken from Stroustrup, minus keywords otherwise fontified. - (sort '("+" "-" "*" "/" "%" "^" "&" "|" "~" "!" "=" "<" ">" - "+=" "-=" "*=" "/=" "%=" "^=" "&=" "|=" "<<" ">>" - ">>=" "<<=" "==" "!=" "<=" ">=" "&&" "||" "++" "--" - "->*" "," "->" "[]" "()") - #'(lambda (a b) (> (length a) (length b))))) - "\\|")) - (c++-type-types -; ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum" -; "signed" "unsigned" "short" "long" "int" "char" "float" "double" -; "void" "volatile" "const" "inline" "friend" "bool" -; "virtual" "complex" "template" -; ;; Eric Hopper says these are new. -; "namespace" "using") + (eval-when-compile + (regexp-opt + ;; Taken from Stroustrup, minus keywords otherwise fontified. + '("+" "-" "*" "/" "%" "^" "&" "|" "~" "!" "=" "<" ">" "+=" "-=" + "*=" "/=" "%=" "^=" "&=" "|=" "<<" ">>" ">>=" "<<=" "==" "!=" + "<=" ">=" "&&" "||" "++" "--" "->*" "," "->" "[]" "()")))) + (c++-type-specs + (eval-when-compile + (regexp-opt + '("class" "public" "private" "protected" "typename" + "struct" "union" "enum" "namespace" "using" + ;; Eric Hopper says these are new. + "static_cast" "dynamic_cast" "const_cast" "reinterpret_cast") t))) + (c++-type-specs-depth + (regexp-opt-depth c++-type-specs)) + (c++-type-names `(mapconcat 'identity - (cons - (,@ (concat "auto\\|bool\\|c\\(har\\|o\\(mplex\\|nst\\)\\)\\|" - "double\\|e\\(num\\|xtern\\)\\|f\\(loat\\|riend\\)\\|" - "in\\(line\\|t\\)\\|long\\|namespace\\|register\\|" - "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|" - "t\\(emplate\\|ypedef\\)\\|" - "u\\(n\\(ion\\|signed\\)\\|sing\\)\\|" - "v\\(irtual\\|o\\(id\\|latile\\)\\)")) ; 12 ()s deep. + (cons + ,(eval-when-compile + (regexp-opt + '("signed" "unsigned" "short" "long" + "int" "char" "float" "double" "void" + "bool" "complex"))) c++-font-lock-extra-types) "\\|")) + (c++-type-names-depth `(regexp-opt-depth ,c++-type-names)) ;; ;; A brave attempt to match templates following a type and/or match ;; class membership. See and sync the above function ;; `font-lock-match-c++-style-declaration-item-and-skip-to-next'. - (c++-type-suffix (concat "\\(<\\(\\sw+\\)[ \t*&]*>\\)?" - "\\([ \t]*::[ \t*~]*\\(\\sw+\\)\\)?")) + (c++-type-suffix (concat "\\([ \t]*<\\([^>\n]+\\)[ \t*&]*>\\)?" + "\\([ \t]*::[ \t*~]*\\(\\sw+\\)\\)*")) + (c++-type-suffix-depth (regexp-opt-depth c++-type-suffix)) ;; If the string is a type, it may be followed by the cruft above. (c++-type-spec (concat "\\(\\sw+\\)\\>" c++-type-suffix)) + (c++-type-spec-depth (regexp-opt-depth c++-type-spec)) ;; ;; Parenthesis depth of user-defined types not forgetting their cruft. - (c++-type-depth `(font-lock-keyword-depth - (concat (,@ c++-type-types) (,@ c++-type-suffix)))) + (c++-type-depth `(regexp-opt-depth + (concat ,c++-type-names ,c++-type-suffix))) ) (setq c++-font-lock-keywords-1 (append @@ -2193,22 +2507,12 @@ See also `c++-font-lock-extra-types'.") (cdr c-font-lock-keywords-1) (list ;; - ;; Class names etc. - (list (concat "\\<\\(class\\|public\\|private\\|protected\\)\\>[ \t]*" - "\\(" c++-type-spec "\\)?") - '(1 font-lock-type-face) - '(3 (if (match-beginning 6) - font-lock-type-face - font-lock-function-name-face) nil t) - '(5 font-lock-function-name-face nil t) - '(7 font-lock-function-name-face nil t)) - ;; ;; Fontify function name definitions, possibly incorporating class names. (list (concat "^" c++-type-spec "[ \t]*(") '(1 (if (or (match-beginning 2) (match-beginning 4)) font-lock-type-face font-lock-function-name-face)) - '(3 font-lock-function-name-face nil t) + '(3 font-lock-type-face nil t) '(5 font-lock-function-name-face nil t)) ))) @@ -2218,7 +2522,7 @@ See also `c++-font-lock-extra-types'.") ;; ;; The list `c-font-lock-keywords-2' for C++ plus operator overloading. `(eval . - (cons (concat "\\<\\(" (,@ c++-type-types) "\\)\\>") + (cons (concat "\\<\\(" ,c++-type-names "\\)\\>") 'font-lock-type-face)) ;; ;; Fontify operator overloading. @@ -2227,17 +2531,30 @@ See also `c++-font-lock-extra-types'.") '(2 font-lock-builtin-face nil t)) ;; ;; Fontify case/goto keywords and targets, and case default/goto tags. - '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?" - (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) + '("\\<\\(case\\|goto\\)\\>" + (1 font-lock-keyword-face) + ("\\(-[0-9]+\\|\\sw+\\)[ \t]*\\(::\\)?" + ;; Return limit of search. + (save-excursion + (while (progn + (skip-chars-forward "^:\n") + (looking-at "::")) + (forward-char 2)) + (point)) + nil + (1 (if (match-beginning 2) + font-lock-type-face + font-lock-constant-face) nil t))) + ;; This must come after the one for keywords and targets. '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:\\($\\|[^:]\\)" (beginning-of-line) (end-of-line) - (1 font-lock-reference-face))) + (1 font-lock-constant-face))) ;; ;; Fontify other builtin keywords. - (cons (concat "\\<\\(" c++-keywords "\\)\\>") 'font-lock-keyword-face) + (concat "\\<\\(" c++-keywords "\\|" c++-type-specs "\\)\\>") ;; ;; Eric Hopper says `true' and `false' are new. - '("\\<\\(false\\|true\\)\\>" . font-lock-reference-face) + '("\\<\\(false\\|true\\)\\>" . font-lock-constant-face) ))) (setq c++-font-lock-keywords-3 @@ -2248,33 +2565,63 @@ See also `c++-font-lock-extra-types'.") ;; ;; Fontify all storage classes and type specifiers, plus their items. `(eval . - (list (concat "\\<\\(" (,@ c++-type-types) "\\)\\>" (,@ c++-type-suffix) - "\\([ \t*&]+" (,@ c++-type-spec) "\\)*") + (list (concat "\\<\\(" ,c++-type-names "\\)\\>" ,c++-type-suffix + "\\([ \t*&]+" ,c++-type-spec "\\)*") + ;; The name of any template type. + (list (+ ,c++-type-names-depth 3) 'font-lock-type-face nil t) ;; Fontify each declaration item. (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next ;; Start with point after all type specifiers. (list 'goto-char (list 'or (list 'match-beginning - (+ (,@ c++-type-depth) 2)) + (+ ,c++-type-depth 2)) '(match-end 1))) ;; Finish with point after first type specifier. '(goto-char (match-end 1)) ;; Fontify as a variable or function name. '(1 (cond ((or (match-beginning 2) (match-beginning 4)) font-lock-type-face) - ((match-beginning 6) font-lock-function-name-face) - (t font-lock-variable-name-face))) - '(3 font-lock-function-name-face nil t) + ((and (match-beginning 6) (c-at-toplevel-p)) + font-lock-function-name-face) + (t + font-lock-variable-name-face))) + '(3 font-lock-type-face nil t) '(5 (if (match-beginning 6) font-lock-function-name-face font-lock-variable-name-face) nil t)))) ;; + ;; Fontify all storage specs and types, plus their items. + `(eval . + (list (concat "\\<" ,c++-type-specs "\\>" ,c++-type-suffix + "[ \t]*\\(" ,c++-type-spec "\\)?") + ;; The name of any template type. + (list ,(+ c++-type-specs-depth 2) 'font-lock-type-face nil t) + ;; The name of any type. + (list (+ ,c++-type-specs-depth ,c++-type-suffix-depth 2) + 'font-lock-type-face nil t) + ;; Fontify each declaration item. + (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next + ;; Start with point after all type specifiers. + nil + ;; Finish with point after first type specifier. + nil + ;; Fontify as a variable or function name. + '(1 (cond ((or (match-beginning 2) (match-beginning 4)) + font-lock-type-face) + ((and (match-beginning 6) (c-at-toplevel-p)) + font-lock-function-name-face) + (t + font-lock-variable-name-face))) + '(3 font-lock-type-face nil t) + '(5 (if (match-beginning 6) + font-lock-function-name-face + font-lock-variable-name-face) nil t)) + )) + ;; ;; Fontify structures, or typedef names, plus their items. '("\\(}\\)[ \t*]*\\sw" (font-lock-match-c++-style-declaration-item-and-skip-to-next (goto-char (match-end 1)) nil - (1 (if (match-beginning 6) - font-lock-function-name-face - font-lock-variable-name-face)))) + (1 font-lock-type-face))) ;; ;; Fontify anything at beginning of line as a declaration or definition. (list (concat "^\\(" c++-type-spec "[ \t*&]*\\)+") @@ -2285,10 +2632,14 @@ See also `c++-font-lock-extra-types'.") font-lock-type-face) ((match-beginning 6) font-lock-function-name-face) (t font-lock-variable-name-face))) - (3 font-lock-function-name-face nil t) + (3 font-lock-type-face nil t) (5 (if (match-beginning 6) font-lock-function-name-face font-lock-variable-name-face) nil t))) + ;; + ;; Fontify constructors and destructors inside class declarations. + '(font-lock-match-c++-structor-declaration + (3 font-lock-function-name-face t)) ))) ) @@ -2312,26 +2663,30 @@ See also `objc-font-lock-extra-types'.") ;; Regexps written with help from Stephen Peters and ;; Jacques Duthen Prestataire . (let* ((objc-keywords -; '("break" "continue" "do" "else" "for" "if" "return" "switch" "while" -; "sizeof" "self" "super") - (concat "break\\|continue\\|do\\|else\\|for\\|if\\|return\\|" - "s\\(elf\\|izeof\\|uper\\|witch\\)\\|while")) - (objc-type-types + (eval-when-compile + (regexp-opt '("break" "continue" "do" "else" "for" "if" "return" + "switch" "while" "sizeof" "self" "super" + "typedef" "auto" "extern" "static" + "volatile" "const")))) + (objc-type-specs + (eval-when-compile + (regexp-opt + '("register" "struct" "union" "enum" + "oneway" "in" "out" "inout" "bycopy" "byref") t))) + (objc-type-specs-depth + (regexp-opt-depth objc-type-specs)) + (objc-type-names `(mapconcat 'identity (cons -; '("auto" "extern" "register" "static" "typedef" "struct" "union" -; "enum" "signed" "unsigned" "short" "long" "int" "char" -; "float" "double" "void" "volatile" "const" -; "id" "oneway" "in" "out" "inout" "bycopy" "byref") - (,@ (concat "auto\\|by\\(copy\\|ref\\)\\|c\\(har\\|onst\\)\\|" - "double\\|e\\(num\\|xtern\\)\\|float\\|" - "i\\([dn]\\|n\\(out\\|t\\)\\)\\|long\\|" - "o\\(neway\\|ut\\)\\|register\\|s\\(hort\\|igned\\|" - "t\\(atic\\|ruct\\)\\)\\|typedef\\|" - "un\\(ion\\|signed\\)\\|vo\\(id\\|latile\\)")) + ,(eval-when-compile + (regexp-opt + '("signed" "unsigned" "short" "long" + "int" "char" "float" "double" "void" + "id"))) objc-font-lock-extra-types) "\\|")) - (objc-type-depth `(font-lock-keyword-depth (,@ objc-type-types))) + (objc-type-names-depth + `(regexp-opt-depth ,objc-type-names)) ) (setq objc-font-lock-keywords-1 (append @@ -2343,26 +2698,23 @@ See also `objc-font-lock-extra-types'.") ;; Fontify compiler directives. '("@\\(\\sw+\\)\\>" (1 font-lock-keyword-face) - ("\\=[ \t:<(,]*\\(\\sw+\\)" nil nil - (1 font-lock-function-name-face))) + ("\\=[ \t:<,]*\\(\\sw+\\)" nil nil + (1 font-lock-type-face))) ;; ;; Fontify method names and arguments. Oh Lordy! ;; First, on the same line as the function declaration. - '("^[+-][ \t]*\\(PRIVATE\\)?[ \t]*\\((\\([^)\n]+\\))\\)?[ \t]*\\(\\sw+\\)" - (1 font-lock-type-face nil t) - (3 font-lock-type-face nil t) - (4 font-lock-function-name-face) - ("\\=[ \t]*\\(\\sw+\\)?:[ \t]*\\((\\([^)\n]+\\))\\)?[ \t]*\\(\\sw+\\)" + '("^[+-][ \t]*\\(PRIVATE\\>\\)?[ \t]*\\(([^)\n]+)\\)?[ \t]*\\(\\sw+\\)" + (1 font-lock-keyword-face nil t) + (3 font-lock-function-name-face) + ("\\=[ \t]*\\(\\sw+\\)?:[ \t]*\\(([^)\n]+)\\)?[ \t]*\\(\\sw+\\)" nil nil (1 font-lock-function-name-face nil t) - (3 font-lock-type-face nil t) - (4 font-lock-variable-name-face))) + (3 font-lock-variable-name-face))) ;; Second, on lines following the function declaration. - '(":" ("^[ \t]*\\(\\sw+\\)?:[ \t]*\\((\\([^)\n]+\\))\\)?[ \t]*\\(\\sw+\\)" + '(":" ("^[ \t]*\\(\\sw+\\)?:[ \t]*\\(([^)\n]+)\\)?[ \t]*\\(\\sw+\\)" (beginning-of-line) (end-of-line) (1 font-lock-function-name-face nil t) - (3 font-lock-type-face nil t) - (4 font-lock-variable-name-face))) + (3 font-lock-variable-name-face))) ))) (setq objc-font-lock-keywords-2 @@ -2373,22 +2725,23 @@ See also `objc-font-lock-extra-types'.") ;; ;; Fontify all type specifiers. `(eval . - (cons (concat "\\<\\(" (,@ objc-type-types) "\\)\\>") + (cons (concat "\\<\\(" ,objc-type-names "\\)\\>") 'font-lock-type-face)) ;; ;; Fontify all builtin keywords (except case, default and goto; see below). - (concat "\\<\\(" objc-keywords "\\)\\>") + (concat "\\<\\(" objc-keywords "\\|" objc-type-specs "\\)\\>") ;; ;; Fontify case/goto keywords and targets, and case default/goto tags. '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?" - (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) + (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) ;; Fontify tags iff sole statement on line, otherwise we detect selectors. + ;; This must come after the one for keywords and targets. '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$" (beginning-of-line) (end-of-line) - (1 font-lock-reference-face))) + (1 font-lock-constant-face))) ;; ;; Fontify null object pointers. - '("\\<\\(Nil\\|nil\\)\\>" 1 font-lock-reference-face) + '("\\<[Nn]il\\>" . font-lock-constant-face) ))) (setq objc-font-lock-keywords-3 @@ -2400,14 +2753,15 @@ See also `objc-font-lock-extra-types'.") ;; ;; Fontify all storage classes and type specifiers, plus their items. `(eval . - (list (concat "\\<\\(" (,@ objc-type-types) "\\)\\>" + (list (concat "\\<\\(" ,objc-type-names "\\)\\>" "\\([ \t*&]+\\sw+\\>\\)*") ;; Fontify each declaration item. (list 'font-lock-match-c-style-declaration-item-and-skip-to-next ;; Start with point after all type specifiers. - (list 'goto-char (list 'or (list 'match-beginning - (+ (,@ objc-type-depth) 2)) - '(match-end 1))) + (list 'goto-char + (list 'or (list 'match-beginning + (+ ,objc-type-names-depth 2)) + '(match-end 1))) ;; Finish with point after first type specifier. '(goto-char (match-end 1)) ;; Fontify as a variable or function name. @@ -2415,13 +2769,26 @@ See also `objc-font-lock-extra-types'.") font-lock-function-name-face font-lock-variable-name-face))))) ;; + ;; Fontify all storage specs and types, plus their items. + `(eval . + (list (concat "\\<\\(" ,objc-type-specs "[ \t]*\\)+\\>" + "[ \t]*\\(\\sw+\\)?") + ;; The name of any type. + (list ,(+ objc-type-specs-depth 2) 'font-lock-type-face nil t) + ;; Fontify each declaration item. + (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next + nil nil + ;; Fontify as a variable or function name. + '(1 (if (match-beginning 2) + font-lock-function-name-face + font-lock-variable-name-face))) + )) + ;; ;; Fontify structures, or typedef names, plus their items. '("\\(}\\)[ \t*]*\\sw" (font-lock-match-c-style-declaration-item-and-skip-to-next (goto-char (match-end 1)) nil - (1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face)))) + (1 font-lock-type-face))) ;; ;; Fontify anything at beginning of line as a declaration or definition. '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*" @@ -2451,92 +2818,93 @@ See also `java-font-lock-extra-types'.") "Gaudy level highlighting for Java mode. See also `java-font-lock-extra-types'.") -;; Regexps written with help from Fred White and -;; Anders Lindgren . +;; Regexps written with help from Fred White , +;; Anders Lindgren and Carl Manning . (let* ((java-keywords - (concat "\\<\\(" -; '("catch" "do" "else" "super" "this" "finally" "for" "if" -;; ;; Anders Lindgren says these have gone. -;; "cast" "byvalue" "future" "generic" "operator" "var" -;; "inner" "outer" "rest" -; "interface" "return" "switch" "throw" "try" "while") - "catch\\|do\\|else\\|f\\(inally\\|or\\)\\|" - "i\\(f\\|nterface\\)\\|return\\|s\\(uper\\|witch\\)\\|" - "t\\(h\\(is\\|row\\)\\|ry\\)\\|while" - "\\)\\>")) + (eval-when-compile + (regexp-opt + '("catch" "do" "else" "super" "this" "finally" "for" "if" + ;; Anders Lindgren says these have gone. + ;; "cast" "byvalue" "future" "generic" "operator" "var" + ;; "inner" "outer" "rest" + "implements" "extends" "throws" "instanceof" "new" + "interface" "return" "switch" "throw" "try" "while")))) ;; - ;; These are immediately followed by an object name. - (java-minor-types - (mapconcat 'identity - '("boolean" "char" "byte" "short" "int" "long" - "float" "double" "void") - "\\|")) + ;; Classes immediately followed by an object name. + (java-type-names + `(mapconcat 'identity + (cons + ,(eval-when-compile + (regexp-opt '("boolean" "char" "byte" "short" "int" "long" + "float" "double" "void"))) + java-font-lock-extra-types) + "\\|")) + (java-type-names-depth `(regexp-opt-depth ,java-type-names)) ;; ;; These are eventually followed by an object name. - (java-major-types -; '("abstract" "const" "final" "synchronized" "transient" "static" -;; ;; Anders Lindgren says this has gone. -;; "threadsafe" -; "volatile" "public" "private" "protected" "native") - (concat "abstract\\|const\\|final\\|native\\|" - "p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|" - "s\\(tatic\\|ynchronized\\)\\|transient\\|volatile")) - ;; - ;; Random types immediately followed by an object name. - (java-other-types - '(mapconcat 'identity (cons "\\sw+\\.\\sw+" java-font-lock-extra-types) - "\\|")) - (java-other-depth `(font-lock-keyword-depth (,@ java-other-types))) - ) + (java-type-specs + (eval-when-compile + (regexp-opt + '("abstract" "const" "final" "synchronized" "transient" "static" + ;; Anders Lindgren says this has gone. + ;; "threadsafe" + "volatile" "public" "private" "protected" "native" + ;; Carl Manning says this is new. + "strictfp")))) + ) (setq java-font-lock-keywords-1 (list ;; ;; Fontify class names. '("\\<\\(class\\)\\>[ \t]*\\(\\sw+\\)?" - (1 font-lock-type-face) (2 font-lock-function-name-face nil t)) + (1 font-lock-keyword-face) (2 font-lock-type-face nil t)) ;; ;; Fontify package names in import directives. '("\\<\\(import\\|package\\)\\>[ \t]*\\(\\sw+\\)?" - (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t) + ("\\=\\.\\(\\*\\|\\sw+\\)" nil nil + (1 font-lock-constant-face nil t))) )) (setq java-font-lock-keywords-2 (append java-font-lock-keywords-1 (list ;; - ;; Fontify all builtin type specifiers. - (cons (concat "\\<\\(" java-minor-types "\\|" java-major-types "\\)\\>") - 'font-lock-type-face) + ;; Fontify class names. + `(eval . + (cons (concat "\\<\\(" ,java-type-names "\\)\\>[^.]") + '(1 font-lock-type-face))) ;; ;; Fontify all builtin keywords (except below). - (concat "\\<\\(" java-keywords "\\)\\>") + (concat "\\<\\(" java-keywords "\\|" java-type-specs "\\)\\>") ;; ;; Fontify keywords and targets, and case default/goto tags. (list "\\<\\(break\\|case\\|continue\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?" - '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t)) - '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:" + '(1 font-lock-keyword-face) '(2 font-lock-constant-face nil t)) + ;; This must come after the one for keywords and targets. + '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$" (beginning-of-line) (end-of-line) - (1 font-lock-reference-face))) - ;; - ;; Fontify keywords and types; the first can be followed by a type list. - (list (concat "\\<\\(" - "implements\\|throws\\|" - "\\(extends\\|instanceof\\|new\\)" - "\\)\\>[ \t]*\\(\\sw+\\)?") - '(1 font-lock-keyword-face) '(3 font-lock-type-face nil t) - '("\\=[ \t]*,[ \t]*\\(\\sw+\\)" - (if (match-beginning 2) (goto-char (match-end 2))) nil - (1 font-lock-type-face))) + (1 font-lock-constant-face))) ;; ;; Fontify all constants. - '("\\<\\(false\\|null\\|true\\)\\>" . font-lock-reference-face) + '("\\<\\(false\\|null\\|true\\)\\>" . font-lock-constant-face) ;; ;; Javadoc tags within comments. - '("@\\(author\\|exception\\|return\\|see\\|version\\)\\>" - (1 font-lock-reference-face prepend)) + (list + (concat "@\\(" + "author\\|deprecated\\|exception" + "\\|link\\|return\\|see\\|serial\\|serialData\\|serialField" + "\\|since\\|throws" + "\\|version" + "\\)\\>") + '(1 font-lock-constant-face prepend)) '("@\\(param\\)\\>[ \t]*\\(\\sw+\\)?" - (1 font-lock-reference-face prepend) + (1 font-lock-constant-face prepend) (2 font-lock-variable-name-face prepend t)) + '("@\\(exception\\|throws\\)\\>[ \t]*\\(\\S-+\\)?" + (1 font-lock-constant-face prepend) + (2 font-lock-type-face prepend t)) ))) (setq java-font-lock-keywords-3 @@ -2546,50 +2914,25 @@ See also `java-font-lock-extra-types'.") ;; We still have to fontify type specifiers individually, as Java is hairy. (list ;; - ;; Fontify random types in casts. - `(eval . - (list (concat "(\\(" (,@ java-other-types) "\\))" - "[ \t]*\\(\\sw\\|[\"\(]\\)") - ;; Fontify the type name. - '(1 font-lock-type-face))) - ;; ;; Fontify random types immediately followed by an item or items. `(eval . - (list (concat "\\<\\(" (,@ java-other-types) "\\)\\>" - "\\([ \t]*\\[[ \t]*\\]\\)*" - "[ \t]*\\sw") - ;; Fontify the type name. - '(1 font-lock-type-face))) - `(eval . - (list (concat "\\<\\(" (,@ java-other-types) "\\)\\>" + (list (concat "\\<\\(" ,java-type-names "\\)\\>" "\\([ \t]*\\[[ \t]*\\]\\)*" "\\([ \t]*\\sw\\)") ;; Fontify each declaration item. (list 'font-lock-match-c-style-declaration-item-and-skip-to-next ;; Start and finish with point after the type specifier. (list 'goto-char (list 'match-beginning - (+ (,@ java-other-depth) 3))) + (+ ,java-type-names-depth 3))) (list 'goto-char (list 'match-beginning - (+ (,@ java-other-depth) 3))) + (+ ,java-type-names-depth 3))) ;; Fontify as a variable or function name. '(1 (if (match-beginning 2) font-lock-function-name-face font-lock-variable-name-face))))) ;; - ;; Fontify those that are immediately followed by an item or items. - (list (concat "\\<\\(" java-minor-types "\\)\\>" - "\\([ \t]*\\[[ \t]*\\]\\)*") - ;; Fontify each declaration item. - '(font-lock-match-c-style-declaration-item-and-skip-to-next - ;; Start and finish with point after the type specifier. - nil (goto-char (match-end 0)) - ;; Fontify as a variable or function name. - (1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face)))) - ;; ;; Fontify those that are eventually followed by an item or items. - (list (concat "\\<\\(" java-major-types "\\)\\>" + (list (concat "\\<\\(" java-type-specs "\\)\\>" "\\([ \t]+\\sw+\\>" "\\([ \t]*\\[[ \t]*\\]\\)*" "\\)*") @@ -2610,13 +2953,9 @@ See also `java-font-lock-extra-types'.") "Default expressions to highlight in Java mode. See also `java-font-lock-extra-types'.") -;; Install ourselves: - -(unless (assq 'font-lock-mode minor-mode-alist) - (push '(font-lock-mode " Font") minor-mode-alist)) - ;; Provide ourselves: (provide 'font-lock) +(require 'jit-lock) ;;; font-lock.el ends here