Mercurial > emacs
annotate lisp/lazy-lock.el @ 16203:5a8275a74b25
(tq-filter): Add unwind-protect and save-match-data.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 15 Sep 1996 18:38:49 +0000 |
parents | aa9675ed8ed4 |
children | f4429e6fe33c |
rev | line source |
---|---|
15461 | 1 ;;; lazy-lock.el --- Lazy demand-driven fontification for fast Font Lock mode. |
2 | |
3 ;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Simon Marshall <simon@gnu.ai.mit.edu> | |
6 ;; Keywords: faces files | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
7 ;; Version: 2.06 |
15461 | 8 |
9 ;;; This file is part of GNU Emacs. | |
10 | |
11 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
12 ;; it under the terms of the GNU General Public License as published by | |
13 ;; the Free Software Foundation; either version 2, or (at your option) | |
14 ;; any later version. | |
15 | |
16 ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 ;; GNU General Public License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
24 ;; Boston, MA 02111-1307, USA. | |
25 | |
26 ;;; Commentary: | |
27 | |
28 ;; Purpose: | |
29 ;; | |
30 ;; To make visiting buffers in `font-lock-mode' faster by making fontification | |
31 ;; be demand-driven, deferred and stealthy. | |
32 ;; Fontification only occurs when, and where, necessary. | |
33 ;; | |
34 ;; See caveats and feedback below. | |
35 ;; See also the fast-lock package. (But don't use them at the same time!) | |
36 | |
37 ;; Installation: | |
38 ;; | |
39 ;; Put in your ~/.emacs: | |
40 ;; | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
41 ;; (setq font-lock-support-mode 'lazy-lock-mode) |
15461 | 42 ;; |
43 ;; Start up a new Emacs and use font-lock as usual (except that you can use the | |
44 ;; so-called "gaudier" fontification regexps on big files without frustration). | |
45 ;; | |
46 ;; In a buffer (which has `font-lock-mode' enabled) which is at least | |
47 ;; `lazy-lock-minimum-size' characters long, buffer fontification will not | |
48 ;; occur and only the visible portion of the buffer will be fontified. Motion | |
49 ;; around the buffer will fontify those visible portions not previously | |
50 ;; fontified. If stealth fontification is enabled, buffer fontification will | |
51 ;; occur in invisible parts of the buffer after `lazy-lock-stealth-time' | |
52 ;; seconds of idle time. If on-the-fly fontification is deferred, on-the-fly | |
53 ;; fontification will occur after `lazy-lock-defer-time' seconds of idle time. | |
54 | |
55 ;; User-visible differences with version 1: | |
56 ;; | |
57 ;; - Version 2 can defer on-the-fly fontification. Therefore you need not, and | |
58 ;; should not, use defer-lock.el with this version of lazy-lock.el. | |
59 ;; | |
60 ;; A number of variables have changed meaning: | |
61 ;; | |
62 ;; - A value of nil for the variable `lazy-lock-minimum-size' means never turn | |
63 ;; on demand-driven fontification. In version 1 this meant always turn on | |
64 ;; demand-driven fontification. If you really want demand-driven fontification | |
65 ;; regardless of buffer size, set this variable to 0. | |
66 ;; | |
67 ;; - The variable `lazy-lock-stealth-lines' cannot have a nil value. In | |
68 ;; version 1 this meant use `window-height' as the maximum number of lines to | |
69 ;; fontify as a stealth chunk. This makes no sense; stealth fontification is | |
70 ;; of a buffer, not a window. | |
71 | |
72 ;; Implementation differences with version 1: | |
73 ;; | |
74 ;; - Version 1 of lazy-lock.el is a bit of a hack. Version 1 demand-driven | |
75 ;; fontification, the core feature of lazy-lock.el, is implemented by placing a | |
76 ;; function on `post-command-hook'. This function fontifies where necessary, | |
77 ;; i.e., where a window scroll has occurred. However, there are a number of | |
78 ;; problems with using `post-command-hook': | |
79 ;; | |
80 ;; (a) As the name suggests, `post-command-hook' is run after every command, | |
81 ;; i.e., frequently and regardless of whether scrolling has occurred. | |
82 ;; (b) Scrolling can occur during a command, when `post-command-hook' is not | |
83 ;; run, i.e., it is not necessarily run after scrolling has occurred. | |
84 ;; (c) When `post-command-hook' is run, there is nothing to suggest where | |
85 ;; scrolling might have occurred, i.e., which windows have scrolled. | |
86 ;; | |
87 ;; Thus lazy-lock.el's function is called almost as often as possible, usually | |
88 ;; when it need not be called, yet it is not always called when it is needed. | |
89 ;; Also, lazy-lock.el's function must check each window to see if a scroll has | |
90 ;; occurred there. Worse still, lazy-lock.el's function must fontify a region | |
91 ;; twice as large as necessary to make sure the window is completely fontified. | |
92 ;; Basically, `post-command-hook' is completely inappropriate for lazy-lock.el. | |
93 ;; | |
94 ;; Ideally, we want to attach lazy-lock.el's function to a hook that is run | |
95 ;; only when scrolling occurs, e.g., `window-start' has changed, and tells us | |
96 ;; as much information as we need, i.e., the window and its new buffer region. | |
97 ;; Richard Stallman implemented a `window-scroll-functions' for Emacs 19.30. | |
98 ;; Functions on it are run when `window-start' has changed, and are supplied | |
99 ;; with the window and the window's new `window-start' position. (It would be | |
100 ;; better if it also supplied the window's new `window-end' position, but that | |
101 ;; is calculated as part of the redisplay process, and the functions on | |
102 ;; `window-scroll-functions' are run before redisplay has finished.) Thus, the | |
103 ;; hook deals with the above problems (a), (b) and (c). | |
104 ;; | |
105 ;; If only life was that easy. Version 2 demand-driven fontification is mostly | |
106 ;; implemented by placing a function on `window-scroll-functions'. However, | |
107 ;; not all scrolling occurs when `window-start' has changed. A change in | |
108 ;; window size, e.g., via C-x 1, or a significant deletion, e.g., of a number | |
109 ;; of lines, causes `window-end' to change without changing `window-start'. | |
110 ;; Arguably, these events are not scrolling events, but fontification must | |
111 ;; occur for lazy-lock.el to work. Hooks `window-size-change-functions' and | |
112 ;; `redisplay-end-trigger-functions' were added for these circumstances. | |
113 ;; | |
114 ;; Ben Wing thinks these hooks are "horribly horribly kludgy", and implemented | |
115 ;; a `pre-idle-hook', a `mother-of-all-post-command-hooks', for XEmacs 19.14. | |
116 ;; He then hacked up a version 1 lazy-lock.el to use `pre-idle-hook' rather | |
117 ;; than `post-command-hook'. Whereas functions on `post-command-hook' are | |
118 ;; called almost as often as possible, functions on `pre-idle-hook' really are | |
119 ;; called as often as possible, even when the mouse moves and, on some systems, | |
120 ;; while XEmacs is idle. Thus, the hook deals with the above problem (b), but | |
121 ;; unfortunately it makes (a) worse and does not address (c) at all. | |
122 ;; | |
123 ;; I freely admit that `redisplay-end-trigger-functions' and, to a much lesser | |
124 ;; extent, `window-size-change-functions' are not pretty. However, I feel that | |
125 ;; a `window-scroll-functions' feature is cleaner than a `pre-idle-hook', and | |
126 ;; the result is faster and smaller, less intrusive and more targeted, code. | |
127 ;; Since `pre-idle-hook' is pretty much like `post-command-hook', there is no | |
128 ;; point in making this version of lazy-lock.el work with it. Anyway, that's | |
129 ;; Lit 30 of my humble opinion. | |
130 ;; | |
131 ;; - Version 1 stealth fontification is also implemented by placing a function | |
132 ;; on `post-command-hook'. This function waits for a given amount of time, | |
133 ;; and, if Emacs remains idle, fontifies where necessary. Again, there are a | |
134 ;; number of problems with using `post-command-hook': | |
135 ;; | |
136 ;; (a) Functions on `post-command-hook' are run sequentially, so this function | |
137 ;; can interfere with other functions on the hook, and vice versa. | |
138 ;; (b) This function waits for a given amount of time, so it can interfere with | |
139 ;; various features that are dealt with by Emacs after a command, e.g., | |
140 ;; region highlighting, asynchronous updating and keystroke echoing. | |
141 ;; (c) Fontification may be required during a command, when `post-command-hook' | |
142 ;; is not run. (Version 2 deferred fontification only.) | |
143 ;; | |
144 ;; Again, `post-command-hook' is completely inappropriate for lazy-lock.el. | |
145 ;; Richard Stallman and Morten Welinder implemented internal Timers and Idle | |
146 ;; Timers for Emacs 19.31. Functions can be run independently at given times | |
147 ;; or after given amounts of idle time. Thus, the feature deals with the above | |
148 ;; problems (a), (b) and (c). Version 2 deferral and stealth are implemented | |
149 ;; by functions on Idle Timers. (A function on XEmacs' `pre-idle-hook' is | |
150 ;; similar to an Emacs Idle Timer function with a fixed zero second timeout. | |
151 ;; Hey, maybe I could stop using `window-scroll-functions' for demand-driven | |
152 ;; fontification and use a zero second Emacs Idle Timer instead? Only joking!) | |
153 | |
154 ;; Caveats: | |
155 ;; | |
156 ;; Lazy Lock mode does not work efficiently with Outline mode. This is because | |
157 ;; when in Outline mode, although text may be hidden (not visible in the | |
158 ;; window), the text is visible to Emacs Lisp code (not surprisingly) and Lazy | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
159 ;; Lock fontifies it mercilessly. Maybe it will be fixed one day. |
15461 | 160 ;; |
161 ;; Because buffer text is not necessarily fontified, other packages that expect | |
162 ;; buffer text to be fontified in Font Lock mode either might not work as | |
163 ;; expected, or might not display buffer text as expected. An example of the | |
164 ;; latter is `occur', which copies lines of buffer text into another buffer. | |
165 ;; | |
166 ;; In Emacs 19.30, Lazy Lock mode does not ensure that an existing buffer is | |
167 ;; fontified if it is made visible via a minibuffer-less command that replaces | |
168 ;; an existing window's buffer (e.g., via the Buffers menu). Upgrade! | |
169 ;; | |
170 ;; In Emacs 19.30, Lazy Lock mode does not work well with Transient Mark mode | |
171 ;; or modes based on Comint mode (e.g., Shell mode), and also interferes with | |
172 ;; the echoing of keystrokes in the minibuffer. This is because of the way | |
173 ;; deferral and stealth have to be implemented for Emacs 19.30. Upgrade! | |
174 ;; | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
175 ;; Currently XEmacs does not have the features to support this version of |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
176 ;; lazy-lock.el. Maybe it will one day. |
15461 | 177 |
178 ;; Feedback: | |
179 ;; | |
180 ;; Feedback is welcome. | |
181 ;; To submit a bug report (or make comments) please use the mechanism provided: | |
182 ;; | |
183 ;; M-x lazy-lock-submit-bug-report RET | |
184 | |
185 ;; History: | |
186 ;; | |
187 ;; 1.15--2.00: | |
188 ;; - Rewrite for Emacs 19.30 and the features rms added to support lazy-lock.el | |
189 ;; so that it could work correctly and efficiently. | |
190 ;; - Many thanks to those who reported bugs, fixed bugs, made suggestions or | |
191 ;; otherwise contributed in the version 1 cycle; Jari Aalto, Kevin Broadey, | |
192 ;; Ulrik Dickow, Bill Dubuque, Bob Glickstein, Boris Goldowsky, | |
193 ;; Jonas Jarnestrom, David Karr, Michael Kifer, Erik Naggum, Rick Sladkey, | |
194 ;; Jim Thompson, Ben Wing, Ilya Zakharevich, and Richard Stallman. | |
195 ;; 2.00--2.01: | |
196 ;; - Made `lazy-lock-fontify-after-command' always `sit-for' and so redisplay | |
197 ;; - Use `buffer-name' not `buffer-live-p' (Bill Dubuque hint) | |
198 ;; - Made `lazy-lock-install' do `add-to-list' not `setq' of `current-buffer' | |
199 ;; - Made `lazy-lock-fontify-after-install' loop over buffer list | |
200 ;; - Made `lazy-lock-arrange-before-change' to arrange `window-end' triggering | |
201 ;; - Made `lazy-lock-let-buffer-state' wrap both `befter-change-functions' | |
202 ;; - Made `lazy-lock-fontify-region' do `condition-case' (Hyman Rosen report) | |
203 ;; 2.01--2.02: | |
204 ;; - Use `buffer-live-p' as `buffer-name' can barf (Richard Stanton report) | |
205 ;; - Made `lazy-lock-install' set `font-lock-fontified' (Kevin Davidson report) | |
206 ;; - Made `lazy-lock-install' add hooks only if needed | |
207 ;; - Made `lazy-lock-unstall' add `font-lock-after-change-function' if needed | |
208 ;; 2.02--2.03: | |
209 ;; - Made `lazy-lock-fontify-region' do `condition-case' for `quit' too | |
210 ;; - Made `lazy-lock-mode' respect the value of `font-lock-inhibit-thing-lock' | |
211 ;; - Added `lazy-lock-after-unfontify-buffer' | |
212 ;; - Removed `lazy-lock-fontify-after-install' hack | |
213 ;; - Made `lazy-lock-fontify-after-scroll' not `set-buffer' to `window-buffer' | |
214 ;; - Made `lazy-lock-fontify-after-trigger' not `set-buffer' to `window-buffer' | |
215 ;; - Made `lazy-lock-fontify-after-idle' be interruptible (Scott Burson hint) | |
216 ;; 2.03--2.04: | |
217 ;; - Rewrite for Emacs 19.31 idle timers | |
218 ;; - Renamed `buffer-windows' to `get-buffer-window-list' | |
219 ;; - Removed `buffer-live-p' | |
220 ;; - Made `lazy-lock-defer-after-change' always save `current-buffer' | |
221 ;; - Made `lazy-lock-fontify-after-defer' just process buffers | |
222 ;; - Made `lazy-lock-install-hooks' add hooks correctly (Kevin Broadey report) | |
223 ;; - Made `lazy-lock-install' cope if `lazy-lock-defer-time' is a list | |
224 ;; 2.04--2.05: | |
225 ;; - Rewrite for Common Lisp macros | |
226 ;; - Added `do-while' macro | |
227 ;; - Renamed `lazy-lock-let-buffer-state' macro to `save-buffer-state' | |
228 ;; - Returned `lazy-lock-fontify-after-install' hack (Darren Hall hint) | |
229 ;; - Added `lazy-lock-defer-driven' functionality (Scott Byer hint) | |
230 ;; - Made `lazy-lock-mode' wrap `font-lock-support-mode' | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
231 ;; 2.05--2.06: |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
232 ;; - Made `lazy-lock-fontify-after-defer' swap correctly (Scott Byer report) |
15461 | 233 |
234 (require 'font-lock) | |
235 | |
236 ;; Make sure lazy-lock.el is supported. | |
237 (if (if (save-match-data (string-match "Lucid\\|XEmacs" (emacs-version))) | |
238 t | |
239 (and (= emacs-major-version 19) (< emacs-minor-version 30))) | |
240 (error "`lazy-lock' was written for Emacs 19.30 or later")) | |
241 | |
242 ;; Flush out those lusers who didn't read all of the Commentary. | |
243 (if (or (memq 'turn-on-defer-lock font-lock-mode-hook) | |
244 (memq 'defer-lock-mode font-lock-mode-hook)) | |
245 (error "`lazy-lock' was written for use without `defer-lock'")) | |
246 | |
247 (eval-when-compile | |
248 ;; | |
249 ;; We don't do this at the top-level as idle timers are not necessarily used. | |
250 (require 'timer) | |
251 ;; We don't do this at the top-level as we only use non-autoloaded macros. | |
252 (require 'cl) | |
253 ;; | |
254 ;; Well, shouldn't Lazy Lock mode be as lazy as possible? | |
255 (setq byte-compile-dynamic t byte-compile-dynamic-docstrings t) | |
256 ;; But, we make sure that the code is as zippy as can be. | |
257 (setq byte-optimize t) | |
258 ;; | |
259 ;; We use this to preserve or protect things when modifying text properties. | |
260 (defmacro save-buffer-state (varlist &rest body) | |
261 "Bind variables according to VARLIST and eval BODY restoring buffer state." | |
262 (` (let* ((,@ (append varlist | |
263 '((modified (buffer-modified-p)) | |
264 (inhibit-read-only t) (buffer-undo-list t) | |
265 before-change-functions after-change-functions | |
266 deactivate-mark buffer-file-name buffer-file-truename)))) | |
267 (,@ body) | |
268 (when (and (not modified) (buffer-modified-p)) | |
269 (set-buffer-modified-p nil))))) | |
270 (put 'save-buffer-state 'lisp-indent-function 1) | |
271 ;; | |
272 ;; We use this for clarity and speed. Naughty but nice. | |
273 (defmacro do-while (test &rest body) | |
274 "(do-while TEST BODY...): eval BODY... and repeat if TEST yields non-nil. | |
275 The order of execution is thus BODY, TEST, BODY, TEST and so on | |
276 until TEST returns nil." | |
277 (` (while (progn (,@ body) (, test))))) | |
278 (put 'do-while 'lisp-indent-function (get 'while 'lisp-indent-function))) | |
279 | |
280 ;; User Variables: | |
281 | |
282 (defvar lazy-lock-minimum-size (* 25 1024) | |
283 "*Minimum size of a buffer for demand-driven fontification. | |
284 On-demand fontification occurs if the buffer size is greater than this value. | |
285 If nil, means demand-driven fontification is never performed. | |
286 If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE), | |
287 where MAJOR-MODE is a symbol or t (meaning the default). For example: | |
288 ((c-mode . 25600) (c++-mode . 25600) (rmail-mode . 1048576)) | |
289 means that the minimum size is 25K for buffers in C or C++ modes, one megabyte | |
290 for buffers in Rmail mode, and size is irrelevant otherwise. | |
291 | |
292 The value of this variable is used when Lazy Lock mode is turned on.") | |
293 | |
294 (defvar lazy-lock-defer-driven nil | |
295 "*If non-nil, means fontification should be defer-driven. | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
296 If nil, means demand-driven fontification is performed. This means when |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
297 scrolling into unfontified areas of the buffer, those areas are immediately |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
298 fontified. Thus scrolling never presents unfontified areas. However, since |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
299 fontification occurs during scrolling, scrolling may be slow. |
15461 | 300 If t, means defer-driven fontification is performed. This means fontification |
301 of those areas is deferred. Thus scrolling may present momentarily unfontified | |
302 areas. However, since fontification does not occur during scrolling, scrolling | |
303 will be faster than demand-driven fontification. | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
304 If any other value, e.g., `eventually', means demand-driven fontification is |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
305 performed until the buffer is fontified, then buffer fontification becomes |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
306 defer-driven. Thus scrolling never presents unfontified areas until the buffer |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
307 is first fontified, after which subsequent scrolling may present future buffer |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
308 insertions momentarily unfontified. However, since fontification does not |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
309 occur during scrolling after the buffer is first fontified, scrolling will |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
310 become faster. |
15461 | 311 |
312 The value of this variable is used when Lazy Lock mode is turned on.") | |
313 | |
314 (defvar lazy-lock-defer-time | |
315 (if (featurep 'lisp-float-type) (/ (float 1) (float 4)) 1) | |
316 "*Time in seconds to delay before beginning deferred fontification. | |
317 Deferred fontification occurs if there is no input within this time. | |
318 If nil, means fontification is never deferred. However, fontification occurs | |
319 on-the-fly or during scrolling, which may be slow. | |
320 If a list, it should be of the form (MAJOR-MODES . TIME), where MAJOR-MODES is | |
321 a list of `major-mode' symbols for which deferred fontification should occur. | |
322 The sense of the list is negated if it begins with `not'. For example: | |
323 ((c-mode c++-mode) . 0.25) | |
324 means that the deferral time is 0.25s for buffers in C or C++ modes, and | |
325 deferral does not occur otherwise. | |
326 | |
327 The value of this variable is used when Lazy Lock mode is turned on.") | |
328 | |
329 (defvar lazy-lock-stealth-time 30 | |
330 "*Time in seconds to delay before beginning stealth fontification. | |
331 Stealth fontification occurs if there is no input within this time. | |
332 If nil, means stealth fontification is never performed. | |
333 | |
334 The value of this variable is used when Lazy Lock mode is turned on.") | |
335 | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
336 (defvar lazy-lock-stealth-lines (if font-lock-maximum-decoration 100 250) |
15461 | 337 "*Maximum size of a chunk of stealth fontification. |
338 Each iteration of stealth fontification can fontify this number of lines. | |
339 To speed up input response during stealth fontification, at the cost of stealth | |
340 taking longer to fontify, you could reduce the value of this variable.") | |
341 | |
342 (defvar lazy-lock-stealth-nice | |
343 (if (featurep 'lisp-float-type) (/ (float 1) (float 8)) 1) | |
344 "*Time in seconds to pause between chunks of stealth fontification. | |
345 Each iteration of stealth fontification is separated by this amount of time. | |
346 To reduce machine load during stealth fontification, at the cost of stealth | |
347 taking longer to fontify, you could increase the value of this variable.") | |
348 | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
349 (defvar lazy-lock-stealth-verbose (not (null font-lock-verbose)) |
15461 | 350 "*If non-nil, means stealth fontification should show status messages.") |
351 | |
352 (defvar lazy-lock-mode nil) | |
353 (defvar lazy-lock-buffers nil) ; for deferral | |
354 (defvar lazy-lock-timers (cons nil nil)) ; for deferral and stealth | |
355 | |
356 ;; User Functions: | |
357 | |
358 ;;;###autoload | |
359 (defun lazy-lock-mode (&optional arg) | |
360 "Toggle Lazy Lock mode. | |
361 With arg, turn Lazy Lock mode on if and only if arg is positive. Enable it | |
362 automatically in your `~/.emacs' by: | |
363 | |
364 (setq font-lock-support-mode 'lazy-lock-mode) | |
365 | |
366 When Lazy Lock mode is enabled, fontification can be lazy in a number of ways: | |
367 | |
368 - Demand-driven buffer fontification if `lazy-lock-minimum-size' is non-nil. | |
369 This means initial fontification does not occur if the buffer is greater | |
370 than `lazy-lock-minimum-size' characters in length. Instead, fontification | |
371 occurs when necessary, such as when scrolling through the buffer would | |
372 otherwise reveal unfontified areas. This is useful if buffer fontification | |
373 is too slow for large buffers. | |
374 | |
375 - Defer-driven buffer fontification if `lazy-lock-defer-driven' is non-nil. | |
376 This means all fontification is deferred, such as fontification that occurs | |
377 when scrolling through the buffer would otherwise reveal unfontified areas. | |
378 Instead, these areas are seen momentarily unfontified. This is useful if | |
379 demand-driven fontification is too slow to keep up with scrolling. | |
380 | |
381 - Deferred on-the-fly fontification if `lazy-lock-defer-time' is non-nil. | |
382 This means on-the-fly fontification does not occur as you type. Instead, | |
383 fontification is deferred until after `lazy-lock-defer-time' seconds of | |
384 Emacs idle time, while Emacs remains idle. This is useful if on-the-fly | |
385 fontification is too slow to keep up with your typing. | |
386 | |
387 - Stealthy buffer fontification if `lazy-lock-stealth-time' is non-nil. | |
388 This means remaining unfontified areas of buffers are fontified if Emacs has | |
389 been idle for `lazy-lock-stealth-time' seconds, while Emacs remains idle. | |
390 This is useful if any buffer has demand- or defer-driven fontification. | |
391 | |
392 See also variables `lazy-lock-stealth-lines', `lazy-lock-stealth-nice' and | |
393 `lazy-lock-stealth-verbose' for stealth fontification. | |
394 | |
395 Use \\[lazy-lock-submit-bug-report] to send bug reports or feedback." | |
396 (interactive "P") | |
397 (set (make-local-variable 'lazy-lock-mode) | |
398 (and (not (memq 'lazy-lock-mode font-lock-inhibit-thing-lock)) | |
399 (if arg (> (prefix-numeric-value arg) 0) (not lazy-lock-mode)))) | |
400 (cond ((and lazy-lock-mode (not font-lock-mode)) | |
401 ;; Turned on `lazy-lock-mode' rather than `font-lock-mode'. | |
402 (let ((font-lock-support-mode 'lazy-lock-mode)) | |
403 (font-lock-mode t))) | |
404 (lazy-lock-mode | |
405 ;; Turn ourselves on. | |
406 (lazy-lock-install)) | |
407 (t | |
408 ;; Turn ourselves off. | |
409 (lazy-lock-unstall)))) | |
410 | |
411 (defun lazy-lock-submit-bug-report () | |
412 "Submit via mail a bug report on lazy-lock.el." | |
413 (interactive) | |
414 (let ((reporter-prompt-for-summary-p t)) | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
415 (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "lazy-lock 2.06" |
15461 | 416 '(lazy-lock-minimum-size lazy-lock-defer-driven lazy-lock-defer-time |
417 lazy-lock-stealth-time lazy-lock-stealth-nice lazy-lock-stealth-lines | |
418 lazy-lock-stealth-verbose) | |
419 nil nil | |
420 (concat "Hi Si., | |
421 | |
422 I want to report a bug. I've read the `Bugs' section of `Info' on Emacs, so I | |
423 know how to make a clear and unambiguous report. To reproduce the bug: | |
424 | |
425 Start a fresh Emacs via `" invocation-name " -no-init-file -no-site-file'. | |
426 In the `*scratch*' buffer, evaluate:")))) | |
427 | |
428 ;;;###autoload | |
429 (defun turn-on-lazy-lock () | |
430 "Unconditionally turn on Lazy Lock mode." | |
431 (lazy-lock-mode t)) | |
432 | |
433 (defun lazy-lock-install () | |
434 (let ((min-size (font-lock-value-in-major-mode lazy-lock-minimum-size))) | |
435 ;; | |
436 ;; Tell Font Lock whether Lazy Lock will do fontification. | |
437 (make-local-variable 'font-lock-fontified) | |
438 (setq font-lock-fontified (and min-size (>= (buffer-size) min-size))) | |
439 ;; | |
440 ;; Add the text properties and fontify. | |
441 (if (not font-lock-fontified) | |
442 (lazy-lock-after-fontify-buffer) | |
443 ;; Make sure we fontify in any existing windows showing the buffer. | |
444 (let ((windows (get-buffer-window-list (current-buffer) 'nomini t))) | |
445 (lazy-lock-after-unfontify-buffer) | |
446 (while windows | |
447 (lazy-lock-fontify-conservatively (car windows)) | |
448 (setq windows (cdr windows))))) | |
449 ;; | |
450 ;; Add the fontification hooks. | |
451 (lazy-lock-install-hooks | |
452 (or (numberp lazy-lock-defer-time) | |
453 (if (eq (car (car lazy-lock-defer-time)) 'not) | |
454 (not (memq major-mode (cdr (car lazy-lock-defer-time)))) | |
455 (memq major-mode (car lazy-lock-defer-time)))) | |
456 font-lock-fontified | |
457 (eq lazy-lock-defer-driven t)) | |
458 ;; | |
459 ;; Add the fontification timers. | |
460 (lazy-lock-install-timers | |
461 (or (cdr-safe lazy-lock-defer-time) lazy-lock-defer-time) | |
462 lazy-lock-stealth-time))) | |
463 | |
464 (defun lazy-lock-install-hooks (deferring fontifying defer-driven) | |
465 ;; | |
466 ;; Add hook if lazy-lock.el is deferring or is fontifying on scrolling. | |
467 (when (or deferring fontifying) | |
468 (make-local-hook 'window-scroll-functions) | |
469 (add-hook 'window-scroll-functions (if (and deferring defer-driven) | |
470 'lazy-lock-defer-after-scroll | |
471 'lazy-lock-fontify-after-scroll) | |
472 nil t)) | |
473 ;; | |
474 ;; Add hook if lazy-lock.el is not deferring and is fontifying. | |
475 (when (and (not deferring) fontifying) | |
476 (make-local-hook 'before-change-functions) | |
477 (add-hook 'before-change-functions 'lazy-lock-arrange-before-change nil t)) | |
478 ;; | |
479 ;; Add hook if lazy-lock.el is deferring. | |
480 (when deferring | |
481 (remove-hook 'after-change-functions 'font-lock-after-change-function t) | |
482 (add-hook 'after-change-functions 'lazy-lock-defer-after-change nil t)) | |
483 ;; | |
484 ;; Add package-specific hooks. | |
485 (make-local-hook 'outline-view-change-hook) | |
486 (add-hook 'outline-view-change-hook 'lazy-lock-fontify-after-outline nil t)) | |
487 | |
488 (defun lazy-lock-install-timers (dtime stime) | |
489 ;; Schedule or re-schedule the deferral and stealth timers. | |
490 ;; The layout of `lazy-lock-timers' is: | |
491 ;; ((DEFER-TIME . DEFER-TIMER) (STEALTH-TIME . STEALTH-TIMER) | |
492 ;; If an idle timeout has changed, cancel the existing idle timer (if there | |
493 ;; is one) and schedule a new one (if the new idle timeout is non-nil). | |
494 (unless (eq dtime (car (car lazy-lock-timers))) | |
495 (let ((defer (car lazy-lock-timers))) | |
496 (when (cdr defer) | |
497 (cancel-timer (cdr defer))) | |
498 (setcar lazy-lock-timers (cons dtime (and dtime | |
499 (run-with-idle-timer dtime t 'lazy-lock-fontify-after-defer)))))) | |
500 (unless (eq stime (car (cdr lazy-lock-timers))) | |
501 (let ((stealth (cdr lazy-lock-timers))) | |
502 (when (cdr stealth) | |
503 (cancel-timer (cdr stealth))) | |
504 (setcdr lazy-lock-timers (cons stime (and stime | |
505 (run-with-idle-timer stime t 'lazy-lock-fontify-after-idle))))))) | |
506 | |
507 (defun lazy-lock-unstall () | |
508 ;; | |
509 ;; Remove the text properties. | |
510 (lazy-lock-after-unfontify-buffer) | |
511 ;; | |
512 ;; Remove the fontification hooks. | |
513 (remove-hook 'window-scroll-functions 'lazy-lock-fontify-after-scroll t) | |
514 (remove-hook 'window-scroll-functions 'lazy-lock-defer-after-scroll t) | |
515 (remove-hook 'before-change-functions 'lazy-lock-arrange-before-change t) | |
516 (remove-hook 'after-change-functions 'lazy-lock-defer-after-change t) | |
517 (remove-hook 'outline-view-change-hook 'lazy-lock-fontify-after-outline t) | |
518 ;; | |
519 ;; If Font Lock mode is still enabled, reinstall its hook. | |
520 (when font-lock-mode | |
521 (add-hook 'after-change-functions 'font-lock-after-change-function nil t))) | |
522 | |
523 ;; Hook functions. | |
524 | |
525 (defun lazy-lock-fontify-after-scroll (window window-start) | |
526 ;; Called from `window-scroll-functions'. | |
527 ;; Fontify WINDOW from WINDOW-START. We cannot use `window-end' so we work | |
528 ;; out what it would be via `vertical-motion'. | |
529 (save-excursion | |
530 (goto-char window-start) | |
531 (vertical-motion (window-height window) window) | |
532 (lazy-lock-fontify-region window-start (point))) | |
533 ;; A prior deletion that did not cause scrolling, followed by a scroll, would | |
534 ;; result in an unnecessary trigger after this if we did not cancel it now. | |
535 (set-window-redisplay-end-trigger window nil)) | |
536 | |
537 (defun lazy-lock-fontify-after-trigger (window trigger-point) | |
538 ;; Called from `redisplay-end-trigger-functions'. | |
539 ;; Fontify WINDOW from TRIGGER-POINT. We cannot use `window-end' so we work | |
540 ;; out what it would be via `vertical-motion'. | |
541 ;; We could probably just use `lazy-lock-fontify-after-scroll' without loss: | |
542 ;; (lazy-lock-fontify-after-scroll window (window-start window)) | |
543 (save-excursion | |
544 (goto-char (window-start window)) | |
545 (vertical-motion (window-height window) window) | |
546 (lazy-lock-fontify-region trigger-point (point)))) | |
547 | |
548 (defun lazy-lock-fontify-after-resize (frame) | |
549 ;; Called from `window-size-change-functions'. | |
550 ;; Fontify windows in FRAME. We cannot use `window-start' or `window-end' so | |
551 ;; we fontify conservatively. | |
552 (save-excursion | |
553 (save-selected-window | |
554 (select-frame frame) | |
555 (walk-windows (function (lambda (window) | |
556 (set-buffer (window-buffer window)) | |
557 (when lazy-lock-mode | |
558 (lazy-lock-fontify-conservatively window)) | |
559 (set-window-redisplay-end-trigger window nil))) | |
560 'nomini frame)))) | |
561 | |
562 (defun lazy-lock-arrange-before-change (beg end) | |
563 ;; Called from `before-change-functions'. | |
564 ;; Arrange that if text becomes visible it will be fontified (if a deletion | |
565 ;; is pending, text might become visible at the bottom). | |
566 (unless (eq beg end) | |
567 (let ((windows (get-buffer-window-list (current-buffer) 'nomini t)) window) | |
568 (while windows | |
569 (setq window (car windows)) | |
570 (unless (markerp (window-redisplay-end-trigger window)) | |
571 (set-window-redisplay-end-trigger window (make-marker))) | |
572 (set-marker (window-redisplay-end-trigger window) (window-end window)) | |
573 (setq windows (cdr windows)))))) | |
574 | |
575 (defun lazy-lock-defer-after-scroll (window window-start) | |
576 ;; Called from `window-scroll-functions'. | |
577 ;; Defer fontification following the scroll. Save the current buffer so that | |
578 ;; we subsequently fontify in all windows showing the buffer. | |
579 (unless (memq (current-buffer) lazy-lock-buffers) | |
580 (push (current-buffer) lazy-lock-buffers))) | |
581 | |
582 (defun lazy-lock-defer-after-change (beg end old-len) | |
583 ;; Called from `after-change-functions'. | |
584 ;; Defer fontification of the current line. Save the current buffer so that | |
585 ;; we subsequently fontify in all windows showing the buffer. | |
586 (save-buffer-state nil | |
587 (unless (memq (current-buffer) lazy-lock-buffers) | |
588 (push (current-buffer) lazy-lock-buffers)) | |
589 (remove-text-properties | |
590 (max (1- beg) (point-min)) (min (1+ end) (point-max)) '(lazy-lock nil)))) | |
591 | |
592 (defun lazy-lock-fontify-after-defer () | |
593 ;; Called from `timer-idle-list'. | |
594 ;; Fontify all windows where deferral has occurred for its buffer. | |
595 (while (and lazy-lock-buffers (not (input-pending-p))) | |
596 (let ((windows (get-buffer-window-list (car lazy-lock-buffers) 'nomini t))) | |
597 (while windows | |
598 (lazy-lock-fontify-window (car windows)) | |
599 (setq windows (cdr windows))) | |
600 (setq lazy-lock-buffers (cdr lazy-lock-buffers)))) | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
601 ;; Add hook if fontification should now be defer-driven in this buffer. |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
602 (when (and lazy-lock-mode lazy-lock-defer-driven |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
603 (memq 'lazy-lock-fontify-after-scroll window-scroll-functions) |
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
604 (not (or (input-pending-p) (lazy-lock-unfontified-p)))) |
15461 | 605 (remove-hook 'window-scroll-functions 'lazy-lock-fontify-after-scroll t) |
606 (add-hook 'window-scroll-functions 'lazy-lock-defer-after-scroll nil t))) | |
607 | |
608 (defun lazy-lock-fontify-after-idle () | |
609 ;; Called from `timer-idle-list'. | |
610 ;; Fontify all buffers that need it, stealthily while idle. | |
611 (unless (or executing-kbd-macro (window-minibuffer-p (selected-window))) | |
612 ;; Loop over all buffers, fontify stealthily for each if necessary. | |
613 (let ((buffers (buffer-list)) (continue t) message message-log-max) | |
614 (save-excursion | |
615 (do-while (and buffers continue) | |
616 (set-buffer (car buffers)) | |
617 (if (not (and lazy-lock-mode (lazy-lock-unfontified-p))) | |
618 (setq continue (not (input-pending-p))) | |
619 ;; Fontify regions in this buffer while there is no input. | |
620 (do-while (and (lazy-lock-unfontified-p) | |
621 (setq continue (sit-for lazy-lock-stealth-nice))) | |
622 (when lazy-lock-stealth-verbose | |
623 (if message | |
624 (message "Fontifying stealthily... %2d%% of %s" | |
625 (lazy-lock-percent-fontified) (buffer-name)) | |
626 (message "Fontifying stealthily...") | |
627 (setq message t))) | |
628 (lazy-lock-fontify-chunk))) | |
629 (setq buffers (cdr buffers)))) | |
630 (when message | |
15499
aa9675ed8ed4
Test for lazy-lock-mode before swapping hooks.
Simon Marshall <simon@gnu.org>
parents:
15461
diff
changeset
|
631 (message "Fontifying stealthily...%s" (if continue "done" "quit")))))) |
15461 | 632 |
633 (defun lazy-lock-fontify-after-outline () | |
634 ;; Called from `outline-view-change-hook'. | |
635 ;; Fontify windows showing the current buffer, as its visibility has changed. | |
636 ;; This is a conspiracy hack between lazy-lock.el and noutline.el. | |
637 (let ((windows (get-buffer-window-list (current-buffer) 'nomini t))) | |
638 (while windows | |
639 (lazy-lock-fontify-conservatively (car windows)) | |
640 (setq windows (cdr windows))))) | |
641 | |
642 (defun lazy-lock-after-fontify-buffer () | |
643 ;; Called from `font-lock-after-fontify-buffer'. | |
644 ;; Mark the current buffer as fontified. | |
645 ;; This is a conspiracy hack between lazy-lock.el and font-lock.el. | |
646 (save-buffer-state nil | |
647 (add-text-properties (point-min) (point-max) '(lazy-lock t)))) | |
648 | |
649 (defun lazy-lock-after-unfontify-buffer () | |
650 ;; Called from `font-lock-after-unfontify-buffer'. | |
651 ;; Mark the current buffer as unfontified. | |
652 ;; This is a conspiracy hack between lazy-lock.el and font-lock.el. | |
653 (save-buffer-state nil | |
654 (remove-text-properties (point-min) (point-max) '(lazy-lock nil)))) | |
655 | |
656 ;; Fontification functions. | |
657 | |
658 ;; If packages want to ensure that some region of the buffer is fontified, they | |
659 ;; should use this function. For an example, see ps-print.el. | |
660 (defun lazy-lock-fontify-region (beg end) | |
661 ;; Fontify between BEG and END, where necessary, in the current buffer. | |
662 (when (setq beg (text-property-any beg end 'lazy-lock nil)) | |
663 (save-excursion | |
664 (save-match-data | |
665 (save-buffer-state | |
666 ;; Ensure syntactic fontification is always correct. | |
667 (font-lock-beginning-of-syntax-function next) | |
668 ;; Find successive unfontified regions between BEG and END. | |
669 (condition-case data | |
670 (do-while beg | |
671 (setq next (or (text-property-any beg end 'lazy-lock t) end)) | |
672 ;; Make sure the region end points are at beginning of line. | |
673 (goto-char beg) | |
674 (unless (bolp) | |
675 (beginning-of-line) | |
676 (setq beg (point))) | |
677 (goto-char next) | |
678 (unless (bolp) | |
679 (forward-line) | |
680 (setq next (point))) | |
681 ;; Fontify the region, then flag it as fontified. | |
682 (font-lock-fontify-region beg next) | |
683 (add-text-properties beg next '(lazy-lock t)) | |
684 (setq beg (text-property-any next end 'lazy-lock nil))) | |
685 ((error quit) (message "Fontifying region...%s" data)))))))) | |
686 | |
687 (defun lazy-lock-fontify-chunk () | |
688 ;; Fontify the nearest chunk, for stealth, in the current buffer. | |
689 (save-excursion | |
690 (save-restriction | |
691 (widen) | |
692 ;; Move to end of line in case the character at point is not fontified. | |
693 (end-of-line) | |
694 ;; Find where the previous, and next, unfontified regions end, and begin. | |
695 (let ((prev (previous-single-property-change (point) 'lazy-lock)) | |
696 (next (text-property-any (point) (point-max) 'lazy-lock nil))) | |
697 ;; Fontify from the nearest unfontified position. | |
698 (if (or (null prev) (and next (< (- next (point)) (- (point) prev)))) | |
699 ;; The next, or neither, region is the nearest not fontified. | |
700 (lazy-lock-fontify-region | |
701 (progn (goto-char (or next (point-min))) | |
702 (beginning-of-line) | |
703 (point)) | |
704 (progn (goto-char (or next (point-min))) | |
705 (forward-line lazy-lock-stealth-lines) | |
706 (point))) | |
707 ;; The previous region is the nearest not fontified. | |
708 (lazy-lock-fontify-region | |
709 (progn (goto-char prev) | |
710 (forward-line (- lazy-lock-stealth-lines)) | |
711 (point)) | |
712 (progn (goto-char prev) | |
713 (forward-line) | |
714 (point)))))))) | |
715 | |
716 (defun lazy-lock-fontify-window (window) | |
717 ;; Fontify in WINDOW between `window-start' and `window-end'. | |
718 ;; We can only do this when we can use `window-start' and `window-end'. | |
719 (save-excursion | |
720 (set-buffer (window-buffer window)) | |
721 (lazy-lock-fontify-region (window-start window) (window-end window)))) | |
722 | |
723 (defun lazy-lock-fontify-conservatively (window) | |
724 ;; Fontify in WINDOW conservatively around point. | |
725 ;; Where we cannot use `window-start' and `window-end' we do `window-height' | |
726 ;; lines around point. That way we guarantee to have done enough. | |
727 (save-excursion | |
728 (set-buffer (window-buffer window)) | |
729 (lazy-lock-fontify-region | |
730 (save-excursion | |
731 (vertical-motion (- (window-height window)) window) (point)) | |
732 (save-excursion | |
733 (vertical-motion (window-height window) window) (point))))) | |
734 | |
735 (defun lazy-lock-unfontified-p () | |
736 ;; Return non-nil if there is anywhere still to be fontified. | |
737 (save-restriction | |
738 (widen) | |
739 (text-property-any (point-min) (point-max) 'lazy-lock nil))) | |
740 | |
741 (defun lazy-lock-percent-fontified () | |
742 ;; Return the percentage (of characters) of the buffer that are fontified. | |
743 (save-restriction | |
744 (widen) | |
745 (let ((beg (point-min)) (end (point-max)) (size 0) next) | |
746 ;; Find where the next fontified region begins. | |
747 (while (setq beg (text-property-any beg end 'lazy-lock t)) | |
748 (setq next (or (text-property-any beg end 'lazy-lock nil) end) | |
749 size (+ size (- next beg)) | |
750 beg next)) | |
751 (/ (* size 100) (buffer-size))))) | |
752 | |
753 ;; Version dependent workarounds and fixes. | |
754 | |
755 (when (if (save-match-data (string-match "Lucid\\|XEmacs" (emacs-version))) | |
756 nil | |
757 (and (= emacs-major-version 19) (= emacs-minor-version 30))) | |
758 ;; | |
759 ;; We use `post-command-idle-hook' for deferral and stealth. Oh Lordy. | |
760 (defun lazy-lock-install-timers (foo bar) | |
761 (add-hook 'post-command-idle-hook 'lazy-lock-fontify-post-command t) | |
762 (add-hook 'post-command-idle-hook 'lazy-lock-fontify-post-idle t) | |
763 (add-to-list 'lazy-lock-install (current-buffer)) | |
764 (add-hook 'post-command-hook 'lazy-lock-fontify-after-install)) | |
765 (defun lazy-lock-fontify-post-command () | |
766 (and lazy-lock-buffers (not executing-kbd-macro) | |
767 (progn | |
768 (and deactivate-mark (deactivate-mark)) | |
769 (sit-for | |
770 (or (cdr-safe lazy-lock-defer-time) lazy-lock-defer-time 0))) | |
771 (lazy-lock-fontify-after-defer))) | |
772 (defun lazy-lock-fontify-post-idle () | |
773 (and lazy-lock-stealth-time (not executing-kbd-macro) | |
774 (not (window-minibuffer-p (selected-window))) | |
775 (progn | |
776 (and deactivate-mark (deactivate-mark)) | |
777 (sit-for lazy-lock-stealth-time)) | |
778 (lazy-lock-fontify-after-idle))) | |
779 ;; | |
780 ;; Simulate running of `window-scroll-functions' in `set-window-buffer'. | |
781 (defvar lazy-lock-install nil) | |
782 (defun lazy-lock-fontify-after-install () | |
783 (remove-hook 'post-command-hook 'lazy-lock-fontify-after-install) | |
784 (while lazy-lock-install | |
785 (mapcar 'lazy-lock-fontify-conservatively | |
786 (get-buffer-window-list (pop lazy-lock-install) 'nomini t))))) | |
787 | |
788 ;; Possibly absent. | |
789 | |
790 (unless (boundp 'font-lock-inhibit-thing-lock) | |
791 ;; Font Lock mode uses this to direct Lazy and Fast Lock modes to stay off. | |
792 (defvar font-lock-inhibit-thing-lock nil | |
793 "List of Font Lock mode related modes that should not be turned on.")) | |
794 | |
795 (unless (fboundp 'font-lock-value-in-major-mode) | |
796 (defun font-lock-value-in-major-mode (alist) | |
797 ;; Return value in ALIST for `major-mode'. | |
798 (if (consp alist) | |
799 (cdr (or (assq major-mode alist) (assq t alist))) | |
800 alist))) | |
801 | |
802 (unless (fboundp 'get-buffer-window-list) | |
803 ;; We use this to get all windows showing a buffer we have to fontify. | |
804 (defun get-buffer-window-list (buffer &optional minibuf frame) | |
805 "Return windows currently displaying BUFFER, or nil if none." | |
806 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows) | |
807 (walk-windows (function (lambda (window) | |
808 (when (eq (window-buffer window) buffer) | |
809 (push window windows)))) | |
810 minibuf frame) | |
811 windows))) | |
812 | |
813 ;; Install ourselves: | |
814 | |
815 (add-hook 'window-size-change-functions 'lazy-lock-fontify-after-resize) | |
816 (add-hook 'redisplay-end-trigger-functions 'lazy-lock-fontify-after-trigger) | |
817 | |
818 (unless (assq 'lazy-lock-mode minor-mode-alist) | |
819 (setq minor-mode-alist (append minor-mode-alist '((lazy-lock-mode nil))))) | |
820 | |
821 ;; Provide ourselves: | |
822 | |
823 (provide 'lazy-lock) | |
824 | |
825 ;;; lazy-lock.el ends here |