diff lisp/font-lock.el @ 17055:f0f8005780cc

1. If PRE-MATCH-FORM returns a suitable number, use that as a value for LIMIT. 2. Commented out menu code.
author Simon Marshall <simon@gnu.org>
date Fri, 21 Feb 1997 09:36:18 +0000
parents 70e9b1d69d0d
children a2d3b455c6f4
line wrap: on
line diff
--- a/lisp/font-lock.el	Thu Feb 20 16:11:48 1997 +0000
+++ b/lisp/font-lock.el	Fri Feb 21 09:36:18 1997 +0000
@@ -50,6 +50,27 @@
 ;; also the variable `font-lock-maximum-size'.  Support modes for Font Lock
 ;; mode can be used to speed up Font Lock mode.  See `font-lock-support-mode'.
 
+;;; How Font Lock mode fontifies:
+
+;; When Font Lock mode is turned on in a buffer, it (a) fontifies the entire
+;; buffer and (b) installs one of its fontification functions on one of the
+;; hook variables that are run by Emacs after every buffer change (i.e., an
+;; insertion or deletion).  Fontification means the replacement of `face' text
+;; properties in a given region; Emacs displays text with these `face' text
+;; 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.
+
 ;;; How Font Lock mode supports modes or is supported by modes:
 
 ;; Modes that support Font Lock mode do so by defining one or more variables
@@ -63,6 +84,9 @@
 ;; (a); (b) is used where it is not clear which package library should contain
 ;; the pattern definitions.)  Font Lock mode chooses which variable to use for
 ;; fontification based on `font-lock-maximum-decoration'.
+;;
+;; Font Lock mode fontification behaviour can be modified in a number of ways.
+;; See the below comments and the comments distributed throughout this file.
 
 ;;; Constructing patterns:
 
@@ -71,7 +95,7 @@
 ;; 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 simon.
+;; archive.cis.ohio-state.edu for this and other functions not just by sm.
 
 ;;; Adding patterns for modes that already support Font Lock:
 
@@ -275,8 +299,7 @@
 
  (MATCHER PRE-MATCH-FORM POST-MATCH-FORM MATCH-HIGHLIGHT ...)
 
-Where MATCHER is as for MATCH-HIGHLIGHT with one exception.  The limit of the
-search is currently guaranteed to be (no greater than) the end of the line.
+Where MATCHER is as for MATCH-HIGHLIGHT 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,
@@ -295,6 +318,13 @@
  searching for subsequent instance of \"anchor\" resumes from where searching
  for \"item\" concluded.)
 
+The above-mentioned exception is as follows.  The limit of the MATCHER search
+defaults to the end of the line after PRE-MATCH-FORM is evaluated.
+However, if PRE-MATCH-FORM returns a position greater than the position after
+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.
 
@@ -499,10 +529,6 @@
   ;; We don't do this at the top-level as we only use non-autoloaded macros.
   (require 'cl)
   ;;
-  ;; Shut the byte-compiler up.
-  (require 'fast-lock)
-  (require 'lazy-lock)
-  ;;
   ;; Borrowed from lazy-lock.el.
   ;; We use this to preserve or protect things when modifying text properties.
   (defmacro save-buffer-state (varlist &rest body)
@@ -553,6 +579,10 @@
  (setq font-lock-support-mode 'lazy-lock-mode)
  (setq font-lock-maximum-decoration t)
 
+To add your own highlighting for some major mode, and modify the highlighting
+selected automatically via the variable `font-lock-maximum-decoration', you can
+use `font-lock-add-keywords'.
+
 To fontify a buffer, without turning on Font Lock mode and regardless of buffer
 size, you can use \\[font-lock-fontify-buffer].
 
@@ -560,10 +590,6 @@
 lines around point), perhaps because modification on the current line caused
 syntactic change on other lines, you can use \\[font-lock-fontify-block].
 
-The default Font Lock mode highlighting are normally selected via the variable
-`font-lock-maximum-decoration'.  You can add your own highlighting for some
-mode, by calling `font-lock-add-keywords'.
-
 The default Font Lock mode faces and their attributes are defined in the
 variable `font-lock-face-attributes', and Font Lock mode default settings in
 the variable `font-lock-defaults-alist'.  You can set your own default settings
@@ -605,8 +631,8 @@
 (defun turn-on-font-lock ()
   "Turn on Font Lock mode conditionally.
 Turn on only if the terminal can display it."
-  (when window-system
-    (font-lock-mode t)))
+  (when (and (not font-lock-mode) window-system)
+    (font-lock-mode)))
 
 ;;;###autoload
 (defun font-lock-add-keywords (major-mode keywords &optional append)
@@ -738,7 +764,7 @@
 (defun font-lock-change-major-mode ()
   ;; Turn off Font Lock mode if it's on.
   (when font-lock-mode
-    (font-lock-mode nil))
+    (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
@@ -826,6 +852,45 @@
 
 ;; Fontification functions.
 
+;; Rather than the function, e.g., `font-lock-fontify-region' containing the
+;; code to fontify a region, the function runs the function whose name is the
+;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,
+;; the value of this variable is, e.g., `font-lock-default-fontify-region'
+;; which does contain the code to fontify a region.  However, the value of the
+;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
+;; do anything.  The indirection of the fontification functions gives major
+;; modes the capability of modifying the way font-lock.el fontifies.  Major
+;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
+;; via the variable `font-lock-defaults'.
+;;
+;; For example, Rmail mode sets the variable `font-lock-defaults' so that
+;; font-lock.el uses its own function for buffer fontification.  This function
+;; makes fontification be on a message-by-message basis and so visiting an
+;; RMAIL file is much faster.  A clever implementation of the function might
+;; fontify the headers differently than the message body.  (It should, and
+;; correspondingly for Mail mode, but I can't be bothered to do the work.  Can
+;; you?)  This hints at a more interesting use...
+;;
+;; Languages that contain text normally contained in different major modes
+;; could define their own fontification functions that treat text differently
+;; depending on its context.  For example, Perl mode could arrange that here
+;; docs are fontified differently than Perl code.  Or Yacc mode could fontify
+;; rules one way and C code another.  Neat!
+;;
+;; A further reason to use the fontification indirection feature is when the
+;; default syntactual fontification, or the default fontification in general,
+;; is not flexible enough for a particular major mode.  For example, perhaps
+;; comments are just too hairy for `font-lock-fontify-syntactically-region' and
+;; `font-lock-comment-start-regexp' to cope with.  You need to write your own
+;; version of that function, e.g., `hairy-fontify-syntactically-region', and
+;; make your own version of `hairy-fontify-region' call it before calling
+;; `font-lock-fontify-keywords-region' for the normal regexp fontification
+;; pass.  And Hairy mode would set `font-lock-defaults' so that font-lock.el
+;; would call your region fontification function instead of its own.  For
+;; example, TeX modes could fontify {\foo ...} and \bar{...} etc. multi-line
+;; directives correctly and cleanly.  (It is the same problem as fontifying
+;; multi-line strings and comments; regexps are not appropriate for the job.)
+
 ;;;###autoload
 (defun font-lock-fontify-buffer ()
   "Fontify the current buffer the way `font-lock-mode' would."
@@ -846,9 +911,11 @@
   (let ((verbose (if (numberp font-lock-verbose)
 		     (> (buffer-size) font-lock-verbose)
 		   font-lock-verbose)))
-    (if verbose (message "Fontifying %s..." (buffer-name)))
+    (when verbose
+      (message "Fontifying %s..." (buffer-name)))
     ;; Make sure we have the right `font-lock-keywords' etc.
-    (if (not font-lock-mode) (font-lock-set-defaults))
+    (unless font-lock-mode
+      (font-lock-set-defaults))
     ;; Make sure we fontify etc. in the whole buffer.
     (save-restriction
       (widen)
@@ -860,10 +927,14 @@
 	      (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")))))
 
 (defun font-lock-default-unfontify-buffer ()
+  ;; Make sure we unfontify etc. in the whole buffer.
   (save-restriction
     (widen)
     (font-lock-unfontify-region (point-min) (point-max))
@@ -1154,12 +1225,15 @@
 
 (defsubst font-lock-fontify-anchored-keywords (keywords limit)
   "Fontify according to KEYWORDS until LIMIT.
-KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords'."
-  (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights)
-    ;; Until we come up with a cleaner solution, we make LIMIT the end of line.
-    (save-excursion (end-of-line) (setq limit (min limit (point))))
-    ;; Evaluate PRE-MATCH-FORM.
-    (eval (nth 1 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
+	;; 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))))
     (save-match-data
       ;; Find an occurrence of `matcher' before `limit'.
       (while (if (stringp matcher)
@@ -1539,12 +1613,113 @@
 	(set-face-underline-p face (nth 5 face-attributes)))
     (set face face)))
 
+;;; Menu support.
+
+;; This section of code is commented out because Emacs does not have real menu
+;; buttons.  (We can mimic them by putting "( ) " or "(X) " at the beginning of
+;; the menu entry text, but with Xt it looks both ugly and embarrassingly
+;; amateur.)  If/When Emacs gets real menus buttons, put in menu-bar.el after
+;; the entry for "Text Properties" something like:
+;;
+;; (define-key menu-bar-edit-menu [font-lock]
+;;   '("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
+;; buttons and when they are on or off needs tweaking.  I have assumed that the
+;; mechanism is via `menu-toggle' and `menu-selected' symbol properties.  sm.
+
+;;;;###autoload
+;(progn
+;  ;; Make the Font Lock menu.
+;  (defvar font-lock-menu (make-sparse-keymap "Syntax Highlighting"))
+;  ;; Add the menu items in reverse order.
+;  (define-key font-lock-menu [fontify-less]
+;    '("Less In Current Buffer" . font-lock-fontify-less))
+;  (define-key font-lock-menu [fontify-more]
+;    '("More In Current Buffer" . font-lock-fontify-more))
+;  (define-key font-lock-menu [font-lock-sep]
+;    '("--"))
+;  (define-key font-lock-menu [font-lock-mode]
+;    '("In Current Buffer" . font-lock-mode))
+;  (define-key font-lock-menu [global-font-lock-mode]
+;    '("In All Buffers" . global-font-lock-mode)))
+;
+;;;;###autoload
+;(progn
+;  ;; We put the appropriate `menu-enable' etc. symbol property values on when
+;  ;; font-lock.el is loaded, so we don't need to autoload the three variables.
+;  (put 'global-font-lock-mode 'menu-toggle t)
+;  (put 'font-lock-mode 'menu-toggle t)
+;  (put 'font-lock-fontify-more 'menu-enable '(identity))
+;  (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 '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))
+;
+;(defvar font-lock-fontify-level nil)	; For less/more fontification.
+;
+;(defun font-lock-fontify-level (level)
+;  (let ((font-lock-maximum-decoration level))
+;    (when font-lock-mode
+;      (font-lock-mode))
+;    (font-lock-mode)
+;    (when font-lock-verbose
+;      (message "Fontifying %s... level %d" (buffer-name) level))))
+;
+;(defun font-lock-fontify-less ()
+;  "Fontify the current buffer with less decoration.
+;See `font-lock-maximum-decoration'."
+;  (interactive)
+;  ;; Check in case we get called interactively.
+;  (if (nth 1 font-lock-fontify-level)
+;      (font-lock-fontify-level (1- (car font-lock-fontify-level)))
+;    (error "No less decoration")))
+;
+;(defun font-lock-fontify-more ()
+;  "Fontify the current buffer with more decoration.
+;See `font-lock-maximum-decoration'."
+;  (interactive)
+;  ;; Check in case we get called interactively.
+;  (if (nth 2 font-lock-fontify-level)
+;      (font-lock-fontify-level (1+ (car font-lock-fontify-level)))
+;    (error "No more decoration")))
+;
+;;; This should be called by `font-lock-set-defaults'.
+;(defun font-lock-set-menu ()
+;  ;; Activate less/more fontification entries if there are multiple levels for
+;  ;; the current buffer.  Sets `font-lock-fontify-level' to be of the form
+;  ;; (CURRENT-LEVEL IS-LOWER-LEVEL-P IS-HIGHER-LEVEL-P) for menu activation.
+;  (let ((keywords (or (nth 0 font-lock-defaults)
+;		      (nth 1 (assq major-mode font-lock-defaults-alist))))
+;	(level (font-lock-value-in-major-mode font-lock-maximum-decoration)))
+;    (make-local-variable 'font-lock-fontify-level)
+;    (if (or (symbolp keywords) (= (length keywords) 1))
+;	(font-lock-unset-menu)
+;      (cond ((eq level t)
+;	     (setq level (1- (length keywords))))
+;	    ((or (null level) (zerop level))
+;	     ;; The default level is usually, but not necessarily, level 1.
+;	     (setq level (- (length keywords)
+;			    (length (member (eval (car keywords))
+;					    (mapcar 'eval (cdr keywords))))))))
+;      (setq font-lock-fontify-level (list level (> level 1)
+;					  (< level (1- (length keywords))))))))
+;
+;;; This should be called by `font-lock-unset-defaults'.
+;(defun font-lock-unset-menu ()
+;  ;; Deactivate less/more fontification entries.
+;  (setq font-lock-fontify-level nil))
+
 ;;; Various regexp information shared by several modes.
 ;;; Information specific to a single mode should go in its load library.
 
 ;; Font Lock support for C, C++, Objective-C and Java modes will one day be in
-;; cc-font.el (and required by cc-mode.el).  However, the below function should
-;; stay in font-lock.el, since it is used by other libraries.  sm.
+;; some cc-font.el (and required by cc-mode.el).  However, the below function
+;; should stay in font-lock.el, since it is used by other libraries.  sm.
 
 (defun font-lock-match-c-style-declaration-item-and-skip-to-next (limit)
   "Match, and move over, any declaration/definition item after point.
@@ -1586,9 +1761,9 @@
      ;; about five times slower.
      (list (concat "^(\\(def\\("
 		   ;; Variable declarations.
-		   "\\(const\\|custom\\|var\\)\\|"
+		   "\\(const\\|custom\\|face\\|var\\)\\|"
 		   ;; Structure declarations.
-		   "\\(class\\|struct\\|type\\)\\|"
+		   "\\(class\\|group\\|struct\\|type\\)\\|"
 		   ;; Everything else is a function declaration.
 		   "\\sw+"
 		   "\\)\\)\\>"
@@ -1601,7 +1776,7 @@
 		     (t font-lock-function-name-face))
 	       nil t))
      ))
- "Subdued level highlighting for Lisp modes.")
+  "Subdued level highlighting for Lisp modes.")
 
 (defconst lisp-font-lock-keywords-2
   (append lisp-font-lock-keywords-1
@@ -1855,7 +2030,7 @@
     (concat "\\<\\(" c-keywords "\\)\\>")
     ;;
     ;; Fontify case/goto keywords and targets, and case default/goto tags.
-    '("\\<\\(case\\|goto\\)\\>[ \t]*\\(\\sw+\\)?"
+    '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?"
       (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
     ;; Anders Lindgren <andersl@csd.uu.se> points out that it is quicker to use
     ;; MATCH-ANCHORED to effectively anchor the regexp on the left.
@@ -2030,7 +2205,7 @@
 	  '(2 font-lock-builtin-face nil t))
     ;;
     ;; Fontify case/goto keywords and targets, and case default/goto tags.
-    '("\\<\\(case\\|goto\\)\\>[ \t]*\\(\\sw+\\)?"
+    '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?"
       (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
     '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:\\($\\|[^:]\\)"
 	   (beginning-of-line) (end-of-line)
@@ -2181,7 +2356,7 @@
     (concat "\\<\\(" objc-keywords "\\)\\>")
     ;;
     ;; Fontify case/goto keywords and targets, and case default/goto tags.
-    '("\\<\\(case\\|goto\\)\\>[ \t]*\\(\\sw+\\)?"
+    '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?"
       (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
     ;; Fontify tags iff sole statement on line, otherwise we detect selectors.
     '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$"
@@ -2311,7 +2486,7 @@
     (concat "\\<\\(" java-keywords "\\)\\>")
     ;;
     ;; Fontify keywords and targets, and case default/goto tags.
-    (list "\\<\\(break\\|case\\|continue\\|goto\\)\\>[ \t]*\\(\\sw+\\)?"
+    (list "\\<\\(break\\|case\\|continue\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?"
 	  '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t))
     '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:"
 	   (beginning-of-line) (end-of-line)