Suppress spurious second invocation of before-change-functions
[bpt/emacs.git] / lisp / font-core.el
1 ;;; font-core.el --- Core interface to font-lock
2
3 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4 ;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 ;; Free Software Foundation, Inc.
6
7 ;; Maintainer: FSF
8 ;; Keywords: languages, faces
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or
15 ;; (at your option) any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24
25 ;;; Code:
26
27 ;; This variable is used by mode packages that support Font Lock mode by
28 ;; defining their own keywords to use for `font-lock-keywords'. (The mode
29 ;; command should make it buffer-local and set it to provide the set up.)
30 (defvar font-lock-defaults nil
31 "Defaults for Font Lock mode specified by the major mode.
32 Defaults should be of the form:
33
34 (KEYWORDS [KEYWORDS-ONLY [CASE-FOLD [SYNTAX-ALIST [SYNTAX-BEGIN ...]]]])
35
36 KEYWORDS may be a symbol (a variable or function whose value is the keywords
37 to use for fontification) or a list of symbols (specifying different levels
38 of fontification).
39
40 If KEYWORDS-ONLY is non-nil, syntactic fontification (strings and
41 comments) is not performed.
42
43 If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
44
45 If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
46 \(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
47 keyword and syntactic fontification (see `modify-syntax-entry').
48
49 If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
50 backwards outside any enclosing syntactic block, for syntactic fontification.
51 Typical values are `beginning-of-line' (i.e., the start of the line is known to
52 be outside a syntactic block), or `beginning-of-defun' for programming modes or
53 `backward-paragraph' for textual modes (i.e., the mode-dependent function is
54 known to move outside a syntactic block). If nil, the beginning of the buffer
55 is used as a position outside of a syntactic block, in the worst case.
56
57 \(See also Info node `(elisp)Font Lock Basics'.)
58
59 These item elements are used by Font Lock mode to set the variables
60 `font-lock-keywords', `font-lock-keywords-only',
61 `font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
62 `font-lock-beginning-of-syntax-function', respectively.
63
64 Further item elements are alists of the form (VARIABLE . VALUE) and are in no
65 particular order. Each VARIABLE is made buffer-local before set to VALUE.
66
67 Currently, appropriate variables include `font-lock-mark-block-function'.
68 If this is non-nil, it should be a function with no args used to mark any
69 enclosing block of text, for fontification via \\[font-lock-fontify-block].
70 Typical values are `mark-defun' for programming modes or `mark-paragraph' for
71 textual modes (i.e., the mode-dependent function is known to put point and mark
72 around a text block relevant to that mode).
73
74 Other variables include that for syntactic keyword fontification,
75 `font-lock-syntactic-keywords' and those for buffer-specialized fontification
76 functions, `font-lock-fontify-buffer-function',
77 `font-lock-unfontify-buffer-function', `font-lock-fontify-region-function',
78 `font-lock-unfontify-region-function', and `font-lock-inhibit-thing-lock'.")
79 ;;;###autoload
80 (put 'font-lock-defaults 'risky-local-variable t)
81 (make-variable-buffer-local 'font-lock-defaults)
82
83 (defvar font-lock-defaults-alist nil
84 "Alist of fall-back Font Lock defaults for major modes.
85
86 Each item should be a list of the form:
87
88 (MAJOR-MODE . FONT-LOCK-DEFAULTS)
89
90 where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default
91 settings. See the variable `font-lock-defaults', which takes precedence.")
92 (make-obsolete-variable 'font-lock-defaults-alist 'font-lock-defaults "21.1")
93
94 (defvar font-lock-function 'font-lock-default-function
95 "A function which is called when `font-lock-mode' is toggled.
96 It will be passed one argument, which is the current value of
97 `font-lock-mode'.")
98
99 ;; The mode for which font-lock was initialized, or nil if none.
100 (defvar font-lock-mode-major-mode)
101 (define-minor-mode font-lock-mode
102 "Toggle Font Lock mode.
103 With arg, turn Font Lock mode off if and only if arg is a non-positive
104 number; if arg is nil, toggle Font Lock mode; anything else turns Font
105 Lock on.
106 \(Font Lock is also known as \"syntax highlighting\".)
107
108 When Font Lock mode is enabled, text is fontified as you type it:
109
110 - Comments are displayed in `font-lock-comment-face';
111 - Strings are displayed in `font-lock-string-face';
112 - Certain other expressions are displayed in other faces according to the
113 value of the variable `font-lock-keywords'.
114
115 To customize the faces (colors, fonts, etc.) used by Font Lock for
116 fontifying different parts of buffer text, use \\[customize-face].
117
118 You can enable Font Lock mode in any major mode automatically by turning on in
119 the major mode's hook. For example, put in your ~/.emacs:
120
121 (add-hook 'c-mode-hook 'turn-on-font-lock)
122
123 Alternatively, you can use Global Font Lock mode to automagically turn on Font
124 Lock mode in buffers whose major mode supports it and whose major mode is one
125 of `font-lock-global-modes'. For example, put in your ~/.emacs:
126
127 (global-font-lock-mode t)
128
129 Where major modes support different levels of fontification, you can use
130 the variable `font-lock-maximum-decoration' to specify which level you
131 generally prefer. When you turn Font Lock mode on/off the buffer is
132 fontified/defontified, though fontification occurs only if the buffer is
133 less than `font-lock-maximum-size'.
134
135 To add your own highlighting for some major mode, and modify the highlighting
136 selected automatically via the variable `font-lock-maximum-decoration', you can
137 use `font-lock-add-keywords'.
138
139 To fontify a buffer, without turning on Font Lock mode and regardless of buffer
140 size, you can use \\[font-lock-fontify-buffer].
141
142 To fontify a block (the function or paragraph containing point, or a number of
143 lines around point), perhaps because modification on the current line caused
144 syntactic change on other lines, you can use \\[font-lock-fontify-block].
145
146 See the variable `font-lock-defaults-alist' for the Font Lock mode default
147 settings. You can set your own default settings for some mode, by setting a
148 buffer local value for `font-lock-defaults', via its mode hook.
149
150 The above is the default behavior of `font-lock-mode'; you may specify
151 your own function which is called when `font-lock-mode' is toggled via
152 `font-lock-function'. "
153 nil nil nil
154 ;; Don't turn on Font Lock mode if we don't have a display (we're running a
155 ;; batch job) or if the buffer is invisible (the name starts with a space).
156 (when (or noninteractive (eq (aref (buffer-name) 0) ?\s))
157 (setq font-lock-mode nil))
158 (funcall font-lock-function font-lock-mode)
159 ;; Arrange to unfontify this buffer if we change major mode later.
160 (if font-lock-mode
161 (add-hook 'change-major-mode-hook 'font-lock-change-mode nil t)
162 (remove-hook 'change-major-mode-hook 'font-lock-change-mode t))
163 (when font-lock-mode
164 (setq font-lock-mode-major-mode major-mode)))
165
166 ;; Get rid of fontification for the old major mode.
167 ;; We do this when changing major modes.
168 (defun font-lock-change-mode ()
169 (font-lock-mode -1))
170
171 (defun font-lock-defontify ()
172 "Clear out all `font-lock-face' properties in current buffer.
173 A major mode that uses `font-lock-face' properties might want to put
174 this function onto `change-major-mode-hook'."
175 (let ((modp (buffer-modified-p))
176 (inhibit-read-only t))
177 (save-restriction
178 (widen)
179 (remove-list-of-text-properties (point-min) (point-max)
180 '(font-lock-face)))
181 (restore-buffer-modified-p modp)))
182
183 (defvar font-lock-set-defaults)
184 (defun font-lock-default-function (mode)
185 ;; Turn on Font Lock mode.
186 (when mode
187 (set (make-local-variable 'char-property-alias-alist)
188 (copy-tree char-property-alias-alist))
189 ;; Add `font-lock-face' as an alias for the `face' property.
190 (let ((elt (assq 'face char-property-alias-alist)))
191 (if elt
192 (unless (memq 'font-lock-face (cdr elt))
193 (setcdr elt (nconc (cdr elt) (list 'font-lock-face))))
194 (push (list 'face 'font-lock-face) char-property-alias-alist))))
195 ;; Turn off Font Lock mode.
196 (unless mode
197 ;; Remove `font-lock-face' as an alias for the `face' property.
198 (set (make-local-variable 'char-property-alias-alist)
199 (copy-tree char-property-alias-alist))
200 (let ((elt (assq 'face char-property-alias-alist)))
201 (when elt
202 (setcdr elt (remq 'font-lock-face (cdr elt)))
203 (when (null (cdr elt))
204 (setq char-property-alias-alist
205 (delq elt char-property-alias-alist))))))
206
207 ;; Only do hard work if the mode has specified stuff in
208 ;; `font-lock-defaults'.
209 (when (or font-lock-defaults
210 (if (boundp 'font-lock-keywords) font-lock-keywords)
211 (with-no-warnings
212 (cdr (assq major-mode font-lock-defaults-alist)))
213 (and mode
214 (boundp 'font-lock-set-defaults)
215 font-lock-set-defaults
216 font-lock-mode-major-mode
217 (not (eq font-lock-mode-major-mode major-mode))))
218 (font-lock-mode-internal mode)))
219
220 (defun turn-on-font-lock ()
221 "Turn on Font Lock mode (only if the terminal can display it)."
222 (unless font-lock-mode
223 (font-lock-mode)))
224
225 ;;; Global Font Lock mode.
226
227 ;; A few people have hassled in the past for a way to make it easier to turn on
228 ;; Font Lock mode, without the user needing to know for which modes s/he has to
229 ;; turn it on, perhaps the same way hilit19.el/hl319.el does. I've always
230 ;; balked at that way, as I see it as just re-moulding the same problem in
231 ;; another form. That is; some person would still have to keep track of which
232 ;; modes (which may not even be distributed with Emacs) support Font Lock mode.
233 ;; The list would always be out of date. And that person might have to be me.
234
235 ;; Implementation.
236 ;;
237 ;; In a previous discussion the following hack came to mind. It is a gross
238 ;; hack, but it generally works. We use the convention that major modes start
239 ;; by calling the function `kill-all-local-variables', which in turn runs
240 ;; functions on the hook variable `change-major-mode-hook'. We attach our
241 ;; function `font-lock-change-major-mode' to that hook. Of course, when this
242 ;; hook is run, the major mode is in the process of being changed and we do not
243 ;; know what the final major mode will be. So, `font-lock-change-major-mode'
244 ;; only (a) notes the name of the current buffer, and (b) adds our function
245 ;; `turn-on-font-lock-if-desired' to the hook variables
246 ;; `after-change-major-mode-hook' and `post-command-hook' (for modes
247 ;; that do not yet run `after-change-major-mode-hook'). By the time
248 ;; the functions on the first of these hooks to be run are run, the new major
249 ;; mode is assumed to be in place. This way we get a Font Lock function run
250 ;; when a major mode is turned on, without knowing major modes or their hooks.
251 ;;
252 ;; Naturally this requires that major modes run `kill-all-local-variables'
253 ;; and `after-change-major-mode-hook', as they are supposed to. For modes
254 ;; that do not run `after-change-major-mode-hook' yet, `post-command-hook'
255 ;; takes care of things if the mode is set directly or indirectly by
256 ;; an interactive command; however, problems can occur if the mode is
257 ;; set by a timer or process: in that case, proper handling of Font Lock mode
258 ;; may be delayed until the next interactive command.
259
260 ;; User interface.
261 ;;
262 ;; Although Global Font Lock mode is a pseudo-mode, I think that the user
263 ;; interface should conform to the usual Emacs convention for modes, i.e., a
264 ;; command to toggle the feature (`global-font-lock-mode') with a variable for
265 ;; finer control of the mode's behavior (`font-lock-global-modes').
266 ;;
267 ;; The feature should not be enabled by loading font-lock.el, since other
268 ;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
269 ;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
270 ;; turned on everywhere. That would not be intuitive or informative because
271 ;; loading a file tells you nothing about the feature or how to control it. It
272 ;; would also be contrary to the Principle of Least Surprise. sm.
273
274 (defcustom font-lock-global-modes t
275 "Modes for which Font Lock mode is automagically turned on.
276 Global Font Lock mode is controlled by the command `global-font-lock-mode'.
277 If nil, means no modes have Font Lock mode automatically turned on.
278 If t, all modes that support Font Lock mode have it automatically turned on.
279 If a list, it should be a list of `major-mode' symbol names for which Font Lock
280 mode should be automatically turned on. The sense of the list is negated if it
281 begins with `not'. For example:
282 (c-mode c++-mode)
283 means that Font Lock mode is turned on for buffers in C and C++ modes only."
284 :type '(choice (const :tag "none" nil)
285 (const :tag "all" t)
286 (set :menu-tag "mode specific" :tag "modes"
287 :value (not)
288 (const :tag "Except" not)
289 (repeat :inline t (symbol :tag "mode"))))
290 :group 'font-lock)
291
292 (defun turn-on-font-lock-if-desired ()
293 (when (cond ((eq font-lock-global-modes t)
294 t)
295 ((eq (car-safe font-lock-global-modes) 'not)
296 (not (memq major-mode (cdr font-lock-global-modes))))
297 (t (memq major-mode font-lock-global-modes)))
298 (let (inhibit-quit)
299 (turn-on-font-lock))))
300
301 (define-globalized-minor-mode global-font-lock-mode
302 font-lock-mode turn-on-font-lock-if-desired
303 ;; What was this :extra-args thingy for? --Stef
304 ;; :extra-args (dummy)
305 :initialize 'custom-initialize-delay
306 :init-value (not (or noninteractive emacs-basic-display))
307 :group 'font-lock
308 :version "22.1")
309
310 ;;; End of Global Font Lock mode.
311
312 (provide 'font-core)
313
314 ;; arch-tag: f8c286e1-02f7-41d9-b89b-1b67780aed71
315 ;;; font-core.el ends here