From: Colin Walters <walters@gnu.org>
Subject: Re: kill ring menu
Date: 08 May 2002 02:05:14 -0400 [thread overview]
Message-ID: <1020837914.1291.390.camel@space-ghost> (raw)
In-Reply-To: <878z6vtrqr.fsf@tc-1-100.kawasaki.gol.ne.jp>
[-- Attachment #1: Type: text/plain, Size: 4533 bytes --]
On Tue, 2002-05-07 at 20:20, Miles Bader wrote:
> There could be a `font-lock-refontify-function' variable that such modes
> set, which `font-lock-mode' would call if necessary to refontify the
> buffer.
Ok, That might be one way to optimize things, if it turns out to be
necessary.
> Then the interface will seem to work consistently for users, but special
> modes can avoid the overhead of the font-lock engine if they desire.
OK. I have thought about this issue a lot more carefully.
Richard: I have changed my mind with regards to your proposal. I first
actually wrote a patch which implemented things the way you suggested.
But from a user perspective, things still wouldn't be consistent,
because typing 'M-x font-lock-mode' wouldn't always do the Right Thing
in special buffers. So we might as well have kept the status quo.
I believe your original objection to my approach was that loading
font-lock.el was a lot of overhead. I have addressed this in the
attached patch, by creating a "font-core.el".
Miles: You objected to putting special text properties on the buffer
text, and then fontifying on them later, correct? Unfortunately this is
the only way I can think of to implement fontification for special
buffers, such that typing M-x font-lock-mode will always do the Right
Thing. I believe I can optimize this such that the mode's
`font-lock-fontify-region' function is only called *once*. This should
minimize the overhead. I don't think this will actually be very slow at
all, anyways. Text properties are quite fast. Or we could solve this
issue the way you suggest above. So this should not be a problem.
One other issue that came up was that special modes wouldn't be
fontified by default. I have solved this in a simple way; we add
`font-lock-mode' to the default value of the mode's hooks. This allows
a user to customize fontification in a clean way. If a user *doesn't*
want those modes fontified, they can
(remove-hook 'foo-mode-hook 'font-lock-mode)
Let me restate things in terms of advantages and disadvantages:
Advantages:
* From a user perspective, the attached patch doesn't change anything at
all, except that typing M-x font-lock-mode will now suddenly work in
special modes like Occur; if we decide to put this patch in, then I will
change Info and all the other modes to support it.
* The memory impact should be quite small, since we only load
font-core.el for special modes.
Disadvantages:
* Fontification of special buffers may take a bit longer. I personally
don't believe the difference will be noticeable. If it is (and I
haven't noticed any slowdown), I will work on making it faster.
In this patch, most of the changes are moved functions. See the entries
for font-core.el to see what (little) code was actually changed.
2002-05-08 Colin Walters <walters@gnu.org>
* font-lock.el (font-lock)
(font-lock-highlighting-faces, font-lock-extra-types)
(fast-lock, lazy-lock, jit-lock, font-lock-maximum-size)
(font-lock-maximum-decoration, font-lock-verbose)
(font-lock-defaults, 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, font-lock-multiline)
(font-lock-fontified, save-buffer-state)
(font-lock-face-attributes, font-lock-mode)
(turn-on-font-lock, global-font-lock-mode)
(font-lock-global-modes, font-lock-support-mode)
(fast-lock-mode, lazy-lock-mode, jit-lock-mode)
(font-lock-turn-on-thing-lock, font-lock-turn-off-thing-lock)
(font-lock-after-fontify-buffer, font-lock-after-unfontify-buffer)
(font-lock-fontify-buffer, font-lock-unfontify-buffer)
(font-lock-fontify-region, font-lock-unfontify-region)
(font-lock-default-fontify-buffer)
(font-lock-default-unfontify-buffer)
(font-lock-default-unfontify-region)
(font-lock-after-change-function):
Moved to font-core.el.
(font-lock-set-defaults): Renamed to `font-lock-set-defaults-1';
partially moved to font-core.el.
* font-core.el: New file, with functions broken out from
font-lock.el.
(font-lock-core-only): New variable.
(font-lock-mode): If `font-lock-core-only' is non-nil, fontify the
whole buffer immediately; don't enable a font-lock support mode.
(font-lock-set-defaults): Partially moved here from font-lock.el.
We try to only load all of font-lock.el if the mode doesn't set
`font-lock-core-only'.
* replace.el (occur-mode-hooks): New variable.
(occur-mode): Set `font-lock-core-only'. Run `occur-mode-hooks'
too.
[-- Attachment #2: font-lock.patch --]
[-- Type: text/plain, Size: 61475 bytes --]
--- loadup.el.~1.122.~ Sun Apr 28 22:29:16 2002
+++ loadup.el Wed May 8 00:38:36 2002
@@ -149,6 +149,7 @@
(load "emacs-lisp/lisp-mode")
(load "textmodes/text-mode")
(load "textmodes/fill")
+(load "font-core")
(message "%s" (garbage-collect))
(load "replace")
--- replace.el.~1.140.~ Tue May 7 23:49:58 2002
+++ replace.el Wed May 8 01:28:26 2002
@@ -453,6 +453,11 @@
"Arguments to pass to `occur-1' to revert an Occur mode buffer.
See `occur-revert-function'.")
+(defcustom occur-mode-hooks '(font-lock-mode)
+ "Hooks run upon entry into `occur-mode'."
+ :type 'hook
+ :group 'matching)
+
(put 'occur-mode 'mode-class 'special)
(defun occur-mode ()
"Major mode for output from \\[occur].
@@ -468,11 +473,13 @@
(make-local-variable 'revert-buffer-function)
(set (make-local-variable 'font-lock-defaults)
'(nil t nil nil nil
+ (font-lock-core-only . t)
(font-lock-fontify-region-function . occur-fontify-region-function)))
(setq revert-buffer-function 'occur-revert-function)
(set (make-local-variable 'revert-buffer-function) 'occur-revert-function)
(make-local-variable 'occur-revert-arguments)
- (run-hooks 'occur-mode-hook))
+ (run-hooks 'occur-mode-hook)
+ (run-hooks 'occur-mode-hooks))
(defun occur-revert-function (ignore1 ignore2)
"Handle `revert-buffer' for Occur mode buffers."
--- font-lock.el.~1.195.~ Tue May 7 18:20:10 2002
+++ font-lock.el Wed May 8 01:21:52 2002
@@ -208,99 +208,8 @@
;;; Code:
(require 'syntax)
+(require 'font-core)
-;; Define core `font-lock' group.
-(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
- "Faces for highlighting text."
- :prefix "font-lock-"
- :group 'font-lock)
-
-(defgroup font-lock-extra-types nil
- "Extra mode-specific type names for highlighting declarations."
- :group 'font-lock)
-
-;; 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")
- :load 'fast-lock
- :group 'font-lock)
-
-(defgroup lazy-lock nil
- "Font Lock support mode to fontify lazily."
- :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)
-\f
-;; User variables.
-
-(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
- "*Maximum decoration level for fontification.
-If nil, use the default decoration (typically the minimum available).
-If t, use the maximum decoration available.
-If a number, use that level of decoration (or if not available the maximum).
-If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
-where MAJOR-MODE is a symbol or t (meaning the default). For example:
- ((c-mode . t) (c++-mode . 2) (t . 1))
-means use the maximum decoration available for buffers in C mode, level 2
-decoration for buffers in C++ mode, and level 1 decoration otherwise."
- :type '(choice (const :tag "default" nil)
- (const :tag "maximum" t)
- (integer :tag "level" 1)
- (repeat :menu-tag "mode specific" :tag "mode specific"
- :value ((t . t))
- (cons :tag "Instance"
- (radio :tag "Mode"
- (const :tag "all" t)
- (symbol :tag "name"))
- (radio :tag "Decoration"
- (const :tag "default" nil)
- (const :tag "maximum" t)
- (integer :tag "level" 1)))))
- :group 'font-lock)
-
-(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)
\f
;; Originally these variable values were face names such as `bold' etc.
@@ -446,55 +355,6 @@
Be careful when composing regexps for this list; a poorly written pattern can
dramatically slow things down!")
-;; This variable is used by mode packages that support Font Lock mode by
-;; defining their own keywords to use for `font-lock-keywords'. (The mode
-;; command should make it buffer-local and set it to provide the set up.)
-(defvar font-lock-defaults nil
- "Defaults for Font Lock mode specified by the major mode.
-Defaults should be of the form:
-
- (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
-
-KEYWORDS may be a symbol (a variable or function whose value is the keywords to
-use for fontification) or a list of symbols. If KEYWORDS-ONLY is non-nil,
-syntactic fontification (strings and comments) is not performed.
-If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
-If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
-\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
-keyword and syntactic fontification (see `modify-syntax-entry').
-
-If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
-backwards outside any enclosing syntactic block, for syntactic fontification.
-Typical values are `beginning-of-line' (i.e., the start of the line is known to
-be outside a syntactic block), or `beginning-of-defun' for programming modes or
-`backward-paragraph' for textual modes (i.e., the mode-dependent function is
-known to move outside a syntactic block). If nil, the beginning of the buffer
-is used as a position outside of a syntactic block, in the worst case.
-
-These item elements are used by Font Lock mode to set the variables
-`font-lock-keywords', `font-lock-keywords-only',
-`font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
-`font-lock-beginning-of-syntax-function', respectively.
-
-Further item elements are alists of the form (VARIABLE . VALUE) and are in no
-particular order. Each VARIABLE is made buffer-local before set to VALUE.
-
-Currently, appropriate variables include `font-lock-mark-block-function'.
-If this is non-nil, it should be a function with no args used to mark any
-enclosing block of text, for fontification via \\[font-lock-fontify-block].
-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 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
(let (;; We use `beginning-of-defun', rather than nil, for SYNTAX-BEGIN.
@@ -632,153 +492,6 @@
enclosing textual block and mark at the end.
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'.")
-
-(defvar font-lock-unfontify-buffer-function 'font-lock-default-unfontify-buffer
- "Function to use for unfontifying the buffer.
-This is used when turning off Font Lock mode.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
- "Function to use for fontifying a region.
-It should take two args, the beginning and end of the region, and an optional
-third arg VERBOSE. If non-nil, the function should print status messages.
-This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
- "Function to use for unfontifying a region.
-It should take two args, the beginning and end of the region.
-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 are `fast-lock-mode', `jit-lock-mode' and
-`lazy-lock-mode'. This is normally set via `font-lock-defaults'.")
-
-(defvar font-lock-multiline nil
- "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.")
-
-(defvar font-lock-fontified nil) ; Whether we have fontified the buffer.
-\f
-;; Font Lock mode.
-
-(eval-when-compile
- ;;
- ;; We don't do this at the top-level as we only use non-autoloaded macros.
- (require 'cl)
- ;;
- ;; Borrowed from lazy-lock.el.
- ;; 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 ((modified (make-symbol "modified")))
- `(let* ,(append varlist
- `((,modified (buffer-modified-p))
- (buffer-undo-list t)
- (inhibit-read-only t)
- (inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t)
- deactivate-mark
- buffer-file-name
- buffer-file-truename))
- (progn
- ,@body)
- (unless ,modified
- (restore-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
-(define-minor-mode font-lock-mode
- "Toggle Font Lock mode.
-With arg, turn Font Lock mode off if and only if arg is a non-positive
-number; if arg is nil, toggle Font Lock mode; anything else turns Font
-Lock on.
-\(Font Lock is also known as \"syntax highlighting\".)
-
-When Font Lock mode is enabled, text is fontified as you type it:
-
- - Comments are displayed in `font-lock-comment-face';
- - Strings are displayed in `font-lock-string-face';
- - 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:
-
- (add-hook 'c-mode-hook 'turn-on-font-lock)
-
-Alternatively, you can use Global Font Lock mode to automagically turn on Font
-Lock mode in buffers whose major mode supports it and whose major mode is one
-of `font-lock-global-modes'. For example, put in your ~/.emacs:
-
- (global-font-lock-mode t)
-
-There are a number of support modes that may be used to speed up Font Lock mode
-in various ways, specified via the variable `font-lock-support-mode'. Where
-major modes support different levels of fontification, you can use the variable
-`font-lock-maximum-decoration' to specify which level you generally prefer.
-When you turn Font Lock mode on/off the buffer is fontified/defontified, though
-fontification occurs only if the buffer is less than `font-lock-maximum-size'.
-
-For example, to specify that Font Lock mode use use Lazy Lock mode as a support
-mode and use maximum levels of fontification, put in your ~/.emacs:
-
- (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].
-
-To fontify a block (the function or paragraph containing point, or a number of
-lines around point), perhaps because modification on the current line caused
-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."
- 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).
- (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 t 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)))
-
;;;###autoload
(defun turn-on-font-lock ()
"Turn on Font Lock mode (only if the terminal can display it)."
@@ -937,279 +650,10 @@
(delete (font-lock-compile-keyword keyword)
font-lock-keywords)))))))
\f
-;;; Global Font Lock mode.
-
-;; A few people have hassled in the past for a way to make it easier to turn on
-;; Font Lock mode, without the user needing to know for which modes s/he has to
-;; turn it on, perhaps the same way hilit19.el/hl319.el does. I've always
-;; balked at that way, as I see it as just re-moulding the same problem in
-;; another form. That is; some person would still have to keep track of which
-;; modes (which may not even be distributed with Emacs) support Font Lock mode.
-;; The list would always be out of date. And that person might have to be me.
-
-;; Implementation.
-;;
-;; In a previous discussion the following hack came to mind. It is a gross
-;; hack, but it generally works. We use the convention that major modes start
-;; by calling the function `kill-all-local-variables', which in turn runs
-;; functions on the hook variable `change-major-mode-hook'. We attach our
-;; function `font-lock-change-major-mode' to that hook. Of course, when this
-;; hook is run, the major mode is in the process of being changed and we do not
-;; know what the final major mode will be. So, `font-lock-change-major-mode'
-;; only (a) notes the name of the current buffer, and (b) adds our function
-;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
-;; `post-command-hook' (for buffers that are not visiting files). By the time
-;; the functions on the first of these hooks to be run are run, the new major
-;; mode is assumed to be in place. This way we get a Font Lock function run
-;; when a major mode is turned on, without knowing major modes or their hooks.
-;;
-;; Naturally this requires that (a) major modes run `kill-all-local-variables',
-;; as they are supposed to do, and (b) the major mode is in place after the
-;; file is visited or the command that ran `kill-all-local-variables' has
-;; finished, whichever the sooner. Arguably, any major mode that does not
-;; follow the convension (a) is broken, and I can't think of any reason why (b)
-;; would not be met (except `gnudoit' on non-files). However, it is not clean.
-;;
-;; Probably the cleanest solution is to have each major mode function run some
-;; hook, e.g., `major-mode-hook', but maybe implementing that change is
-;; impractical. I am personally against making `setq' a macro or be advised,
-;; or have a special function such as `set-major-mode', but maybe someone can
-;; come up with another solution?
-
-;; User interface.
-;;
-;; Although Global Font Lock mode is a pseudo-mode, I think that the user
-;; interface should conform to the usual Emacs convention for modes, i.e., a
-;; command to toggle the feature (`global-font-lock-mode') with a variable for
-;; finer control of the mode's behaviour (`font-lock-global-modes').
-;;
-;; The feature should not be enabled by loading font-lock.el, since other
-;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
-;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
-;; turned on everywhere. That would not be intuitive or informative because
-;; 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.
-
-(defcustom font-lock-global-modes t
- "*Modes for which Font Lock mode is automagically turned on.
-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
-mode should be automatically turned on. The sense of the list is negated if it
-begins with `not'. For example:
- (c-mode c++-mode)
-means that Font Lock mode is turned on for buffers in C and C++ modes only."
- :type '(choice (const :tag "none" nil)
- (const :tag "all" t)
- (set :menu-tag "mode specific" :tag "modes"
- :value (not)
- (const :tag "Except" not)
- (repeat :inline t (symbol :tag "mode"))))
- :group 'font-lock)
-
-(defun turn-on-font-lock-if-enabled ()
- (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.
-\f
-;;; Font Lock Support mode.
-
-;; This is the code used to interface font-lock.el with any of its add-on
-;; packages, and provide the user interface. Packages that have their own
-;; local buffer fontification functions (see below) may have to call
-;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
-;; themselves.
-
-(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'),
-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),
-where MAJOR-MODE is a symbol or t (meaning the default). For example:
- ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
-means that Fast Lock mode is used to support Font Lock mode for buffers in C or
-C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
-
-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 . jit-lock-mode))
- (cons :tag "Instance"
- (radio :tag "Mode"
- (const :tag "all" t)
- (symbol :tag "name"))
- (radio :tag "Support"
- (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)))
- ))
- :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))
- ((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 -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 -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))))
-
-;;; End of Font Lock Support mode.
\f
-;;; 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' 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 that function 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 the function `font-lock-mode' would."
- (interactive)
- (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
- (funcall font-lock-fontify-buffer-function)))
-
-(defun font-lock-unfontify-buffer ()
- (funcall font-lock-unfontify-buffer-function))
-
-(defun font-lock-fontify-region (beg end &optional loudly)
- (funcall font-lock-fontify-region-function beg end loudly))
-
-(defun font-lock-unfontify-region (beg end)
- (funcall font-lock-unfontify-region-function beg end))
-
-(defun font-lock-default-fontify-buffer ()
- (let ((verbose (if (numberp font-lock-verbose)
- (> (buffer-size) font-lock-verbose)
- font-lock-verbose)))
- (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)))))))
-
-(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))
- (font-lock-after-unfontify-buffer)
- (setq font-lock-fontified nil)))
+;;; Non-core fontification functions.
(defun font-lock-default-fontify-region (beg end loudly)
(save-buffer-state
@@ -1248,41 +692,6 @@
;; Clean up.
(set-syntax-table old-syntax-table))))
-;; 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
-; font-lock-cache-state)))
-; (or (nth 4 state) (nth 7 state))))
-; (font-lock-fontify-keywords-region beg end))
-
-(defvar font-lock-extra-managed-props nil
- "Additional text properties managed by font-lock.
-This is used by `font-lock-default-unfontify-region' to decide
-what properties to clear before refontifying a region.
-Since it is more or less directly passed to `remove-text-properties',
-it should have the shape of a property list (i.e. every other element
-is ignored).")
-
-(defun font-lock-default-unfontify-region (beg end)
- (save-buffer-state nil
- (remove-text-properties
- beg end (append
- font-lock-extra-managed-props
- (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)
- (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.
The lines could be a function or paragraph, or a specified number of lines.
@@ -1309,7 +718,13 @@
(define-key facemenu-keymap "\M-g" 'font-lock-fontify-block)
-;;; End of Fontification functions.
+;; 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
+; font-lock-cache-state)))
+; (or (nth 4 state) (nth 7 state))))
+; (font-lock-fontify-keywords-region beg end))
\f
;;; Additional text property functions.
@@ -1718,17 +1133,8 @@
(t
(car keywords))))
-(defvar font-lock-set-defaults nil) ; Whether we have set up defaults.
-
-(defun font-lock-set-defaults ()
- "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'."
+(defun font-lock-set-defaults-1 ()
;; Set fontification defaults iff not previously set.
- (unless font-lock-set-defaults
- (set (make-local-variable 'font-lock-set-defaults) t)
- (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
@@ -1771,7 +1177,7 @@
(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)))))
+ (font-lock-remove-keywords nil removed-keywords))))
\f
;;; Colour etc. support.
--- /dev/null Wed Dec 31 19:00:00 1969
+++ font-core.el Wed May 8 01:21:03 2002
@@ -0,0 +1,647 @@
+;;; font-core.el --- Core interface to font-lock
+
+;; Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999, 2000, 2001, 2002
+;; Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+;; Keywords: languages, faces
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+;; Define core `font-lock' group.
+(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
+ "Faces for highlighting text."
+ :prefix "font-lock-"
+ :group 'font-lock)
+
+(defgroup font-lock-extra-types nil
+ "Extra mode-specific type names for highlighting declarations."
+ :group 'font-lock)
+
+;; 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")
+ :load 'fast-lock
+ :group 'font-lock)
+
+(defgroup lazy-lock nil
+ "Font Lock support mode to fontify lazily."
+ :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)
+\f
+;; User variables.
+
+(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
+ "*Maximum decoration level for fontification.
+If nil, use the default decoration (typically the minimum available).
+If t, use the maximum decoration available.
+If a number, use that level of decoration (or if not available the maximum).
+If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
+where MAJOR-MODE is a symbol or t (meaning the default). For example:
+ ((c-mode . t) (c++-mode . 2) (t . 1))
+means use the maximum decoration available for buffers in C mode, level 2
+decoration for buffers in C++ mode, and level 1 decoration otherwise."
+ :type '(choice (const :tag "default" nil)
+ (const :tag "maximum" t)
+ (integer :tag "level" 1)
+ (repeat :menu-tag "mode specific" :tag "mode specific"
+ :value ((t . t))
+ (cons :tag "Instance"
+ (radio :tag "Mode"
+ (const :tag "all" t)
+ (symbol :tag "name"))
+ (radio :tag "Decoration"
+ (const :tag "default" nil)
+ (const :tag "maximum" t)
+ (integer :tag "level" 1)))))
+ :group 'font-lock)
+
+(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)
+
+;; This variable is used by mode packages that support Font Lock mode by
+;; defining their own keywords to use for `font-lock-keywords'. (The mode
+;; command should make it buffer-local and set it to provide the set up.)
+(defvar font-lock-defaults nil
+ "Defaults for Font Lock mode specified by the major mode.
+Defaults should be of the form:
+
+ (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
+
+KEYWORDS may be a symbol (a variable or function whose value is the keywords to
+use for fontification) or a list of symbols. If KEYWORDS-ONLY is non-nil,
+syntactic fontification (strings and comments) is not performed.
+If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
+If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
+\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
+keyword and syntactic fontification (see `modify-syntax-entry').
+
+If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
+backwards outside any enclosing syntactic block, for syntactic fontification.
+Typical values are `beginning-of-line' (i.e., the start of the line is known to
+be outside a syntactic block), or `beginning-of-defun' for programming modes or
+`backward-paragraph' for textual modes (i.e., the mode-dependent function is
+known to move outside a syntactic block). If nil, the beginning of the buffer
+is used as a position outside of a syntactic block, in the worst case.
+
+These item elements are used by Font Lock mode to set the variables
+`font-lock-keywords', `font-lock-keywords-only',
+`font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
+`font-lock-beginning-of-syntax-function', respectively.
+
+Further item elements are alists of the form (VARIABLE . VALUE) and are in no
+particular order. Each VARIABLE is made buffer-local before set to VALUE.
+
+Currently, appropriate variables include `font-lock-mark-block-function'.
+If this is non-nil, it should be a function with no args used to mark any
+enclosing block of text, for fontification via \\[font-lock-fontify-block].
+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 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)
+
+(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'.")
+
+(defvar font-lock-unfontify-buffer-function 'font-lock-default-unfontify-buffer
+ "Function to use for unfontifying the buffer.
+This is used when turning off Font Lock mode.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
+ "Function to use for fontifying a region.
+It should take two args, the beginning and end of the region, and an optional
+third arg VERBOSE. If non-nil, the function should print status messages.
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
+ "Function to use for unfontifying a region.
+It should take two args, the beginning and end of the region.
+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 are `fast-lock-mode', `jit-lock-mode' and
+`lazy-lock-mode'. This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-multiline nil
+ "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.")
+
+(defvar font-lock-fontified nil) ; Whether we have fontified the buffer.
+(defvar font-lock-core-only nil)
+
+;; Font Lock mode.
+
+(define-minor-mode font-lock-mode
+ "Toggle Font Lock mode.
+With arg, turn Font Lock mode off if and only if arg is a non-positive
+number; if arg is nil, toggle Font Lock mode; anything else turns Font
+Lock on.
+\(Font Lock is also known as \"syntax highlighting\".)
+
+When Font Lock mode is enabled, text is fontified as you type it:
+
+ - Comments are displayed in `font-lock-comment-face';
+ - Strings are displayed in `font-lock-string-face';
+ - 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:
+
+ (add-hook 'c-mode-hook 'turn-on-font-lock)
+
+Alternatively, you can use Global Font Lock mode to automagically turn on Font
+Lock mode in buffers whose major mode supports it and whose major mode is one
+of `font-lock-global-modes'. For example, put in your ~/.emacs:
+
+ (global-font-lock-mode t)
+
+There are a number of support modes that may be used to speed up Font Lock mode
+in various ways, specified via the variable `font-lock-support-mode'. Where
+major modes support different levels of fontification, you can use the variable
+`font-lock-maximum-decoration' to specify which level you generally prefer.
+When you turn Font Lock mode on/off the buffer is fontified/defontified, though
+fontification occurs only if the buffer is less than `font-lock-maximum-size'.
+
+For example, to specify that Font Lock mode use use Lazy Lock mode as a support
+mode and use maximum levels of fontification, put in your ~/.emacs:
+
+ (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].
+
+To fontify a block (the function or paragraph containing point, or a number of
+lines around point), perhaps because modification on the current line caused
+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."
+ 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).
+ (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 t t)
+ (font-lock-set-defaults)
+ (if font-lock-core-only
+ (font-lock-fontify-buffer)
+ (progn
+ (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)
+ (unless font-lock-core-only
+ (font-lock-turn-off-thing-lock))))
+
+;;; Global Font Lock mode.
+
+;; A few people have hassled in the past for a way to make it easier to turn on
+;; Font Lock mode, without the user needing to know for which modes s/he has to
+;; turn it on, perhaps the same way hilit19.el/hl319.el does. I've always
+;; balked at that way, as I see it as just re-moulding the same problem in
+;; another form. That is; some person would still have to keep track of which
+;; modes (which may not even be distributed with Emacs) support Font Lock mode.
+;; The list would always be out of date. And that person might have to be me.
+
+;; Implementation.
+;;
+;; In a previous discussion the following hack came to mind. It is a gross
+;; hack, but it generally works. We use the convention that major modes start
+;; by calling the function `kill-all-local-variables', which in turn runs
+;; functions on the hook variable `change-major-mode-hook'. We attach our
+;; function `font-lock-change-major-mode' to that hook. Of course, when this
+;; hook is run, the major mode is in the process of being changed and we do not
+;; know what the final major mode will be. So, `font-lock-change-major-mode'
+;; only (a) notes the name of the current buffer, and (b) adds our function
+;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
+;; `post-command-hook' (for buffers that are not visiting files). By the time
+;; the functions on the first of these hooks to be run are run, the new major
+;; mode is assumed to be in place. This way we get a Font Lock function run
+;; when a major mode is turned on, without knowing major modes or their hooks.
+;;
+;; Naturally this requires that (a) major modes run `kill-all-local-variables',
+;; as they are supposed to do, and (b) the major mode is in place after the
+;; file is visited or the command that ran `kill-all-local-variables' has
+;; finished, whichever the sooner. Arguably, any major mode that does not
+;; follow the convension (a) is broken, and I can't think of any reason why (b)
+;; would not be met (except `gnudoit' on non-files). However, it is not clean.
+;;
+;; Probably the cleanest solution is to have each major mode function run some
+;; hook, e.g., `major-mode-hook', but maybe implementing that change is
+;; impractical. I am personally against making `setq' a macro or be advised,
+;; or have a special function such as `set-major-mode', but maybe someone can
+;; come up with another solution?
+
+;; User interface.
+;;
+;; Although Global Font Lock mode is a pseudo-mode, I think that the user
+;; interface should conform to the usual Emacs convention for modes, i.e., a
+;; command to toggle the feature (`global-font-lock-mode') with a variable for
+;; finer control of the mode's behaviour (`font-lock-global-modes').
+;;
+;; The feature should not be enabled by loading font-lock.el, since other
+;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
+;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
+;; turned on everywhere. That would not be intuitive or informative because
+;; 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.
+
+(defcustom font-lock-global-modes t
+ "*Modes for which Font Lock mode is automagically turned on.
+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
+mode should be automatically turned on. The sense of the list is negated if it
+begins with `not'. For example:
+ (c-mode c++-mode)
+means that Font Lock mode is turned on for buffers in C and C++ modes only."
+ :type '(choice (const :tag "none" nil)
+ (const :tag "all" t)
+ (set :menu-tag "mode specific" :tag "modes"
+ :value (not)
+ (const :tag "Except" not)
+ (repeat :inline t (symbol :tag "mode"))))
+ :group 'font-lock)
+
+(easy-mmode-define-global-mode
+ global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
+ :extra-args (dummy))
+
+(defun turn-on-font-lock-if-enabled ()
+ (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))))
+
+;;; End of Global Font Lock mode.
+
+
+;;; Font Lock Support mode.
+
+;; This is the code used to interface font-lock.el with any of its add-on
+;; packages, and provide the user interface. Packages that have their own
+;; local buffer fontification functions (see below) may have to call
+;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
+;; themselves.
+
+(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'),
+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),
+where MAJOR-MODE is a symbol or t (meaning the default). For example:
+ ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
+means that Fast Lock mode is used to support Font Lock mode for buffers in C or
+C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
+
+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 . jit-lock-mode))
+ (cons :tag "Instance"
+ (radio :tag "Mode"
+ (const :tag "all" t)
+ (symbol :tag "name"))
+ (radio :tag "Support"
+ (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)))
+ ))
+ :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))
+ ((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 -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 -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))))
+
+;;; End of Font Lock Support mode.
+
+;;; Core 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' 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 that function 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.)
+
+(defun font-lock-fontify-buffer ()
+ "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)))
+
+(defun font-lock-unfontify-buffer ()
+ (funcall font-lock-unfontify-buffer-function))
+
+(defun font-lock-fontify-region (beg end &optional loudly)
+ (funcall font-lock-fontify-region-function beg end loudly))
+
+(defun font-lock-unfontify-region (beg end)
+ (funcall font-lock-unfontify-region-function beg end))
+
+(defun font-lock-default-fontify-buffer ()
+ (let ((verbose (if (numberp font-lock-verbose)
+ (> (buffer-size) font-lock-verbose)
+ font-lock-verbose)))
+ (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)))))))
+
+(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))
+ (font-lock-after-unfontify-buffer)
+ (setq font-lock-fontified nil)))
+
+\f
+(eval-when-compile
+ ;;
+ ;; We don't do this at the top-level as we only use non-autoloaded macros.
+ (require 'cl)
+ ;;
+ ;; Borrowed from lazy-lock.el.
+ ;; 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 ((modified (make-symbol "modified")))
+ `(let* ,(append varlist
+ `((,modified (buffer-modified-p))
+ (buffer-undo-list t)
+ (inhibit-read-only t)
+ (inhibit-point-motion-hooks t)
+ (inhibit-modification-hooks t)
+ deactivate-mark
+ buffer-file-name
+ buffer-file-truename))
+ (progn
+ ,@body)
+ (unless ,modified
+ (restore-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.
+
+(defvar font-lock-extra-managed-props nil
+ "Additional text properties managed by font-lock.
+This is used by `font-lock-default-unfontify-region' to decide
+what properties to clear before refontifying a region.
+Since it is more or less directly passed to `remove-text-properties',
+it should have the shape of a property list (i.e. every other element
+is ignored).")
+
+(defun font-lock-default-unfontify-region (beg end)
+ (save-buffer-state nil
+ (remove-text-properties
+ beg end (append
+ font-lock-extra-managed-props
+ (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)
+ (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)))))))
+
+;;; End of Fontification functions.
+
+(defvar font-lock-set-defaults nil) ; Whether we have set up defaults.
+
+(defun font-lock-set-defaults ()
+ "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'."
+ (unless font-lock-set-defaults
+ (set (make-local-variable 'font-lock-set-defaults) t)
+ (make-local-variable 'font-lock-fontified)
+ (make-local-variable 'font-lock-multiline)
+ (let ((options (nthcdr 5 font-lock-defaults)))
+ ;; Detect if this is a simple mode, which doesn't use any
+ ;; syntactic fontification functions.
+ (if (and (assq 'font-lock-fontify-region-function options)
+ (assq 'font-lock-core-only options))
+ (dolist (x (nthcdr 5 font-lock-defaults))
+ (set (make-local-variable (car x)) (cdr x)))
+ (require 'font-lock)
+ (font-lock-set-defaults-1)))))
+
+(provide 'font-core)
+
+;;; font-core.el ends here
+
next prev parent reply other threads:[~2002-05-08 6:05 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-04-28 19:41 kill ring menu Colin Walters
2002-04-28 20:06 ` Colin Walters
2002-04-29 5:05 ` Richard Stallman
2002-04-29 18:40 ` Richard Stallman
2002-04-28 22:53 ` Miles Bader
2002-04-28 23:36 ` Stefan Monnier
2002-04-28 23:42 ` Miles Bader
2002-04-29 4:34 ` Colin Walters
2002-04-30 4:49 ` Eli Zaretskii
2002-04-29 3:35 ` Miles Bader
2002-04-29 4:37 ` Colin Walters
2002-04-29 4:56 ` Miles Bader
2002-04-29 5:37 ` Colin Walters
2002-04-29 7:09 ` Miles Bader
2002-04-30 5:18 ` Richard Stallman
2002-04-30 10:18 ` Per Abrahamsen
2002-04-29 9:22 ` CC (was: Re: kill ring menu) Per Abrahamsen
2002-04-29 15:11 ` Benjamin Rutt
2002-04-29 15:31 ` Miles Bader
2002-04-30 5:19 ` Richard Stallman
2002-04-30 10:14 ` Per Abrahamsen
2002-04-30 11:08 ` Simon Josefsson
2002-04-29 10:10 ` Addressing email (was: " Eli Zaretskii
2002-04-29 13:13 ` kill ring menu Stefan Monnier
2002-04-29 18:40 ` Richard Stallman
[not found] ` <200204290505.g3T55t006146@aztec.santafe.edu>
[not found] ` <1020059236.31789.358.camel@space-ghost>
[not found] ` <200204300519.g3U5Js306727@aztec.santafe.edu>
[not found] ` <1020212569.27106.2246.camel@space-ghost>
[not found] ` <200205011926.g41JQBC07690@aztec.santafe.edu>
[not found] ` <1020284783.27106.3417.camel@space-ghost>
2002-05-03 18:25 ` Richard Stallman
2002-05-03 18:46 ` Miles Bader
2002-05-03 19:05 ` Miles Bader
2002-05-03 20:20 ` Colin Walters
2002-05-04 1:34 ` Miles Bader
2002-05-04 3:36 ` Richard Stallman
2002-05-04 3:49 ` Miles Bader
2002-05-05 5:34 ` Richard Stallman
2002-05-04 6:04 ` Eli Zaretskii
[not found] ` <1020320725.27616.54.camel@space-ghost>
[not found] ` <200205031825.g43IPuD00768@aztec.santafe.edu>
[not found] ` <1020502030.5286.25.camel@space-ghost>
2002-05-05 17:46 ` Richard Stallman
2002-05-06 5:15 ` Colin Walters
2002-05-06 6:39 ` Miles Bader
2002-05-06 22:55 ` Colin Walters
2002-05-07 1:35 ` Miles Bader
2002-05-07 3:55 ` Colin Walters
2002-05-07 4:18 ` Miles Bader
2002-05-07 20:07 ` Richard Stallman
2002-05-07 20:38 ` Colin Walters
2002-05-08 0:20 ` Miles Bader
2002-05-08 6:05 ` Colin Walters [this message]
2002-05-08 6:50 ` Miles Bader
2002-05-08 7:36 ` Colin Walters
2002-05-08 7:48 ` Miles Bader
2002-05-08 8:57 ` Colin Walters
2002-05-08 13:14 ` Stefan Monnier
2002-05-09 4:29 ` Colin Walters
2002-05-09 10:08 ` Kim F. Storm
2002-05-09 2:45 ` Richard Stallman
2002-05-09 4:28 ` Colin Walters
2002-05-10 0:30 ` Richard Stallman
2002-05-16 18:47 ` Colin Walters
2002-05-16 19:12 ` Miles Bader
2002-05-16 19:20 ` Colin Walters
2002-05-16 19:36 ` Miles Bader
2002-05-16 19:45 ` Miles Bader
2002-05-16 19:54 ` Colin Walters
2002-05-16 20:12 ` Miles Bader
2002-05-16 20:17 ` Colin Walters
2002-05-16 20:23 ` Miles Bader
2002-05-16 21:47 ` Colin Walters
2002-05-16 21:54 ` Kim F. Storm
2002-05-16 21:15 ` Miles Bader
2002-05-17 19:29 ` Richard Stallman
2002-05-07 19:22 ` Alex Schroeder
2002-05-09 20:09 ` Colin Walters
2002-05-11 6:30 ` Richard Stallman
2002-05-13 22:17 ` Colin Walters
2002-05-14 8:36 ` Miles Bader
2002-05-14 12:49 ` Emacs 21.4 (was: kill ring menu) Eli Zaretskii
2002-05-15 7:01 ` kill ring menu Richard Stallman
2002-05-06 6:46 ` Stephen J. Turnbull
2002-05-06 22:46 ` Colin Walters
2002-05-08 10:06 ` Francesco Potorti`
2002-05-08 10:20 ` Eli Zaretskii
2002-05-06 19:32 ` Richard Stallman
2002-05-07 4:03 ` Colin Walters
2002-05-07 5:27 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1020837914.1291.390.camel@space-ghost \
--to=walters@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).