Mercurial > emacs
comparison lisp/lazy-lock.el @ 16580:f4429e6fe33c
(a) split lazy-lock-defer-time into lazy-lock-defer-time and lazy-lock-defer-on-the-fly, (b) add lazy-lock-defer-on-scrolling, (c) use these to choose one of lazy-lock-defer-line-after-change, lazy-lock-defer-rest-after-change, lazy-lock-fontify-line-after-change, lazy-lock-fontify-rest-after-change to add to after-change-functions, (d) use with-current-buffer rather than save-excursion, (e) avoid integer overflow in lazy-lock-percent-fontified.
author | Simon Marshall <simon@gnu.org> |
---|---|
date | Sat, 16 Nov 1996 13:33:51 +0000 |
parents | aa9675ed8ed4 |
children | 5ea11c278a57 |
comparison
equal
deleted
inserted
replaced
16579:aadb4abdeaaa | 16580:f4429e6fe33c |
---|---|
2 | 2 |
3 ;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. |
4 | 4 |
5 ;; Author: Simon Marshall <simon@gnu.ai.mit.edu> | 5 ;; Author: Simon Marshall <simon@gnu.ai.mit.edu> |
6 ;; Keywords: faces files | 6 ;; Keywords: faces files |
7 ;; Version: 2.06 | 7 ;; Version: 2.07 |
8 | 8 |
9 ;;; This file is part of GNU Emacs. | 9 ;;; This file is part of GNU Emacs. |
10 | 10 |
11 ;; GNU Emacs is free software; you can redistribute it and/or modify | 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 | 12 ;; it under the terms of the GNU General Public License as published by |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
24 ;; Boston, MA 02111-1307, USA. | 24 ;; Boston, MA 02111-1307, USA. |
25 | 25 |
26 ;;; Commentary: | 26 ;;; Commentary: |
27 | 27 |
28 ;; Purpose: | 28 ;; Lazy Lock mode is a Font Lock support mode. |
29 ;; | 29 ;; It makes visiting buffers in Font Lock mode faster by making fontification |
30 ;; To make visiting buffers in `font-lock-mode' faster by making fontification | 30 ;; be demand-driven, deferred and stealthy, so that fontification only occurs |
31 ;; be demand-driven, deferred and stealthy. | 31 ;; when, and where, necessary. |
32 ;; Fontification only occurs when, and where, necessary. | |
33 ;; | 32 ;; |
34 ;; See caveats and feedback below. | 33 ;; See caveats and feedback below. |
35 ;; See also the fast-lock package. (But don't use them at the same time!) | 34 ;; See also the fast-lock package. (But don't use them at the same time!) |
36 | 35 |
37 ;; Installation: | 36 ;; Installation: |
104 ;; | 103 ;; |
105 ;; If only life was that easy. Version 2 demand-driven fontification is mostly | 104 ;; If only life was that easy. Version 2 demand-driven fontification is mostly |
106 ;; implemented by placing a function on `window-scroll-functions'. However, | 105 ;; implemented by placing a function on `window-scroll-functions'. However, |
107 ;; not all scrolling occurs when `window-start' has changed. A change in | 106 ;; 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 | 107 ;; 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'. | 108 ;; of lines, causes text previously invisible (i.e., after `window-end') to |
110 ;; Arguably, these events are not scrolling events, but fontification must | 109 ;; become visible without changing `window-start'. Arguably, these events are |
111 ;; occur for lazy-lock.el to work. Hooks `window-size-change-functions' and | 110 ;; not scrolling events, but fontification must occur for lazy-lock.el to work. |
112 ;; `redisplay-end-trigger-functions' were added for these circumstances. | 111 ;; Hooks `window-size-change-functions' and `redisplay-end-trigger-functions' |
112 ;; were added for these circumstances. | |
113 ;; | 113 ;; |
114 ;; Ben Wing thinks these hooks are "horribly horribly kludgy", and implemented | 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. | 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 | 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 | 117 ;; than `post-command-hook'. Whereas functions on `post-command-hook' are |
145 ;; Richard Stallman and Morten Welinder implemented internal Timers and Idle | 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 | 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 | 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 | 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 | 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. | 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 | 151 |
154 ;; Caveats: | 152 ;; Caveats: |
155 ;; | 153 ;; |
156 ;; Lazy Lock mode does not work efficiently with Outline mode. This is because | 154 ;; Lazy Lock mode does not work efficiently with Outline mode. |
157 ;; when in Outline mode, although text may be hidden (not visible in the | 155 ;; This is because when in Outline mode, although text may be not visible to |
158 ;; window), the text is visible to Emacs Lisp code (not surprisingly) and Lazy | 156 ;; you in the window, the text is visible to Emacs Lisp code (not surprisingly) |
159 ;; Lock fontifies it mercilessly. Maybe it will be fixed one day. | 157 ;; and Lazy Lock fontifies it mercilessly. Maybe it will be fixed one day. |
160 ;; | 158 ;; |
161 ;; Because buffer text is not necessarily fontified, other packages that expect | 159 ;; 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 | 160 ;; 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 | 161 ;; 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. | 162 ;; latter is `occur', which copies lines of buffer text into another buffer. |
172 ;; the echoing of keystrokes in the minibuffer. This is because of the way | 170 ;; 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! | 171 ;; deferral and stealth have to be implemented for Emacs 19.30. Upgrade! |
174 ;; | 172 ;; |
175 ;; Currently XEmacs does not have the features to support this version of | 173 ;; Currently XEmacs does not have the features to support this version of |
176 ;; lazy-lock.el. Maybe it will one day. | 174 ;; lazy-lock.el. Maybe it will one day. |
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 | 175 |
185 ;; History: | 176 ;; History: |
186 ;; | 177 ;; |
187 ;; 1.15--2.00: | 178 ;; 1.15--2.00: |
188 ;; - Rewrite for Emacs 19.30 and the features rms added to support lazy-lock.el | 179 ;; - Rewrite for Emacs 19.30 and the features rms added to support lazy-lock.el |
224 ;; 2.04--2.05: | 215 ;; 2.04--2.05: |
225 ;; - Rewrite for Common Lisp macros | 216 ;; - Rewrite for Common Lisp macros |
226 ;; - Added `do-while' macro | 217 ;; - Added `do-while' macro |
227 ;; - Renamed `lazy-lock-let-buffer-state' macro to `save-buffer-state' | 218 ;; - Renamed `lazy-lock-let-buffer-state' macro to `save-buffer-state' |
228 ;; - Returned `lazy-lock-fontify-after-install' hack (Darren Hall hint) | 219 ;; - Returned `lazy-lock-fontify-after-install' hack (Darren Hall hint) |
229 ;; - Added `lazy-lock-defer-driven' functionality (Scott Byer hint) | 220 ;; - Added `lazy-lock-defer-on-scrolling' functionality (Scott Byer hint) |
230 ;; - Made `lazy-lock-mode' wrap `font-lock-support-mode' | 221 ;; - Made `lazy-lock-mode' wrap `font-lock-support-mode' |
231 ;; 2.05--2.06: | 222 ;; 2.05--2.06: |
232 ;; - Made `lazy-lock-fontify-after-defer' swap correctly (Scott Byer report) | 223 ;; - Made `lazy-lock-fontify-after-defer' swap correctly (Scott Byer report) |
224 ;; 2.06--2.07: | |
225 ;; - Added `lazy-lock-stealth-load' functionality (Rob Hooft hint) | |
226 ;; - Made `lazy-lock-unstall' call `lazy-lock-fontify-region' if needed | |
227 ;; - Made `lazy-lock-mode' call `lazy-lock-unstall' only if needed | |
228 ;; - Made `lazy-lock-defer-after-scroll' do `set-window-redisplay-end-trigger' | |
229 ;; - Added `lazy-lock-defer-contextually' functionality | |
230 ;; - Added `lazy-lock-defer-on-the-fly' from `lazy-lock-defer-time' | |
231 ;; - Renamed `lazy-lock-defer-driven' to `lazy-lock-defer-on-scrolling' | |
232 ;; - Removed `lazy-lock-submit-bug-report' and bade farewell | |
233 | 233 |
234 ;;; Code: | |
235 | |
234 (require 'font-lock) | 236 (require 'font-lock) |
235 | 237 |
236 ;; Make sure lazy-lock.el is supported. | 238 ;; Make sure lazy-lock.el is supported. |
237 (if (if (save-match-data (string-match "Lucid\\|XEmacs" (emacs-version))) | 239 (if (if (save-match-data (string-match "Lucid\\|XEmacs" (emacs-version))) |
238 t | 240 t |
273 (defmacro do-while (test &rest body) | 275 (defmacro do-while (test &rest body) |
274 "(do-while TEST BODY...): eval BODY... and repeat if TEST yields non-nil. | 276 "(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 | 277 The order of execution is thus BODY, TEST, BODY, TEST and so on |
276 until TEST returns nil." | 278 until TEST returns nil." |
277 (` (while (progn (,@ body) (, test))))) | 279 (` (while (progn (,@ body) (, test))))) |
278 (put 'do-while 'lisp-indent-function (get 'while 'lisp-indent-function))) | 280 (put 'do-while 'lisp-indent-function (get 'while 'lisp-indent-function)) |
281 ;; | |
282 ;; We use this for clarity and speed. Borrowed from a future Emacs. | |
283 (or (fboundp 'with-current-buffer) | |
284 (defmacro with-current-buffer (buffer &rest body) | |
285 "Execute the forms in BODY with BUFFER as the current buffer. | |
286 The value returned is the value of the last form in BODY." | |
287 (` (save-excursion (set-buffer (, buffer)) (,@ body))))) | |
288 (put 'with-current-buffer 'lisp-indent-function 1)) | |
289 | |
290 ;(defun lazy-lock-submit-bug-report () | |
291 ; "Submit via mail a bug report on lazy-lock.el." | |
292 ; (interactive) | |
293 ; (let ((reporter-prompt-for-summary-p t)) | |
294 ; (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "lazy-lock 2.07" | |
295 ; '(lazy-lock-minimum-size lazy-lock-defer-on-the-fly | |
296 ; lazy-lock-defer-on-scrolling lazy-lock-defer-contextually | |
297 ; lazy-lock-defer-time lazy-lock-stealth-time | |
298 ; lazy-lock-stealth-load lazy-lock-stealth-nice lazy-lock-stealth-lines | |
299 ; lazy-lock-stealth-verbose) | |
300 ; nil nil | |
301 ; (concat "Hi Si., | |
302 ; | |
303 ;I want to report a bug. I've read the `Bugs' section of `Info' on Emacs, so I | |
304 ;know how to make a clear and unambiguous report. To reproduce the bug: | |
305 ; | |
306 ;Start a fresh editor via `" invocation-name " -no-init-file -no-site-file'. | |
307 ;In the `*scratch*' buffer, evaluate:")))) | |
308 | |
309 (defvar lazy-lock-mode nil) | |
310 (defvar lazy-lock-buffers nil) ; for deferral | |
311 (defvar lazy-lock-timers (cons nil nil)) ; for deferral and stealth | |
279 | 312 |
280 ;; User Variables: | 313 ;; User Variables: |
281 | 314 |
282 (defvar lazy-lock-minimum-size (* 25 1024) | 315 (defvar lazy-lock-minimum-size (* 25 1024) |
283 "*Minimum size of a buffer for demand-driven fontification. | 316 "*Minimum size of a buffer for demand-driven fontification. |
289 means that the minimum size is 25K for buffers in C or C++ modes, one megabyte | 322 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. | 323 for buffers in Rmail mode, and size is irrelevant otherwise. |
291 | 324 |
292 The value of this variable is used when Lazy Lock mode is turned on.") | 325 The value of this variable is used when Lazy Lock mode is turned on.") |
293 | 326 |
294 (defvar lazy-lock-defer-driven nil | 327 (defvar lazy-lock-defer-on-the-fly t |
295 "*If non-nil, means fontification should be defer-driven. | 328 "*If non-nil, means fontification after a change should be deferred. |
329 If nil, means on-the-fly fontification is performed. This means when changes | |
330 occur in the buffer, those areas are immediately fontified. | |
331 If a list, it should be a list of `major-mode' symbol names for which deferred | |
332 fontification should occur. The sense of the list is negated if it begins with | |
333 `not'. For example: | |
334 (c-mode c++-mode) | |
335 means that on-the-fly fontification is deferred for buffers in C and C++ modes | |
336 only, and deferral does not occur otherwise. | |
337 | |
338 The value of this variable is used when Lazy Lock mode is turned on.") | |
339 | |
340 (defvar lazy-lock-defer-on-scrolling nil | |
341 "*If non-nil, means fontification after a scroll should be deferred. | |
296 If nil, means demand-driven fontification is performed. This means when | 342 If nil, means demand-driven fontification is performed. This means when |
297 scrolling into unfontified areas of the buffer, those areas are immediately | 343 scrolling into unfontified areas of the buffer, those areas are immediately |
298 fontified. Thus scrolling never presents unfontified areas. However, since | 344 fontified. Thus scrolling never presents unfontified areas. However, since |
299 fontification occurs during scrolling, scrolling may be slow. | 345 fontification occurs during scrolling, scrolling may be slow. |
300 If t, means defer-driven fontification is performed. This means fontification | 346 If t, means defer-driven fontification is performed. This means fontification |
305 performed until the buffer is fontified, then buffer fontification becomes | 351 performed until the buffer is fontified, then buffer fontification becomes |
306 defer-driven. Thus scrolling never presents unfontified areas until the buffer | 352 defer-driven. Thus scrolling never presents unfontified areas until the buffer |
307 is first fontified, after which subsequent scrolling may present future buffer | 353 is first fontified, after which subsequent scrolling may present future buffer |
308 insertions momentarily unfontified. However, since fontification does not | 354 insertions momentarily unfontified. However, since fontification does not |
309 occur during scrolling after the buffer is first fontified, scrolling will | 355 occur during scrolling after the buffer is first fontified, scrolling will |
310 become faster. | 356 become faster. (But, since contextual changes continually occur, such a value |
357 makes little sense if `lazy-lock-defer-contextually' is non-nil.) | |
311 | 358 |
312 The value of this variable is used when Lazy Lock mode is turned on.") | 359 The value of this variable is used when Lazy Lock mode is turned on.") |
313 | 360 |
361 (defvar lazy-lock-defer-contextually 'syntax-driven | |
362 "*If non-nil, means deferred fontification should be syntactically true. | |
363 If nil, means deferred fontification occurs only on those lines modified. This | |
364 means where modification on a line causes syntactic change on subsequent lines, | |
365 those subsequent lines are not refontified to reflect their new context. | |
366 If t, means deferred fontification occurs on those lines modified and all | |
367 subsequent lines. This means those subsequent lines are refontified to reflect | |
368 their new syntactic context, either immediately or when scrolling into them. | |
369 If any other value, e.g., `syntax-driven', means deferred syntactically true | |
370 fontification occurs only if syntactic fontification is performed using the | |
371 buffer mode's syntax table, i.e., only if `font-lock-keywords-only' is nil. | |
372 | |
373 The value of this variable is used when Lazy Lock mode is turned on.") | |
374 | |
314 (defvar lazy-lock-defer-time | 375 (defvar lazy-lock-defer-time |
315 (if (featurep 'lisp-float-type) (/ (float 1) (float 4)) 1) | 376 (if (featurep 'lisp-float-type) (/ (float 1) (float 3)) 1) |
316 "*Time in seconds to delay before beginning deferred fontification. | 377 "*Time in seconds to delay before beginning deferred fontification. |
317 Deferred fontification occurs if there is no input within this time. | 378 Deferred fontification occurs if there is no input within this time. |
318 If nil, means fontification is never deferred. However, fontification occurs | 379 If nil, means fontification is never deferred, regardless of the values of the |
319 on-the-fly or during scrolling, which may be slow. | 380 variables `lazy-lock-defer-on-the-fly', `lazy-lock-defer-on-scrolling' and |
320 If a list, it should be of the form (MAJOR-MODES . TIME), where MAJOR-MODES is | 381 `lazy-lock-defer-contextually'. |
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 | 382 |
327 The value of this variable is used when Lazy Lock mode is turned on.") | 383 The value of this variable is used when Lazy Lock mode is turned on.") |
328 | 384 |
329 (defvar lazy-lock-stealth-time 30 | 385 (defvar lazy-lock-stealth-time 30 |
330 "*Time in seconds to delay before beginning stealth fontification. | 386 "*Time in seconds to delay before beginning stealth fontification. |
337 "*Maximum size of a chunk of stealth fontification. | 393 "*Maximum size of a chunk of stealth fontification. |
338 Each iteration of stealth fontification can fontify this number of lines. | 394 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 | 395 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.") | 396 taking longer to fontify, you could reduce the value of this variable.") |
341 | 397 |
398 (defvar lazy-lock-stealth-load | |
399 (when (condition-case nil (load-average) (error)) 200) | |
400 "*Load in percentage above which stealth fontification is suspended. | |
401 Stealth fontification pauses when the system short-term load average (as | |
402 returned by the function `load-average' if supported) goes above this level, | |
403 thus reducing the demand that stealth fontification makes on the system. | |
404 If nil, means stealth fontification is never suspended. | |
405 To reduce machine load during stealth fontification, at the cost of stealth | |
406 taking longer to fontify, you could reduce the value of this variable. | |
407 See also `lazy-lock-stealth-nice'.") | |
408 | |
342 (defvar lazy-lock-stealth-nice | 409 (defvar lazy-lock-stealth-nice |
343 (if (featurep 'lisp-float-type) (/ (float 1) (float 8)) 1) | 410 (if (featurep 'lisp-float-type) (/ (float 1) (float 8)) 1) |
344 "*Time in seconds to pause between chunks of stealth fontification. | 411 "*Time in seconds to pause between chunks of stealth fontification. |
345 Each iteration of stealth fontification is separated by this amount of time. | 412 Each iteration of stealth fontification is separated by this amount of time, |
413 thus reducing the demand that stealth fontification makes on the system. | |
414 If nil, means stealth fontification is never paused. | |
346 To reduce machine load during stealth fontification, at the cost of stealth | 415 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.") | 416 taking longer to fontify, you could increase the value of this variable. |
348 | 417 See also `lazy-lock-stealth-load'.") |
349 (defvar lazy-lock-stealth-verbose (not (null font-lock-verbose)) | 418 |
419 (defvar lazy-lock-stealth-verbose | |
420 (when (featurep 'lisp-float-type) | |
421 (and font-lock-verbose (not lazy-lock-defer-contextually))) | |
350 "*If non-nil, means stealth fontification should show status messages.") | 422 "*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 | 423 |
356 ;; User Functions: | 424 ;; User Functions: |
357 | 425 |
358 ;;;###autoload | 426 ;;;###autoload |
359 (defun lazy-lock-mode (&optional arg) | 427 (defun lazy-lock-mode (&optional arg) |
363 | 431 |
364 (setq font-lock-support-mode 'lazy-lock-mode) | 432 (setq font-lock-support-mode 'lazy-lock-mode) |
365 | 433 |
366 When Lazy Lock mode is enabled, fontification can be lazy in a number of ways: | 434 When Lazy Lock mode is enabled, fontification can be lazy in a number of ways: |
367 | 435 |
368 - Demand-driven buffer fontification if `lazy-lock-minimum-size' is non-nil. | 436 - 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 | 437 This means initial fontification does not occur if the buffer is greater than |
370 than `lazy-lock-minimum-size' characters in length. Instead, fontification | 438 `lazy-lock-minimum-size' characters in length. Instead, fontification occurs |
371 occurs when necessary, such as when scrolling through the buffer would | 439 when necessary, such as when scrolling through the buffer would otherwise |
372 otherwise reveal unfontified areas. This is useful if buffer fontification | 440 reveal unfontified areas. This is useful if buffer fontification is too slow |
373 is too slow for large buffers. | 441 for large buffers. |
374 | 442 |
375 - Defer-driven buffer fontification if `lazy-lock-defer-driven' is non-nil. | 443 - Deferred scroll fontification if `lazy-lock-defer-on-scrolling' is non-nil. |
376 This means all fontification is deferred, such as fontification that occurs | 444 This means demand-driven fontification does not occur as you scroll. |
377 when scrolling through the buffer would otherwise reveal unfontified areas. | 445 Instead, fontification is deferred until after `lazy-lock-defer-time' seconds |
378 Instead, these areas are seen momentarily unfontified. This is useful if | 446 of Emacs idle time, while Emacs remains idle. This is useful if |
379 demand-driven fontification is too slow to keep up with scrolling. | 447 fontification is too slow to keep up with scrolling. |
380 | 448 |
381 - Deferred on-the-fly fontification if `lazy-lock-defer-time' is non-nil. | 449 - Deferred on-the-fly fontification if `lazy-lock-defer-on-the-fly' is non-nil. |
382 This means on-the-fly fontification does not occur as you type. Instead, | 450 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 | 451 fontification is deferred until after `lazy-lock-defer-time' seconds of Emacs |
384 Emacs idle time, while Emacs remains idle. This is useful if on-the-fly | 452 idle time, while Emacs remains idle. This is useful if fontification is too |
385 fontification is too slow to keep up with your typing. | 453 slow to keep up with your typing. |
386 | 454 |
387 - Stealthy buffer fontification if `lazy-lock-stealth-time' is non-nil. | 455 - Deferred context fontification if `lazy-lock-defer-contextually' is non-nil. |
388 This means remaining unfontified areas of buffers are fontified if Emacs has | 456 This means fontification updates the buffer corresponding to true syntactic |
389 been idle for `lazy-lock-stealth-time' seconds, while Emacs remains idle. | 457 context, after `lazy-lock-defer-time' seconds of Emacs idle time, while Emacs |
390 This is useful if any buffer has demand- or defer-driven fontification. | 458 remains idle. Otherwise, fontification occurs on modified lines only, and |
391 | 459 subsequent lines can remain fontified corresponding to previous syntactic |
392 See also variables `lazy-lock-stealth-lines', `lazy-lock-stealth-nice' and | 460 contexts. This is useful where strings or comments span lines. |
393 `lazy-lock-stealth-verbose' for stealth fontification. | 461 |
394 | 462 - Stealthy buffer fontification if `lazy-lock-stealth-time' is non-nil. |
395 Use \\[lazy-lock-submit-bug-report] to send bug reports or feedback." | 463 This means remaining unfontified areas of buffers are fontified if Emacs has |
464 been idle for `lazy-lock-stealth-time' seconds, while Emacs remains idle. | |
465 This is useful if any buffer has any deferred fontification. | |
466 | |
467 Basic Font Lock mode on-the-fly fontification behaviour fontifies modified | |
468 lines only. Thus, if `lazy-lock-defer-contextually' is non-nil, Lazy Lock mode | |
469 on-the-fly fontification may fontify differently, albeit correctly. In any | |
470 event, to refontify some lines you can use \\[font-lock-fontify-block]. | |
471 | |
472 Stealth fontification only occurs while the system remains unloaded. | |
473 If the system load rises above `lazy-lock-stealth-load' percent, stealth | |
474 fontification is suspended. Stealth fontification intensity is controlled via | |
475 the variable `lazy-lock-stealth-nice' and `lazy-lock-stealth-lines', and | |
476 verbosity is controlled via the variable `lazy-lock-stealth-verbose'." | |
396 (interactive "P") | 477 (interactive "P") |
397 (set (make-local-variable 'lazy-lock-mode) | 478 (let* ((was-on lazy-lock-mode) |
398 (and (not (memq 'lazy-lock-mode font-lock-inhibit-thing-lock)) | 479 (now-on (unless (memq 'lazy-lock-mode font-lock-inhibit-thing-lock) |
399 (if arg (> (prefix-numeric-value arg) 0) (not lazy-lock-mode)))) | 480 (if arg (> (prefix-numeric-value arg) 0) (not was-on))))) |
400 (cond ((and lazy-lock-mode (not font-lock-mode)) | 481 (cond ((and now-on (not font-lock-mode)) |
401 ;; Turned on `lazy-lock-mode' rather than `font-lock-mode'. | 482 ;; Turned on `lazy-lock-mode' rather than `font-lock-mode'. |
402 (let ((font-lock-support-mode 'lazy-lock-mode)) | 483 (let ((font-lock-support-mode 'lazy-lock-mode)) |
403 (font-lock-mode t))) | 484 (font-lock-mode t))) |
404 (lazy-lock-mode | 485 (now-on |
405 ;; Turn ourselves on. | 486 ;; Turn ourselves on. |
406 (lazy-lock-install)) | 487 (set (make-local-variable 'lazy-lock-mode) t) |
407 (t | 488 (lazy-lock-install)) |
408 ;; Turn ourselves off. | 489 (was-on |
409 (lazy-lock-unstall)))) | 490 ;; Turn ourselves off. |
410 | 491 (set (make-local-variable 'lazy-lock-mode) nil) |
411 (defun lazy-lock-submit-bug-report () | 492 (lazy-lock-unstall))))) |
412 "Submit via mail a bug report on lazy-lock.el." | |
413 (interactive) | |
414 (let ((reporter-prompt-for-summary-p t)) | |
415 (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "lazy-lock 2.06" | |
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 | 493 |
428 ;;;###autoload | 494 ;;;###autoload |
429 (defun turn-on-lazy-lock () | 495 (defun turn-on-lazy-lock () |
430 "Unconditionally turn on Lazy Lock mode." | 496 "Unconditionally turn on Lazy Lock mode." |
431 (lazy-lock-mode t)) | 497 (lazy-lock-mode t)) |
432 | 498 |
433 (defun lazy-lock-install () | 499 (defun lazy-lock-install () |
434 (let ((min-size (font-lock-value-in-major-mode lazy-lock-minimum-size))) | 500 (let ((min-size (font-lock-value-in-major-mode lazy-lock-minimum-size)) |
501 (defer-change (and lazy-lock-defer-time lazy-lock-defer-on-the-fly)) | |
502 (defer-scroll (and lazy-lock-defer-time lazy-lock-defer-on-scrolling)) | |
503 (defer-context (and lazy-lock-defer-time lazy-lock-defer-contextually | |
504 (or (eq lazy-lock-defer-contextually t) | |
505 (null font-lock-keywords-only))))) | |
435 ;; | 506 ;; |
436 ;; Tell Font Lock whether Lazy Lock will do fontification. | 507 ;; Tell Font Lock whether Lazy Lock will do fontification. |
437 (make-local-variable 'font-lock-fontified) | 508 (make-local-variable 'font-lock-fontified) |
438 (setq font-lock-fontified (and min-size (>= (buffer-size) min-size))) | 509 (setq font-lock-fontified (and min-size (>= (buffer-size) min-size))) |
439 ;; | 510 ;; |
447 (lazy-lock-fontify-conservatively (car windows)) | 518 (lazy-lock-fontify-conservatively (car windows)) |
448 (setq windows (cdr windows))))) | 519 (setq windows (cdr windows))))) |
449 ;; | 520 ;; |
450 ;; Add the fontification hooks. | 521 ;; Add the fontification hooks. |
451 (lazy-lock-install-hooks | 522 (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 | 523 font-lock-fontified |
457 (eq lazy-lock-defer-driven t)) | 524 (cond ((eq (car-safe defer-change) 'not) |
525 (not (memq major-mode (cdr defer-change)))) | |
526 ((listp defer-change) | |
527 (memq major-mode defer-change)) | |
528 (t | |
529 defer-change)) | |
530 (eq defer-scroll t) | |
531 defer-context) | |
458 ;; | 532 ;; |
459 ;; Add the fontification timers. | 533 ;; Add the fontification timers. |
460 (lazy-lock-install-timers | 534 (lazy-lock-install-timers |
461 (or (cdr-safe lazy-lock-defer-time) lazy-lock-defer-time) | 535 (if (or defer-change defer-scroll defer-context) lazy-lock-defer-time) |
462 lazy-lock-stealth-time))) | 536 lazy-lock-stealth-time))) |
463 | 537 |
464 (defun lazy-lock-install-hooks (deferring fontifying defer-driven) | 538 (defun lazy-lock-install-hooks (fontifying |
465 ;; | 539 defer-change defer-scroll defer-context) |
466 ;; Add hook if lazy-lock.el is deferring or is fontifying on scrolling. | 540 ;; |
467 (when (or deferring fontifying) | 541 ;; Add hook if lazy-lock.el is fontifying on scrolling or is deferring. |
542 (when (or fontifying defer-change defer-scroll defer-context) | |
468 (make-local-hook 'window-scroll-functions) | 543 (make-local-hook 'window-scroll-functions) |
469 (add-hook 'window-scroll-functions (if (and deferring defer-driven) | 544 (add-hook 'window-scroll-functions (if defer-scroll |
470 'lazy-lock-defer-after-scroll | 545 'lazy-lock-defer-after-scroll |
471 'lazy-lock-fontify-after-scroll) | 546 'lazy-lock-fontify-after-scroll) |
472 nil t)) | 547 nil t)) |
473 ;; | 548 ;; |
474 ;; Add hook if lazy-lock.el is not deferring and is fontifying. | 549 ;; Add hook if lazy-lock.el is fontifying and is not deferring changes. |
475 (when (and (not deferring) fontifying) | 550 (when (and fontifying (not defer-change) (not defer-context)) |
476 (make-local-hook 'before-change-functions) | 551 (make-local-hook 'before-change-functions) |
477 (add-hook 'before-change-functions 'lazy-lock-arrange-before-change nil t)) | 552 (add-hook 'before-change-functions 'lazy-lock-arrange-before-change nil t)) |
478 ;; | 553 ;; |
479 ;; Add hook if lazy-lock.el is deferring. | 554 ;; Replace Font Lock mode hook. |
480 (when deferring | 555 (remove-hook 'after-change-functions 'font-lock-after-change-function t) |
481 (remove-hook 'after-change-functions 'font-lock-after-change-function t) | 556 (add-hook 'after-change-functions |
482 (add-hook 'after-change-functions 'lazy-lock-defer-after-change nil t)) | 557 (cond ((and defer-change defer-context) |
483 ;; | 558 'lazy-lock-defer-rest-after-change) |
484 ;; Add package-specific hooks. | 559 (defer-change |
560 'lazy-lock-defer-line-after-change) | |
561 (defer-context | |
562 'lazy-lock-fontify-rest-after-change) | |
563 (t | |
564 'lazy-lock-fontify-line-after-change)) | |
565 nil t) | |
566 ;; | |
567 ;; Add package-specific hook. | |
485 (make-local-hook 'outline-view-change-hook) | 568 (make-local-hook 'outline-view-change-hook) |
486 (add-hook 'outline-view-change-hook 'lazy-lock-fontify-after-outline nil t)) | 569 (add-hook 'outline-view-change-hook 'lazy-lock-fontify-after-outline nil t)) |
487 | 570 |
488 (defun lazy-lock-install-timers (dtime stime) | 571 (defun lazy-lock-install-timers (dtime stime) |
489 ;; Schedule or re-schedule the deferral and stealth timers. | 572 ;; Schedule or re-schedule the deferral and stealth timers. |
504 (setcdr lazy-lock-timers (cons stime (and stime | 587 (setcdr lazy-lock-timers (cons stime (and stime |
505 (run-with-idle-timer stime t 'lazy-lock-fontify-after-idle))))))) | 588 (run-with-idle-timer stime t 'lazy-lock-fontify-after-idle))))))) |
506 | 589 |
507 (defun lazy-lock-unstall () | 590 (defun lazy-lock-unstall () |
508 ;; | 591 ;; |
592 ;; If Font Lock mode is still enabled, make sure that the buffer is | |
593 ;; fontified, and reinstall its hook. We must do this first. | |
594 (when font-lock-mode | |
595 (when (lazy-lock-unfontified-p) | |
596 (let ((verbose (if (numberp font-lock-verbose) | |
597 (> (buffer-size) font-lock-verbose) | |
598 font-lock-verbose))) | |
599 (if verbose (message "Fontifying %s..." (buffer-name))) | |
600 ;; Make sure we fontify etc. in the whole buffer. | |
601 (save-restriction | |
602 (widen) | |
603 (lazy-lock-fontify-region (point-min) (point-max))) | |
604 (if verbose (message "Fontifying %s...%s" (buffer-name) | |
605 (if (lazy-lock-unfontified-p) "quit" "done"))))) | |
606 (add-hook 'after-change-functions 'font-lock-after-change-function nil t)) | |
607 ;; | |
509 ;; Remove the text properties. | 608 ;; Remove the text properties. |
510 (lazy-lock-after-unfontify-buffer) | 609 (lazy-lock-after-unfontify-buffer) |
511 ;; | 610 ;; |
512 ;; Remove the fontification hooks. | 611 ;; Remove the fontification hooks. |
513 (remove-hook 'window-scroll-functions 'lazy-lock-fontify-after-scroll t) | 612 (remove-hook 'window-scroll-functions 'lazy-lock-fontify-after-scroll t) |
514 (remove-hook 'window-scroll-functions 'lazy-lock-defer-after-scroll t) | 613 (remove-hook 'window-scroll-functions 'lazy-lock-defer-after-scroll t) |
515 (remove-hook 'before-change-functions 'lazy-lock-arrange-before-change t) | 614 (remove-hook 'before-change-functions 'lazy-lock-arrange-before-change t) |
516 (remove-hook 'after-change-functions 'lazy-lock-defer-after-change t) | 615 (remove-hook 'after-change-functions 'lazy-lock-fontify-line-after-change t) |
517 (remove-hook 'outline-view-change-hook 'lazy-lock-fontify-after-outline t) | 616 (remove-hook 'after-change-functions 'lazy-lock-fontify-rest-after-change t) |
518 ;; | 617 (remove-hook 'after-change-functions 'lazy-lock-defer-line-after-change t) |
519 ;; If Font Lock mode is still enabled, reinstall its hook. | 618 (remove-hook 'after-change-functions 'lazy-lock-defer-rest-after-change t) |
520 (when font-lock-mode | 619 (remove-hook 'outline-view-change-hook 'lazy-lock-fontify-after-outline t)) |
521 (add-hook 'after-change-functions 'font-lock-after-change-function nil t))) | |
522 | 620 |
523 ;; Hook functions. | 621 ;; Hook functions. |
524 | 622 |
623 ;; Lazy Lock mode intervenes when (1) a previously invisible buffer region | |
624 ;; becomes visible, i.e., for demand- or defer-driven on-the-scroll | |
625 ;; fontification, (2) a buffer modification occurs, i.e., for defer-driven | |
626 ;; on-the-fly fontification, (3) Emacs becomes idle, i.e., for fontification of | |
627 ;; deferred fontification and stealth fontification, and (4) other special | |
628 ;; occasions. | |
629 | |
630 ;; 1. There are three ways whereby this can happen. | |
631 ;; | |
632 ;; (a) Scrolling the window, either explicitly (e.g., `scroll-up') or | |
633 ;; implicitly (e.g., `search-forward'). Here, `window-start' changes. | |
634 ;; Fontification occurs by adding `lazy-lock-fontify-after-scroll' (for | |
635 ;; demand-driven fontification) or `lazy-lock-defer-after-scroll' (for | |
636 ;; defer-driven fontification) to the hook `window-scroll-functions'. | |
637 | |
525 (defun lazy-lock-fontify-after-scroll (window window-start) | 638 (defun lazy-lock-fontify-after-scroll (window window-start) |
526 ;; Called from `window-scroll-functions'. | 639 ;; Called from `window-scroll-functions'. |
527 ;; Fontify WINDOW from WINDOW-START. We cannot use `window-end' so we work | 640 ;; Fontify WINDOW from WINDOW-START following the scroll. We cannot use |
528 ;; out what it would be via `vertical-motion'. | 641 ;; `window-end' so we work out what it would be via `vertical-motion'. |
529 (save-excursion | 642 (save-excursion |
530 (goto-char window-start) | 643 (goto-char window-start) |
531 (vertical-motion (window-height window) window) | 644 (vertical-motion (window-height window) window) |
532 (lazy-lock-fontify-region window-start (point))) | 645 (lazy-lock-fontify-region window-start (point))) |
533 ;; A prior deletion that did not cause scrolling, followed by a scroll, would | 646 ;; 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. | 647 ;; result in an unnecessary trigger after this if we did not cancel it now. |
535 (set-window-redisplay-end-trigger window nil)) | 648 (set-window-redisplay-end-trigger window nil)) |
536 | 649 |
537 (defun lazy-lock-fontify-after-trigger (window trigger-point) | 650 (defun lazy-lock-defer-after-scroll (window window-start) |
538 ;; Called from `redisplay-end-trigger-functions'. | 651 ;; Called from `window-scroll-functions'. |
539 ;; Fontify WINDOW from TRIGGER-POINT. We cannot use `window-end' so we work | 652 ;; Defer fontification following the scroll. Save the current buffer so that |
540 ;; out what it would be via `vertical-motion'. | 653 ;; we subsequently fontify in all windows showing the buffer. |
541 ;; We could probably just use `lazy-lock-fontify-after-scroll' without loss: | 654 (unless (memq (current-buffer) lazy-lock-buffers) |
542 ;; (lazy-lock-fontify-after-scroll window (window-start window)) | 655 (push (current-buffer) lazy-lock-buffers)) |
543 (save-excursion | 656 ;; A prior deletion that did not cause scrolling, followed by a scroll, would |
544 (goto-char (window-start window)) | 657 ;; result in an unnecessary trigger after this if we did not cancel it now. |
545 (vertical-motion (window-height window) window) | 658 (set-window-redisplay-end-trigger window nil)) |
546 (lazy-lock-fontify-region trigger-point (point)))) | 659 |
660 ;; (b) Resizing the window, either explicitly (e.g., `enlarge-window') or | |
661 ;; implicitly (e.g., `delete-other-windows'). Here, `window-end' changes. | |
662 ;; Fontification occurs by adding `lazy-lock-fontify-after-resize' to the | |
663 ;; hook `window-size-change-functions'. | |
547 | 664 |
548 (defun lazy-lock-fontify-after-resize (frame) | 665 (defun lazy-lock-fontify-after-resize (frame) |
549 ;; Called from `window-size-change-functions'. | 666 ;; Called from `window-size-change-functions'. |
550 ;; Fontify windows in FRAME. We cannot use `window-start' or `window-end' so | 667 ;; Fontify windows in FRAME following the resize. We cannot use |
551 ;; we fontify conservatively. | 668 ;; `window-start' or `window-end' so we fontify conservatively. |
552 (save-excursion | 669 (save-excursion |
553 (save-selected-window | 670 (save-selected-window |
554 (select-frame frame) | 671 (select-frame frame) |
555 (walk-windows (function (lambda (window) | 672 (walk-windows (function (lambda (window) |
556 (set-buffer (window-buffer window)) | 673 (set-buffer (window-buffer window)) |
557 (when lazy-lock-mode | 674 (when lazy-lock-mode |
558 (lazy-lock-fontify-conservatively window)) | 675 (lazy-lock-fontify-conservatively window)) |
559 (set-window-redisplay-end-trigger window nil))) | 676 (set-window-redisplay-end-trigger window nil))) |
560 'nomini frame)))) | 677 'nomini frame)))) |
678 | |
679 ;; (c) Deletion in the buffer. Here, a `window-end' marker can become visible. | |
680 ;; Fontification occurs by adding `lazy-lock-arrange-before-change' to | |
681 ;; `before-change-functions' and `lazy-lock-fontify-after-trigger' to the | |
682 ;; hook `redisplay-end-trigger-functions'. Before every deletion, the | |
683 ;; marker `window-redisplay-end-trigger' position is set to the soon-to-be | |
684 ;; changed `window-end' position. If the marker becomes visible, | |
685 ;; `lazy-lock-fontify-after-trigger' gets called. Ouch. Note that we only | |
686 ;; have to deal with this eventuality if there is no on-the-fly deferral. | |
561 | 687 |
562 (defun lazy-lock-arrange-before-change (beg end) | 688 (defun lazy-lock-arrange-before-change (beg end) |
563 ;; Called from `before-change-functions'. | 689 ;; Called from `before-change-functions'. |
564 ;; Arrange that if text becomes visible it will be fontified (if a deletion | 690 ;; Arrange that if text becomes visible it will be fontified (if a deletion |
565 ;; is pending, text might become visible at the bottom). | 691 ;; is pending, text might become visible at the bottom). |
570 (unless (markerp (window-redisplay-end-trigger window)) | 696 (unless (markerp (window-redisplay-end-trigger window)) |
571 (set-window-redisplay-end-trigger window (make-marker))) | 697 (set-window-redisplay-end-trigger window (make-marker))) |
572 (set-marker (window-redisplay-end-trigger window) (window-end window)) | 698 (set-marker (window-redisplay-end-trigger window) (window-end window)) |
573 (setq windows (cdr windows)))))) | 699 (setq windows (cdr windows)))))) |
574 | 700 |
575 (defun lazy-lock-defer-after-scroll (window window-start) | 701 (defun lazy-lock-fontify-after-trigger (window trigger-point) |
576 ;; Called from `window-scroll-functions'. | 702 ;; Called from `redisplay-end-trigger-functions'. |
577 ;; Defer fontification following the scroll. Save the current buffer so that | 703 ;; Fontify WINDOW from TRIGGER-POINT. We cannot use `window-end' so we work |
578 ;; we subsequently fontify in all windows showing the buffer. | 704 ;; out what it would be via `vertical-motion'. |
579 (unless (memq (current-buffer) lazy-lock-buffers) | 705 ;; We could probably just use `lazy-lock-fontify-after-scroll' without loss: |
580 (push (current-buffer) lazy-lock-buffers))) | 706 ;; (lazy-lock-fontify-after-scroll window (window-start window)) |
581 | 707 (save-excursion |
582 (defun lazy-lock-defer-after-change (beg end old-len) | 708 (goto-char (window-start window)) |
709 (vertical-motion (window-height window) window) | |
710 (lazy-lock-fontify-region trigger-point (point)))) | |
711 | |
712 ;; 2. Modified text must be marked as unfontified so it can be identified and | |
713 ;; fontified later when Emacs is idle. Deferral occurs by adding one of | |
714 ;; `lazy-lock-fontify-*-after-change' (for on-the-fly fontification) or | |
715 ;; `lazy-lock-defer-*-after-change' (for deferred fontification) to the | |
716 ;; hook `after-change-functions'. | |
717 | |
718 (defalias 'lazy-lock-fontify-line-after-change | |
583 ;; Called from `after-change-functions'. | 719 ;; Called from `after-change-functions'. |
584 ;; Defer fontification of the current line. Save the current buffer so that | 720 ;; Fontify the current change. |
585 ;; we subsequently fontify in all windows showing the buffer. | 721 'font-lock-after-change-function) |
722 | |
723 (defun lazy-lock-fontify-rest-after-change (beg end old-len) | |
724 ;; Called from `after-change-functions'. | |
725 ;; Fontify the current change and defer fontification of the rest of the | |
726 ;; buffer. Save the current buffer so that we subsequently fontify in all | |
727 ;; windows showing the buffer. | |
728 (lazy-lock-fontify-line-after-change beg end old-len) | |
586 (save-buffer-state nil | 729 (save-buffer-state nil |
587 (unless (memq (current-buffer) lazy-lock-buffers) | 730 (unless (memq (current-buffer) lazy-lock-buffers) |
588 (push (current-buffer) lazy-lock-buffers)) | 731 (push (current-buffer) lazy-lock-buffers)) |
589 (remove-text-properties | 732 (remove-text-properties end (point-max) '(lazy-lock nil)))) |
590 (max (1- beg) (point-min)) (min (1+ end) (point-max)) '(lazy-lock nil)))) | 733 |
734 (defun lazy-lock-defer-line-after-change (beg end old-len) | |
735 ;; Called from `after-change-functions'. | |
736 ;; Defer fontification of the current change. Save the current buffer so | |
737 ;; that we subsequently fontify in all windows showing the buffer. | |
738 (save-buffer-state nil | |
739 (unless (memq (current-buffer) lazy-lock-buffers) | |
740 (push (current-buffer) lazy-lock-buffers)) | |
741 (remove-text-properties (max (1- beg) (point-min)) | |
742 (min (1+ end) (point-max)) | |
743 '(lazy-lock nil)))) | |
744 | |
745 (defun lazy-lock-defer-rest-after-change (beg end old-len) | |
746 ;; Called from `after-change-functions'. | |
747 ;; Defer fontification of the rest of the buffer. Save the current buffer so | |
748 ;; that we subsequently fontify in all windows showing the buffer. | |
749 (save-buffer-state nil | |
750 (unless (memq (current-buffer) lazy-lock-buffers) | |
751 (push (current-buffer) lazy-lock-buffers)) | |
752 (remove-text-properties (max (1- beg) (point-min)) | |
753 (point-max) | |
754 '(lazy-lock nil)))) | |
755 | |
756 ;; 3. Deferred fontification and stealth fontification are done from these two | |
757 ;; functions. They are set up as Idle Timers. | |
591 | 758 |
592 (defun lazy-lock-fontify-after-defer () | 759 (defun lazy-lock-fontify-after-defer () |
593 ;; Called from `timer-idle-list'. | 760 ;; Called from `timer-idle-list'. |
594 ;; Fontify all windows where deferral has occurred for its buffer. | 761 ;; Fontify all windows where deferral has occurred for its buffer. |
595 (while (and lazy-lock-buffers (not (input-pending-p))) | 762 (while (and lazy-lock-buffers (not (input-pending-p))) |
597 (while windows | 764 (while windows |
598 (lazy-lock-fontify-window (car windows)) | 765 (lazy-lock-fontify-window (car windows)) |
599 (setq windows (cdr windows))) | 766 (setq windows (cdr windows))) |
600 (setq lazy-lock-buffers (cdr lazy-lock-buffers)))) | 767 (setq lazy-lock-buffers (cdr lazy-lock-buffers)))) |
601 ;; Add hook if fontification should now be defer-driven in this buffer. | 768 ;; Add hook if fontification should now be defer-driven in this buffer. |
602 (when (and lazy-lock-mode lazy-lock-defer-driven | 769 (when (and lazy-lock-mode lazy-lock-defer-on-scrolling |
603 (memq 'lazy-lock-fontify-after-scroll window-scroll-functions) | 770 (memq 'lazy-lock-fontify-after-scroll window-scroll-functions) |
604 (not (or (input-pending-p) (lazy-lock-unfontified-p)))) | 771 (not (or (input-pending-p) (lazy-lock-unfontified-p)))) |
605 (remove-hook 'window-scroll-functions 'lazy-lock-fontify-after-scroll t) | 772 (remove-hook 'window-scroll-functions 'lazy-lock-fontify-after-scroll t) |
606 (add-hook 'window-scroll-functions 'lazy-lock-defer-after-scroll nil t))) | 773 (add-hook 'window-scroll-functions 'lazy-lock-defer-after-scroll nil t))) |
607 | 774 |
615 (do-while (and buffers continue) | 782 (do-while (and buffers continue) |
616 (set-buffer (car buffers)) | 783 (set-buffer (car buffers)) |
617 (if (not (and lazy-lock-mode (lazy-lock-unfontified-p))) | 784 (if (not (and lazy-lock-mode (lazy-lock-unfontified-p))) |
618 (setq continue (not (input-pending-p))) | 785 (setq continue (not (input-pending-p))) |
619 ;; Fontify regions in this buffer while there is no input. | 786 ;; Fontify regions in this buffer while there is no input. |
620 (do-while (and (lazy-lock-unfontified-p) | 787 (do-while (and (lazy-lock-unfontified-p) continue) |
621 (setq continue (sit-for lazy-lock-stealth-nice))) | 788 (if (and lazy-lock-stealth-load |
622 (when lazy-lock-stealth-verbose | 789 (> (car (load-average)) lazy-lock-stealth-load)) |
623 (if message | 790 ;; Wait a while before continuing with the loop. |
624 (message "Fontifying stealthily... %2d%% of %s" | 791 (progn |
625 (lazy-lock-percent-fontified) (buffer-name)) | 792 (when message |
626 (message "Fontifying stealthily...") | 793 (message "Fontifying stealthily...suspended") |
627 (setq message t))) | 794 (setq message nil)) |
628 (lazy-lock-fontify-chunk))) | 795 (setq continue (sit-for (or lazy-lock-stealth-time 30)))) |
796 ;; Fontify a chunk. | |
797 (when lazy-lock-stealth-verbose | |
798 (if message | |
799 (message "Fontifying stealthily... %2d%% of %s" | |
800 (lazy-lock-percent-fontified) (buffer-name)) | |
801 (message "Fontifying stealthily...") | |
802 (setq message t))) | |
803 (lazy-lock-fontify-chunk) | |
804 (setq continue (sit-for (or lazy-lock-stealth-nice 0)))))) | |
629 (setq buffers (cdr buffers)))) | 805 (setq buffers (cdr buffers)))) |
630 (when message | 806 (when message |
631 (message "Fontifying stealthily...%s" (if continue "done" "quit")))))) | 807 (message "Fontifying stealthily...%s" (if continue "done" "quit")))))) |
808 | |
809 ;; 4. Special circumstances. | |
632 | 810 |
633 (defun lazy-lock-fontify-after-outline () | 811 (defun lazy-lock-fontify-after-outline () |
634 ;; Called from `outline-view-change-hook'. | 812 ;; Called from `outline-view-change-hook'. |
635 ;; Fontify windows showing the current buffer, as its visibility has changed. | 813 ;; Fontify windows showing the current buffer, as its visibility has changed. |
636 ;; This is a conspiracy hack between lazy-lock.el and noutline.el. | 814 ;; This is a conspiracy hack between lazy-lock.el and noutline.el. |
714 (point)))))))) | 892 (point)))))))) |
715 | 893 |
716 (defun lazy-lock-fontify-window (window) | 894 (defun lazy-lock-fontify-window (window) |
717 ;; Fontify in WINDOW between `window-start' and `window-end'. | 895 ;; Fontify in WINDOW between `window-start' and `window-end'. |
718 ;; We can only do this when we can use `window-start' and `window-end'. | 896 ;; We can only do this when we can use `window-start' and `window-end'. |
719 (save-excursion | 897 (with-current-buffer (window-buffer window) |
720 (set-buffer (window-buffer window)) | |
721 (lazy-lock-fontify-region (window-start window) (window-end window)))) | 898 (lazy-lock-fontify-region (window-start window) (window-end window)))) |
722 | 899 |
723 (defun lazy-lock-fontify-conservatively (window) | 900 (defun lazy-lock-fontify-conservatively (window) |
724 ;; Fontify in WINDOW conservatively around point. | 901 ;; Fontify in WINDOW conservatively around point. |
725 ;; Where we cannot use `window-start' and `window-end' we do `window-height' | 902 ;; 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. | 903 ;; lines around point. That way we guarantee to have done enough. |
727 (save-excursion | 904 (with-current-buffer (window-buffer window) |
728 (set-buffer (window-buffer window)) | |
729 (lazy-lock-fontify-region | 905 (lazy-lock-fontify-region |
730 (save-excursion | 906 (save-excursion |
731 (vertical-motion (- (window-height window)) window) (point)) | 907 (vertical-motion (- (window-height window)) window) (point)) |
732 (save-excursion | 908 (save-excursion |
733 (vertical-motion (window-height window) window) (point))))) | 909 (vertical-motion (window-height window) window) (point))))) |
740 | 916 |
741 (defun lazy-lock-percent-fontified () | 917 (defun lazy-lock-percent-fontified () |
742 ;; Return the percentage (of characters) of the buffer that are fontified. | 918 ;; Return the percentage (of characters) of the buffer that are fontified. |
743 (save-restriction | 919 (save-restriction |
744 (widen) | 920 (widen) |
745 (let ((beg (point-min)) (end (point-max)) (size 0) next) | 921 (let ((beg (point-min)) (size 0) next) |
746 ;; Find where the next fontified region begins. | 922 ;; Find where the next fontified region begins. |
747 (while (setq beg (text-property-any beg end 'lazy-lock t)) | 923 (while (setq beg (text-property-any beg (point-max) 'lazy-lock t)) |
748 (setq next (or (text-property-any beg end 'lazy-lock nil) end) | 924 (setq next (or (text-property-any beg (point-max) 'lazy-lock nil) |
749 size (+ size (- next beg)) | 925 (point-max))) |
750 beg next)) | 926 (incf size (- next beg)) |
751 (/ (* size 100) (buffer-size))))) | 927 (setq beg next)) |
928 ;; Float because using integer multiplication will frequently overflow. | |
929 (truncate (* (/ (float size) (point-max)) 100))))) | |
752 | 930 |
753 ;; Version dependent workarounds and fixes. | 931 ;; Version dependent workarounds and fixes. |
754 | 932 |
755 (when (if (save-match-data (string-match "Lucid\\|XEmacs" (emacs-version))) | 933 (when (if (save-match-data (string-match "Lucid\\|XEmacs" (emacs-version))) |
756 nil | 934 nil |
782 (defun lazy-lock-fontify-after-install () | 960 (defun lazy-lock-fontify-after-install () |
783 (remove-hook 'post-command-hook 'lazy-lock-fontify-after-install) | 961 (remove-hook 'post-command-hook 'lazy-lock-fontify-after-install) |
784 (while lazy-lock-install | 962 (while lazy-lock-install |
785 (mapcar 'lazy-lock-fontify-conservatively | 963 (mapcar 'lazy-lock-fontify-conservatively |
786 (get-buffer-window-list (pop lazy-lock-install) 'nomini t))))) | 964 (get-buffer-window-list (pop lazy-lock-install) 'nomini t))))) |
965 | |
966 (when (consp lazy-lock-defer-time) | |
967 ;; | |
968 ;; In 2.06.04 and below, `lazy-lock-defer-time' could specify modes and time. | |
969 (with-output-to-temp-buffer "*Help*" | |
970 (princ "The value of the variable `lazy-lock-defer-time' was\n ") | |
971 (princ lazy-lock-defer-time) | |
972 (princ "\n") | |
973 (princ "This variable cannot now be a list of modes and time, ") | |
974 (princ "so instead use the forms:\n") | |
975 (princ " (setq lazy-lock-defer-time ") | |
976 (princ (cdr lazy-lock-defer-time)) | |
977 (princ ")\n") | |
978 (princ " (setq lazy-lock-defer-on-the-fly '") | |
979 (princ (car lazy-lock-defer-time)) | |
980 (princ ")\n") | |
981 (princ "in your ~/.emacs. ") | |
982 (princ "The above forms have been evaluated for this editor session,\n") | |
983 (princ "but you should change your ~/.emacs now.")) | |
984 (setq lazy-lock-defer-on-the-fly (car lazy-lock-defer-time) | |
985 lazy-lock-defer-time (cdr lazy-lock-defer-time))) | |
986 | |
987 (when (boundp 'lazy-lock-defer-driven) | |
988 ;; | |
989 ;; In 2.06.04 and below, `lazy-lock-defer-driven' was the variable name. | |
990 (with-output-to-temp-buffer "*Help*" | |
991 (princ "The value of the variable `lazy-lock-defer-driven' is set to ") | |
992 (if (memq lazy-lock-defer-driven '(nil t)) | |
993 (princ lazy-lock-defer-driven) | |
994 (princ "`") | |
995 (princ lazy-lock-defer-driven) | |
996 (princ "'")) | |
997 (princ ".\n") | |
998 (princ "This variable is now called `lazy-lock-defer-on-scrolling',\n") | |
999 (princ "so instead use the form:\n") | |
1000 (princ " (setq lazy-lock-defer-on-scrolling ") | |
1001 (unless (memq lazy-lock-defer-driven '(nil t)) | |
1002 (princ "'")) | |
1003 (princ lazy-lock-defer-driven) | |
1004 (princ ")\n") | |
1005 (princ "in your ~/.emacs. ") | |
1006 (princ "The above form has been evaluated for this editor session,\n") | |
1007 (princ "but you should change your ~/.emacs now.")) | |
1008 (setq lazy-lock-defer-on-scrolling lazy-lock-defer-driven)) | |
787 | 1009 |
788 ;; Possibly absent. | 1010 ;; Possibly absent. |
789 | 1011 |
790 (unless (boundp 'font-lock-inhibit-thing-lock) | 1012 (unless (boundp 'font-lock-inhibit-thing-lock) |
791 ;; Font Lock mode uses this to direct Lazy and Fast Lock modes to stay off. | 1013 ;; Font Lock mode uses this to direct Lazy and Fast Lock modes to stay off. |