From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Colin Walters Newsgroups: gmane.emacs.devel Subject: Re: kill ring menu Date: 08 May 2002 02:05:14 -0400 Sender: emacs-devel-admin@gnu.org Message-ID: <1020837914.1291.390.camel@space-ghost> References: <1020022891.27106.142.camel@space-ghost> <200204290505.g3T55t006146@aztec.santafe.edu> <1020059236.31789.358.camel@space-ghost> <200204300519.g3U5Js306727@aztec.santafe.edu> <1020320725.27616.54.camel@space-ghost> <200205031825.g43IPuD00768@aztec.santafe.edu> <1020502030.5286.25.camel@space-ghost> <200205051746.g45Hk5P01808@aztec.santafe.edu> <1020662101.5288.76.camel@space-ghost> <87helleq50.fsf@tc-1-100.kawasaki.gol.ne.jp> <1020725723.5138.127.camel@space-ghost> <1020743734.5288.153.camel@space-ghost> <200205072007.g47K7bv04781@aztec.santafe.edu> <1020803891.5288.198.camel@space-ghost> <878z6vtrqr.fsf@tc-1-100.kawasaki.gol.ne.jp> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-5skm+6LKpXSRjDW/acow" X-Trace: main.gmane.org 1020837992 5756 127.0.0.1 (8 May 2002 06:06:32 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Wed, 8 May 2002 06:06:32 +0000 (UTC) Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.33 #1 (Debian)) id 175Kau-0001Uj-00 for ; Wed, 08 May 2002 08:06:32 +0200 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 175Kis-0003Bu-00 for ; Wed, 08 May 2002 08:14:47 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 175Kao-0003bh-00; Wed, 08 May 2002 02:06:26 -0400 Original-Received: from monk.debian.net ([216.185.54.61] helo=monk.verbum.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 175KaK-0003ZE-00 for ; Wed, 08 May 2002 02:05:56 -0400 Original-Received: from space-ghost.verbum.private (freedom.cis.ohio-state.edu [164.107.60.183]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (Client CN "space-ghost.verbum.org", Issuer "monk.verbum.org" (verified OK)) by monk.verbum.org (Postfix (Debian/GNU)) with ESMTP id D9F537400252 for ; Wed, 8 May 2002 02:05:44 -0400 (EDT) Original-Received: by space-ghost.verbum.private (Postfix (Debian/GNU), from userid 1000) id 544B682FB74; Wed, 8 May 2002 02:05:15 -0400 (EDT) Original-To: emacs-devel@gnu.org In-Reply-To: <878z6vtrqr.fsf@tc-1-100.kawasaki.gol.ne.jp> X-Mailer: Ximian Evolution 1.0.3 Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.9 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:3704 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:3704 --=-5skm+6LKpXSRjDW/acow Content-Type: text/plain Content-Transfer-Encoding: 7bit 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 * 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. --=-5skm+6LKpXSRjDW/acow Content-Disposition: attachment; filename=font-lock.patch Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; name=font-lock.patch; charset=ISO-8859-1 --- 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)) =20 (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'.") =20 +(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-functio= n) (make-local-variable 'occur-revert-arguments) - (run-hooks 'occur-mode-hook)) + (run-hooks 'occur-mode-hook) + (run-hooks 'occur-mode-hooks)) =20 (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: =20 (require 'syntax) +(require 'font-core) =20 -;; 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) -=0C -;; 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 . SI= ZE), -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 meg= abyte -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 . LE= VEL), -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 messag= es." - :type '(choice (const :tag "never" nil) - (other :tag "always" t) - (integer :tag "size")) - :group 'font-lock) =0C =20 ;; 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!") =20 -;; 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 keywor= ds 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 fontifyi= ng. -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, f= or -keyword and syntactic fontification (see `modify-syntax-entry'). - -If SYNTAX-BEGIN is non-nil, it should be a function with no args used to m= ove -backwards outside any enclosing syntactic block, for syntactic fontificati= on. -Typical values are `beginning-of-line' (i.e., the start of the line is kno= wn to -be outside a syntactic block), or `beginning-of-defun' for programming mod= es 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 bu= ffer -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'.") =20 -(defvar font-lock-fontify-buffer-function 'font-lock-default-fontify-buffe= r - "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-b= uffer - "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-regio= n - "Function to use for fontifying a region. -It should take two args, the beginning and end of the region, and an optio= nal -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-r= egion - "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. -=0C -;; Font Lock mode. - -(eval-when-compile - ;; - ;; We don't do this at the top-level as we only use non-autoloaded macro= s. - (require 'cl) - ;; - ;; Borrowed from lazy-lock.el. - ;; We use this to preserve or protect things when modifying text propert= ies. - (defmacro save-buffer-state (varlist &rest body) - "Bind variables according to VARLIST and eval BODY restoring buffer st= ate." - (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 o= n 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'. Whe= re -major modes support different levels of fontification, you can use the var= iable -`font-lock-maximum-decoration' to specify which level you generally prefer= . -When you turn Font Lock mode on/off the buffer is fontified/defontified, t= hough -fontification occurs only if the buffer is less than `font-lock-maximum-si= ze'. - -For example, to specify that Font Lock mode use use Lazy Lock mode as a su= pport -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 highlight= ing -selected automatically via the variable `font-lock-maximum-decoration', yo= u can -use `font-lock-add-keywords'. - -To fontify a buffer, without turning on Font Lock mode and regardless of b= uffer -size, you can use \\[font-lock-fontify-buffer]. - -To fontify a block (the function or paragraph containing point, or a numbe= r of -lines around point), perhaps because modification on the current line caus= ed -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 runnin= g a - ;; batch job) or if the buffer is invisible (the name starts with a spac= e). - (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))))))) =0C -;;; Global Font Lock mode. - -;; A few people have hassled in the past for a way to make it easier to tu= rn on -;; Font Lock mode, without the user needing to know for which modes s/he h= as 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 w= hich -;; 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 gros= s -;; hack, but it generally works. We use the convention that major modes s= tart -;; 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 t= his -;; hook is run, the major mode is in the process of being changed and we d= o not -;; know what the final major mode will be. So, `font-lock-change-major-mo= de' -;; only (a) notes the name of the current buffer, and (b) adds our functio= n -;; `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 ma= jor -;; mode is assumed to be in place. This way we get a Font Lock function r= un -;; when a major mode is turned on, without knowing major modes or their ho= oks. -;; -;; Naturally this requires that (a) major modes run `kill-all-local-variab= les', -;; as they are supposed to do, and (b) the major mode is in place after th= e -;; 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 wh= y (b) -;; would not be met (except `gnudoit' on non-files). However, it is not c= lean. -;; -;; 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 advis= ed, -;; 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 RE= T 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 becau= se -;; 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 o= n. -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)))) =20 -;;;###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. -=0C -;;; 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-buff= er' -;; 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 fontifica= tion -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 (symb= ol -`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-mod= e)) -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. =0C -;;; Fontification functions. =20 -;; Rather than the function, e.g., `font-lock-fontify-region' containing t= he -;; 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'. Norm= ally, -;; 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' c= ould -;; do anything. The indirection of the fontification functions gives majo= r -;; modes the capability of modifying the way font-lock.el fontifies. Majo= r -;; modes can modify the values of, e.g., `font-lock-fontify-region-functio= n', -;; 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 func= tion -;; makes fontification be on a message-by-message basis and so visiting an -;; RMAIL file is much faster. A clever implementation of the function mig= ht -;; 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 differen= tly -;; depending on its context. For example, Perl mode could arrange that he= re -;; docs are fontified differently than Perl code. Or Yacc mode could font= ify -;; rules one way and C code another. Neat! -;; -;; A further reason to use the fontification indirection feature is when t= he -;; default syntactual fontification, or the default fontification in gener= al, -;; is not flexible enough for a particular major mode. For example, perha= ps -;; 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-l= ine -;; directives correctly and cleanly. (It is the same problem as fontifyin= g -;; multi-line strings and comments; regexps are not appropriate for the jo= b.) - -;;;###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. =20 (defun font-lock-default-fontify-region (beg end loudly) (save-buffer-state @@ -1248,41 +692,6 @@ ;; Clean up. (set-syntax-table old-syntax-table)))) =20 -;; The following must be rethought, since keywords can override fontificat= ion. -; ;; 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 @@ =20 (define-key facemenu-keymap "\M-g" 'font-lock-fontify-block) =20 -;;; End of Fontification functions. +;; The following must be rethought, since keywords can override fontificat= ion. +; ;; 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)) =0C ;;; Additional text property functions. =20 @@ -1718,17 +1133,8 @@ (t (car keywords)))) =20 -(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)))) =0C ;;; 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) +=0C +;; 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 . SI= ZE), +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 meg= abyte +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 . LE= VEL), +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 messag= es." + :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 keywor= ds 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 fontifyi= ng. +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, f= or +keyword and syntactic fontification (see `modify-syntax-entry'). + +If SYNTAX-BEGIN is non-nil, it should be a function with no args used to m= ove +backwards outside any enclosing syntactic block, for syntactic fontificati= on. +Typical values are `beginning-of-line' (i.e., the start of the line is kno= wn to +be outside a syntactic block), or `beginning-of-defun' for programming mod= es 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 bu= ffer +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-buffe= r + "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-b= uffer + "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-regio= n + "Function to use for fontifying a region. +It should take two args, the beginning and end of the region, and an optio= nal +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-r= egion + "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 o= n 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'. Whe= re +major modes support different levels of fontification, you can use the var= iable +`font-lock-maximum-decoration' to specify which level you generally prefer= . +When you turn Font Lock mode on/off the buffer is fontified/defontified, t= hough +fontification occurs only if the buffer is less than `font-lock-maximum-si= ze'. + +For example, to specify that Font Lock mode use use Lazy Lock mode as a su= pport +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 highlight= ing +selected automatically via the variable `font-lock-maximum-decoration', yo= u can +use `font-lock-add-keywords'. + +To fontify a buffer, without turning on Font Lock mode and regardless of b= uffer +size, you can use \\[font-lock-fontify-buffer]. + +To fontify a block (the function or paragraph containing point, or a numbe= r of +lines around point), perhaps because modification on the current line caus= ed +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 runnin= g a + ;; batch job) or if the buffer is invisible (the name starts with a spac= e). + (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-si= ze" + (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 tu= rn on +;; Font Lock mode, without the user needing to know for which modes s/he h= as 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 w= hich +;; 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 gros= s +;; hack, but it generally works. We use the convention that major modes s= tart +;; 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 t= his +;; hook is run, the major mode is in the process of being changed and we d= o not +;; know what the final major mode will be. So, `font-lock-change-major-mo= de' +;; only (a) notes the name of the current buffer, and (b) adds our functio= n +;; `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 ma= jor +;; mode is assumed to be in place. This way we get a Font Lock function r= un +;; when a major mode is turned on, without knowing major modes or their ho= oks. +;; +;; Naturally this requires that (a) major modes run `kill-all-local-variab= les', +;; as they are supposed to do, and (b) the major mode is in place after th= e +;; 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 wh= y (b) +;; would not be met (except `gnudoit' on non-files). However, it is not c= lean. +;; +;; 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 advis= ed, +;; 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 RE= T 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 becau= se +;; 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 o= n. +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-buff= er' +;; 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 fontifica= tion +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 (symb= ol +`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-mod= e)) +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 t= he +;; 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'. Norm= ally, +;; 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' c= ould +;; do anything. The indirection of the fontification functions gives majo= r +;; modes the capability of modifying the way font-lock.el fontifies. Majo= r +;; modes can modify the values of, e.g., `font-lock-fontify-region-functio= n', +;; 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 func= tion +;; makes fontification be on a message-by-message basis and so visiting an +;; RMAIL file is much faster. A clever implementation of the function mig= ht +;; 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 differen= tly +;; depending on its context. For example, Perl mode could arrange that he= re +;; docs are fontified differently than Perl code. Or Yacc mode could font= ify +;; rules one way and C code another. Neat! +;; +;; A further reason to use the fontification indirection feature is when t= he +;; default syntactual fontification, or the default fontification in gener= al, +;; is not flexible enough for a particular major mode. For example, perha= ps +;; 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-l= ine +;; directives correctly and cleanly. (It is the same problem as fontifyin= g +;; multi-line strings and comments; regexps are not appropriate for the jo= b.) + +(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))) + +=0C +(eval-when-compile + ;; + ;; We don't do this at the top-level as we only use non-autoloaded macro= s. + (require 'cl) + ;; + ;; Borrowed from lazy-lock.el. + ;; We use this to preserve or protect things when modifying text propert= ies. + (defmacro save-buffer-state (varlist &rest body) + "Bind variables according to VARLIST and eval BODY restoring buffer st= ate." + (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 + --=-5skm+6LKpXSRjDW/acow--