Regenerate ldefs-boot.el
[bpt/emacs.git] / lisp / jit-lock.el
CommitLineData
117f94cf 1;;; jit-lock.el --- just-in-time fontification -*- lexical-binding: t -*-
7840ced1 2
ba318903 3;; Copyright (C) 1998, 2000-2014 Free Software Foundation, Inc.
7840ced1
GM
4
5;; Author: Gerd Moellmann <gerd@gnu.org>
6;; Keywords: faces files
bd78fa1d 7;; Package: emacs
7840ced1
GM
8
9;; This file is part of GNU Emacs.
10
eb3fa2cf 11;; GNU Emacs is free software: you can redistribute it and/or modify
7840ced1 12;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
13;; the Free Software Foundation, either version 3 of the License, or
14;; (at your option) any later version.
7840ced1
GM
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
eb3fa2cf 22;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
7840ced1
GM
23
24;;; Commentary:
25
26;; Just-in-time fontification, triggered by C redisplay code.
27
28;;; Code:
29
30
7840ced1 31(eval-when-compile
bcacade9 32 (defmacro with-buffer-prepared-for-jit-lock (&rest body)
7840ced1
GM
33 "Execute BODY in current buffer, overriding several variables.
34Preserves the `buffer-modified-p' state of the current buffer."
7b4d9d3b 35 (declare (debug t))
d36b74ca
SM
36 `(let ((inhibit-point-motion-hooks t))
37 (with-silent-modifications
38 ,@body))))
7840ced1
GM
39\f
40;;; Customization.
41
623a1226
SM
42(defgroup jit-lock nil
43 "Font Lock support mode to fontify just-in-time."
623a1226
SM
44 :version "21.1"
45 :group 'font-lock)
46
7840ced1 47(defcustom jit-lock-chunk-size 500
9201cc28 48 "Jit-lock fontifies chunks of at most this many characters at a time.
45cb4c96
EZ
49
50This variable controls both display-time and stealth fontification."
7840ced1
GM
51 :type 'integer
52 :group 'jit-lock)
53
54
d0483d25 55(defcustom jit-lock-stealth-time nil
9201cc28 56 "Time in seconds to wait before beginning stealth fontification.
7840ced1 57Stealth fontification occurs if there is no input within this time.
f86292a9 58If nil, stealth fontification is never performed.
7840ced1
GM
59
60The value of this variable is used when JIT Lock mode is turned on."
61 :type '(choice (const :tag "never" nil)
d0483d25 62 (number :tag "seconds" :value 16))
7840ced1
GM
63 :group 'jit-lock)
64
65
4739237d 66(defcustom jit-lock-stealth-nice 0.5
9201cc28 67 "Time in seconds to pause between chunks of stealth fontification.
7840ced1
GM
68Each iteration of stealth fontification is separated by this amount of time,
69thus reducing the demand that stealth fontification makes on the system.
70If nil, means stealth fontification is never paused.
71To reduce machine load during stealth fontification, at the cost of stealth
72taking longer to fontify, you could increase the value of this variable.
73See also `jit-lock-stealth-load'."
74 :type '(choice (const :tag "never" nil)
f1180544 75 (number :tag "seconds"))
7840ced1 76 :group 'jit-lock)
f1180544 77
7840ced1
GM
78
79(defcustom jit-lock-stealth-load
80 (if (condition-case nil (load-average) (error)) 200)
9201cc28 81 "Load in percentage above which stealth fontification is suspended.
7840ced1
GM
82Stealth fontification pauses when the system short-term load average (as
83returned by the function `load-average' if supported) goes above this level,
84thus reducing the demand that stealth fontification makes on the system.
85If nil, means stealth fontification is never suspended.
86To reduce machine load during stealth fontification, at the cost of stealth
87taking longer to fontify, you could reduce the value of this variable.
88See also `jit-lock-stealth-nice'."
89 :type (if (condition-case nil (load-average) (error))
90 '(choice (const :tag "never" nil)
91 (integer :tag "load"))
92 '(const :format "%t: unsupported\n" nil))
93 :group 'jit-lock)
94
95
96(defcustom jit-lock-stealth-verbose nil
9201cc28 97 "If non-nil, means stealth fontification should show status messages."
7840ced1
GM
98 :type 'boolean
99 :group 'jit-lock)
100
101
f415f2d7
SM
102(defvaralias 'jit-lock-defer-contextually 'jit-lock-contextually)
103(defcustom jit-lock-contextually 'syntax-driven
9201cc28 104 "If non-nil, means fontification should be syntactically true.
f415f2d7 105If nil, means fontification occurs only on those lines modified. This
7840ced1
GM
106means where modification on a line causes syntactic change on subsequent lines,
107those subsequent lines are not refontified to reflect their new context.
f415f2d7 108If t, means fontification occurs on those lines modified and all
7840ced1 109subsequent lines. This means those subsequent lines are refontified to reflect
7b4d9d3b 110their new syntactic context, after `jit-lock-context-time' seconds.
f415f2d7 111If any other value, e.g., `syntax-driven', means syntactically true
7840ced1
GM
112fontification occurs only if syntactic fontification is performed using the
113buffer mode's syntax table, i.e., only if `font-lock-keywords-only' is nil.
114
115The value of this variable is used when JIT Lock mode is turned on."
116 :type '(choice (const :tag "never" nil)
117 (const :tag "always" t)
118 (other :tag "syntax-driven" syntax-driven))
119 :group 'jit-lock)
120
7b4d9d3b
SM
121(defcustom jit-lock-context-time 0.5
122 "Idle time after which text is contextually refontified, if applicable."
f5307782
JB
123 :type '(number :tag "seconds")
124 :group 'jit-lock)
125
8e069ce2 126(defcustom jit-lock-defer-time nil ;; 0.25
b743187d
SM
127 "Idle time after which deferred fontification should take place.
128If nil, fontification is not deferred."
129 :group 'jit-lock
130 :type '(choice (const :tag "never" nil)
131 (number :tag "seconds")))
7840ced1
GM
132\f
133;;; Variables that are not customizable.
134
1d4e7225 135(defvar-local jit-lock-mode nil
7840ced1 136 "Non-nil means Just-in-time Lock mode is active.")
7840ced1 137
1d4e7225 138(defvar-local jit-lock-functions nil
be390cb3
SM
139 "Functions to do the actual fontification.
140They are called with two arguments: the START and END of the region to fontify.")
7840ced1 141
1d4e7225 142(defvar-local jit-lock-context-unfontify-pos nil
a62e3c6f 143 "Consider text after this position as contextually unfontified.
bcacade9 144If nil, contextual fontification is disabled.")
7840ced1
GM
145
146(defvar jit-lock-stealth-timer nil
147 "Timer for stealth fontification in Just-in-time Lock mode.")
1063efe8
CY
148(defvar jit-lock-stealth-repeat-timer nil
149 "Timer for repeated stealth fontification in Just-in-time Lock mode.")
7b4d9d3b
SM
150(defvar jit-lock-context-timer nil
151 "Timer for context fontification in Just-in-time Lock mode.")
b743187d
SM
152(defvar jit-lock-defer-timer nil
153 "Timer for deferred fontification in Just-in-time Lock mode.")
154
623a1226 155(defvar jit-lock-defer-buffers nil
b743187d 156 "List of buffers with pending deferred fontification.")
1063efe8
CY
157(defvar jit-lock-stealth-buffers nil
158 "List of buffers that are being fontified stealthily.")
7840ced1
GM
159\f
160;;; JIT lock mode
161
7840ced1
GM
162(defun jit-lock-mode (arg)
163 "Toggle Just-in-time Lock mode.
bcacade9 164Turn Just-in-time Lock mode on if and only if ARG is non-nil.
7840ced1
GM
165Enable it automatically by customizing group `font-lock'.
166
167When Just-in-time Lock mode is enabled, fontification is different in the
168following ways:
169
170- Demand-driven buffer fontification triggered by Emacs C code.
171 This means initial fontification of the whole buffer does not occur.
172 Instead, fontification occurs when necessary, such as when scrolling
173 through the buffer would otherwise reveal unfontified areas. This is
174 useful if buffer fontification is too slow for large buffers.
175
176- Stealthy buffer fontification if `jit-lock-stealth-time' is non-nil.
177 This means remaining unfontified areas of buffers are fontified if Emacs has
178 been idle for `jit-lock-stealth-time' seconds, while Emacs remains idle.
179 This is useful if any buffer has any deferred fontification.
180
f415f2d7 181- Deferred context fontification if `jit-lock-contextually' is
7840ced1 182 non-nil. This means fontification updates the buffer corresponding to
7b4d9d3b 183 true syntactic context, after `jit-lock-context-time' seconds of Emacs
7840ced1
GM
184 idle time, while Emacs remains idle. Otherwise, fontification occurs
185 on modified lines only, and subsequent lines can remain fontified
186 corresponding to previous syntactic contexts. This is useful where
187 strings or comments span lines.
188
189Stealth fontification only occurs while the system remains unloaded.
190If the system load rises above `jit-lock-stealth-load' percent, stealth
191fontification is suspended. Stealth fontification intensity is controlled via
47a73eb0
GM
192the variable `jit-lock-stealth-nice'.
193
194If you need to debug code run from jit-lock, see `jit-lock-debug-mode'."
bcacade9 195 (setq jit-lock-mode arg)
eb4c6947
SM
196 (cond
197 ((buffer-base-buffer)
198 ;; We're in an indirect buffer. This doesn't work because jit-lock relies
199 ;; on the `fontified' text-property which is shared with the base buffer.
200 (setq jit-lock-mode nil)
201 (message "Not enabling jit-lock: it does not work in indirect buffer"))
202
203 (jit-lock-mode ;; Turn Just-in-time Lock mode on.
204
205 ;; Mark the buffer for refontification.
206 (jit-lock-refontify)
207
208 ;; Install an idle timer for stealth fontification.
209 (when (and jit-lock-stealth-time (null jit-lock-stealth-timer))
210 (setq jit-lock-stealth-timer
211 (run-with-idle-timer jit-lock-stealth-time t
212 'jit-lock-stealth-fontify)))
213
214 ;; Create, but do not activate, the idle timer for repeated
215 ;; stealth fontification.
216 (when (and jit-lock-stealth-time (null jit-lock-stealth-repeat-timer))
217 (setq jit-lock-stealth-repeat-timer (timer-create))
218 (timer-set-function jit-lock-stealth-repeat-timer
219 'jit-lock-stealth-fontify '(t)))
220
221 ;; Init deferred fontification timer.
222 (when (and jit-lock-defer-time (null jit-lock-defer-timer))
223 (setq jit-lock-defer-timer
224 (run-with-idle-timer jit-lock-defer-time t
225 'jit-lock-deferred-fontify)))
226
227 ;; Initialize contextual fontification if requested.
228 (when (eq jit-lock-contextually t)
229 (unless jit-lock-context-timer
230 (setq jit-lock-context-timer
231 (run-with-idle-timer jit-lock-context-time t
232 'jit-lock-context-fontify)))
233 (setq jit-lock-context-unfontify-pos
234 (or jit-lock-context-unfontify-pos (point-max))))
235
236 ;; Setup our hooks.
237 (add-hook 'after-change-functions 'jit-lock-after-change nil t)
238 (add-hook 'fontification-functions 'jit-lock-function))
239
240 ;; Turn Just-in-time Lock mode off.
241 (t
242 ;; Cancel our idle timers.
243 (when (and (or jit-lock-stealth-timer jit-lock-defer-timer
244 jit-lock-context-timer)
245 ;; Only if there's no other buffer using them.
246 (not (catch 'found
247 (dolist (buf (buffer-list))
248 (with-current-buffer buf
249 (when jit-lock-mode (throw 'found t)))))))
250 (when jit-lock-stealth-timer
251 (cancel-timer jit-lock-stealth-timer)
252 (setq jit-lock-stealth-timer nil))
253 (when jit-lock-context-timer
254 (cancel-timer jit-lock-context-timer)
255 (setq jit-lock-context-timer nil))
256 (when jit-lock-defer-timer
257 (cancel-timer jit-lock-defer-timer)
258 (setq jit-lock-defer-timer nil)))
259
260 ;; Remove hooks.
261 (remove-hook 'after-change-functions 'jit-lock-after-change t)
262 (remove-hook 'fontification-functions 'jit-lock-function))))
7840ced1 263
e5b5a34d
SM
264(define-minor-mode jit-lock-debug-mode
265 "Minor mode to help debug code run from jit-lock.
266When this minor mode is enabled, jit-lock runs as little code as possible
267during redisplay and moves the rest to a timer, where things
268like `debug-on-error' and Edebug can be used."
ed8be7ff 269 :global t :group 'jit-lock
e5b5a34d
SM
270 (when jit-lock-defer-timer
271 (cancel-timer jit-lock-defer-timer)
272 (setq jit-lock-defer-timer nil))
273 (when jit-lock-debug-mode
274 (setq jit-lock-defer-timer
275 (run-with-idle-timer 0 t #'jit-lock--debug-fontify))))
276
277(defvar jit-lock--debug-fontifying nil)
278
279(defun jit-lock--debug-fontify ()
280 "Fontify what was deferred for debugging."
281 (when (and (not jit-lock--debug-fontifying)
282 jit-lock-defer-buffers (not memory-full))
283 (let ((jit-lock--debug-fontifying t)
284 (inhibit-debugger nil)) ;FIXME: Not sufficient!
285 ;; Mark the deferred regions back to `fontified = nil'
286 (dolist (buffer jit-lock-defer-buffers)
287 (when (buffer-live-p buffer)
288 (with-current-buffer buffer
289 ;; (message "Jit-Debug %s" (buffer-name))
290 (with-buffer-prepared-for-jit-lock
291 (let ((pos (point-min)))
292 (while
293 (progn
294 (when (eq (get-text-property pos 'fontified) 'defer)
295 (let ((beg pos)
296 (end (setq pos (next-single-property-change
297 pos 'fontified
298 nil (point-max)))))
299 (put-text-property beg end 'fontified nil)
300 (jit-lock-fontify-now beg end)))
301 (setq pos (next-single-property-change
302 pos 'fontified)))))))))
303 (setq jit-lock-defer-buffers nil))))
304
c94d5f40 305(defun jit-lock-register (fun &optional contextual)
8a677d4f
SM
306 "Register FUN as a fontification function to be called in this buffer.
307FUN will be called with two arguments START and END indicating the region
c94d5f40
SM
308that needs to be (re)fontified.
309If non-nil, CONTEXTUAL means that a contextual fontification would be useful."
f8bacc70 310 (add-hook 'jit-lock-functions fun nil t)
f415f2d7 311 (when (and contextual jit-lock-contextually)
1d4e7225 312 (setq-local jit-lock-contextually t))
f8bacc70
SM
313 (jit-lock-mode t))
314
315(defun jit-lock-unregister (fun)
8a677d4f 316 "Unregister FUN as a fontification function.
f8bacc70
SM
317Only applies to the current buffer."
318 (remove-hook 'jit-lock-functions fun t)
a62e3c6f 319 (unless jit-lock-functions (jit-lock-mode nil)))
7840ced1 320
02b420eb
SM
321;; This function is used to prevent font-lock-fontify-buffer from
322;; fontifying eagerly the whole buffer. This is important for
323;; things like CWarn mode which adds/removes a few keywords and
324;; does a refontify (which takes ages on large files).
a62e3c6f
SM
325(defun jit-lock-refontify (&optional beg end)
326 "Force refontification of the region BEG..END (default whole buffer)."
bcacade9 327 (with-buffer-prepared-for-jit-lock
5a5987eb
SM
328 (save-restriction
329 (widen)
b743187d
SM
330 (put-text-property (or beg (point-min)) (or end (point-max))
331 'fontified nil))))
7840ced1
GM
332\f
333;;; On demand fontification.
334
335(defun jit-lock-function (start)
336 "Fontify current buffer starting at position START.
337This function is added to `fontification-functions' when `jit-lock-mode'
338is active."
74614ac6 339 (when (and jit-lock-mode (not memory-full))
0902822d 340 (if (null jit-lock-defer-timer)
b743187d
SM
341 ;; No deferral.
342 (jit-lock-fontify-now start (+ start jit-lock-chunk-size))
343 ;; Record the buffer for later fontification.
623a1226
SM
344 (unless (memq (current-buffer) jit-lock-defer-buffers)
345 (push (current-buffer) jit-lock-defer-buffers))
b743187d
SM
346 ;; Mark the area as defer-fontified so that the redisplay engine
347 ;; is happy and so that the idle timer can find the places to fontify.
348 (with-buffer-prepared-for-jit-lock
349 (put-text-property start
350 (next-single-property-change
351 start 'fontified nil
352 (min (point-max) (+ start jit-lock-chunk-size)))
353 'fontified 'defer)))))
a62e3c6f
SM
354
355(defun jit-lock-fontify-now (&optional start end)
356 "Fontify current buffer from START to END.
357Defaults to the whole buffer. END can be out of bounds."
bcacade9 358 (with-buffer-prepared-for-jit-lock
60bffb78 359 (save-excursion
c9cf2e67
SM
360 (unless start (setq start (point-min)))
361 (setq end (if end (min end (point-max)) (point-max)))
362 ;; This did bind `font-lock-beginning-of-syntax-function' to
363 ;; nil at some point, for an unknown reason. Don't do this; it
364 ;; can make highlighting slow due to expensive calls to
365 ;; `parse-partial-sexp' in function
366 ;; `font-lock-fontify-syntactically-region'. Example: paging
367 ;; from the end of a buffer to its start, can do repeated
368 ;; `parse-partial-sexp' starting from `point-min', which can
369 ;; take a long time in a large buffer.
663e1660 370 (let ((orig-start start) next)
c9cf2e67
SM
371 (save-match-data
372 ;; Fontify chunks beginning at START. The end of a
373 ;; chunk is either `end', or the start of a region
374 ;; before `end' that has already been fontified.
c1860747 375 (while (and start (< start end))
c9cf2e67
SM
376 ;; Determine the end of this chunk.
377 (setq next (or (text-property-any start end 'fontified t)
378 end))
379
380 ;; Decide which range of text should be fontified.
381 ;; The problem is that START and NEXT may be in the
382 ;; middle of something matched by a font-lock regexp.
383 ;; Until someone has a better idea, let's start
384 ;; at the start of the line containing START and
385 ;; stop at the start of the line following NEXT.
386 (goto-char next) (setq next (line-beginning-position 2))
387 (goto-char start) (setq start (line-beginning-position))
f1180544 388
c4ac63d0
SM
389 ;; Make sure the contextual refontification doesn't re-refontify
390 ;; what's already been refontified.
c4ac63d0
SM
391 (when (and jit-lock-context-unfontify-pos
392 (< jit-lock-context-unfontify-pos next)
7aaf6f17
SM
393 (>= jit-lock-context-unfontify-pos start)
394 ;; Don't move boundary forward if we have to
395 ;; refontify previous text. Otherwise, we risk moving
396 ;; it past the end of the multiline property and thus
397 ;; forget about this multiline region altogether.
398 (not (get-text-property start 'jit-lock-defer-multiline)))
c4ac63d0
SM
399 (setq jit-lock-context-unfontify-pos next))
400
c9cf2e67
SM
401 ;; Fontify the chunk, and mark it as fontified.
402 ;; We mark it first, to make sure that we don't indefinitely
403 ;; re-execute this fontification if an error occurs.
404 (put-text-property start next 'fontified t)
f415f2d7
SM
405 (condition-case err
406 (run-hook-with-args 'jit-lock-functions start next)
407 ;; If the user quits (which shouldn't happen in normal on-the-fly
408 ;; jit-locking), make sure the fontification will be performed
409 ;; before displaying the block again.
410 (quit (put-text-property start next 'fontified nil)
411 (funcall 'signal (car err) (cdr err))))
c9cf2e67 412
663e1660
SM
413 ;; The redisplay engine has already rendered the buffer up-to
414 ;; `orig-start' and won't notice if the above jit-lock-functions
415 ;; changed the appearance of any part of the buffer prior
416 ;; to that. So if `start' is before `orig-start', we need to
417 ;; cause a new redisplay cycle after this one so that any changes
418 ;; are properly reflected on screen.
419 ;; To make such repeated redisplay happen less often, we can
420 ;; eagerly extend the refontified region with
421 ;; jit-lock-after-change-extend-region-functions.
422 (when (< start orig-start)
117f94cf
SM
423 (run-with-timer 0 nil #'jit-lock-force-redisplay
424 (copy-marker start) (copy-marker orig-start)))
663e1660 425
c9cf2e67
SM
426 ;; Find the start of the next chunk, if any.
427 (setq start (text-property-any next end 'fontified nil))))))))
7840ced1 428
117f94cf 429(defun jit-lock-force-redisplay (start end)
bacb3380
GM
430 "Force the display engine to re-render START's buffer from START to END.
431This applies to the buffer associated with marker START."
117f94cf
SM
432 (when (marker-buffer start)
433 (with-current-buffer (marker-buffer start)
434 (with-buffer-prepared-for-jit-lock
435 (when (> end (point-max))
436 (setq end (point-max) start (min start end)))
437 (when (< start (point-min))
438 (setq start (point-min) end (max start end)))
439 ;; Don't cause refontification (it's already been done), but just do
440 ;; some random buffer change, so as to force redisplay.
441 (put-text-property start end 'fontified t)))))
7840ced1
GM
442\f
443;;; Stealth fontification.
444
445(defsubst jit-lock-stealth-chunk-start (around)
6dea7173 446 "Return the start of the next chunk to fontify around position AROUND.
7840ced1 447Value is nil if there is nothing more to fontify."
8c887c51
GM
448 (if (zerop (buffer-size))
449 nil
1d4e7225
SM
450 (let* ((next (text-property-not-all around (point-max) 'fontified t))
451 (prev (previous-single-property-change around 'fontified))
452 (prop (get-text-property (max (point-min) (1- around))
453 'fontified))
454 (start (cond
455 ((null prev)
456 ;; There is no property change between AROUND
457 ;; and the start of the buffer. If PROP is
458 ;; non-nil, everything in front of AROUND is
459 ;; fontified, otherwise nothing is fontified.
460 (if (eq prop t)
461 nil
462 (max (point-min)
463 (- around (/ jit-lock-chunk-size 2)))))
464 ((eq prop t)
465 ;; PREV is the start of a region of fontified
466 ;; text containing AROUND. Start fontifying a
467 ;; chunk size before the end of the unfontified
468 ;; region in front of that.
469 (max (or (previous-single-property-change prev 'fontified)
470 (point-min))
471 (- prev jit-lock-chunk-size)))
472 (t
473 ;; PREV is the start of a region of unfontified
474 ;; text containing AROUND. Start at PREV or
475 ;; chunk size in front of AROUND, whichever is
476 ;; nearer.
477 (max prev (- around jit-lock-chunk-size)))))
478 (result (cond ((null start) next)
479 ((null next) start)
480 ((< (- around start) (- next around)) start)
481 (t next))))
482 result)))
f1180544 483
1063efe8 484(defun jit-lock-stealth-fontify (&optional repeat)
7840ced1 485 "Fontify buffers stealthily.
1063efe8
CY
486This function is called repeatedly after Emacs has become idle for
487`jit-lock-stealth-time' seconds. Optional argument REPEAT is expected
488non-nil in a repeated invocation of this function."
489 ;; Cancel timer for repeated invocations.
490 (unless repeat
491 (cancel-timer jit-lock-stealth-repeat-timer))
7840ced1 492 (unless (or executing-kbd-macro
74614ac6 493 memory-full
290d5b58 494 (window-minibuffer-p)
1063efe8
CY
495 ;; For first invocation set up `jit-lock-stealth-buffers'.
496 ;; In repeated invocations it's already been set up.
497 (null (if repeat
498 jit-lock-stealth-buffers
499 (setq jit-lock-stealth-buffers (buffer-list)))))
500 (let ((buffer (car jit-lock-stealth-buffers))
501 (delay 0)
7840ced1 502 minibuffer-auto-raise
1063efe8
CY
503 message-log-max
504 start)
505 (if (and jit-lock-stealth-load
506 (> (car (load-average)) jit-lock-stealth-load))
507 ;; Wait a little if load is too high.
508 (setq delay jit-lock-stealth-time)
509 (if (buffer-live-p buffer)
510 (with-current-buffer buffer
511 (if (and jit-lock-mode
512 (setq start (jit-lock-stealth-chunk-start (point))))
513 ;; Fontify one block of at most `jit-lock-chunk-size'
514 ;; characters.
515 (with-temp-message (if jit-lock-stealth-verbose
516 (concat "JIT stealth lock "
517 (buffer-name)))
518 (jit-lock-fontify-now start
519 (+ start jit-lock-chunk-size))
520 ;; Run again after `jit-lock-stealth-nice' seconds.
521 (setq delay (or jit-lock-stealth-nice 0)))
522 ;; Nothing to fontify here. Remove this buffer from
523 ;; `jit-lock-stealth-buffers' and run again immediately.
524 (setq jit-lock-stealth-buffers (cdr jit-lock-stealth-buffers))))
525 ;; Buffer is no longer live. Remove it from
526 ;; `jit-lock-stealth-buffers' and run again immediately.
527 (setq jit-lock-stealth-buffers (cdr jit-lock-stealth-buffers))))
528 ;; Call us again.
529 (when jit-lock-stealth-buffers
530 (timer-set-idle-time jit-lock-stealth-repeat-timer (current-idle-time))
531 (timer-inc-time jit-lock-stealth-repeat-timer delay)
532 (timer-activate-when-idle jit-lock-stealth-repeat-timer t)))))
7840ced1
GM
533
534\f
535;;; Deferred fontification.
536
b743187d
SM
537(defun jit-lock-deferred-fontify ()
538 "Fontify what was deferred."
74614ac6 539 (when (and jit-lock-defer-buffers (not memory-full))
b743187d 540 ;; Mark the deferred regions back to `fontified = nil'
623a1226 541 (dolist (buffer jit-lock-defer-buffers)
b743187d
SM
542 (when (buffer-live-p buffer)
543 (with-current-buffer buffer
544 ;; (message "Jit-Defer %s" (buffer-name))
545 (with-buffer-prepared-for-jit-lock
546 (let ((pos (point-min)))
547 (while
548 (progn
549 (when (eq (get-text-property pos 'fontified) 'defer)
550 (put-text-property
551 pos (setq pos (next-single-property-change
552 pos 'fontified nil (point-max)))
553 'fontified nil))
e5b5a34d
SM
554 (setq pos (next-single-property-change
555 pos 'fontified)))))))))
623a1226 556 (setq jit-lock-defer-buffers nil)
b743187d 557 ;; Force fontification of the visible parts.
0902822d 558 (let ((jit-lock-defer-timer nil))
b743187d
SM
559 ;; (message "Jit-Defer Now")
560 (sit-for 0)
561 ;; (message "Jit-Defer Done")
562 )))
f1180544 563
b743187d 564
7b4d9d3b
SM
565(defun jit-lock-context-fontify ()
566 "Refresh fontification to take new context into account."
74614ac6
RS
567 (unless memory-full
568 (dolist (buffer (buffer-list))
569 (with-current-buffer buffer
570 (when jit-lock-context-unfontify-pos
571 ;; (message "Jit-Context %s" (buffer-name))
572 (save-restriction
1d4e7225
SM
573 ;; Don't be blindsided by narrowing that starts in the middle
574 ;; of a jit-lock-defer-multiline.
575 (widen)
74614ac6
RS
576 (when (and (>= jit-lock-context-unfontify-pos (point-min))
577 (< jit-lock-context-unfontify-pos (point-max)))
578 ;; If we're in text that matches a complex multi-line
579 ;; font-lock pattern, make sure the whole text will be
580 ;; redisplayed eventually.
581 ;; Despite its name, we treat jit-lock-defer-multiline here
582 ;; rather than in jit-lock-defer since it has to do with multiple
583 ;; lines, i.e. with context.
584 (when (get-text-property jit-lock-context-unfontify-pos
585 'jit-lock-defer-multiline)
586 (setq jit-lock-context-unfontify-pos
587 (or (previous-single-property-change
588 jit-lock-context-unfontify-pos
589 'jit-lock-defer-multiline)
590 (point-min))))
591 (with-buffer-prepared-for-jit-lock
592 ;; Force contextual refontification.
593 (remove-text-properties
594 jit-lock-context-unfontify-pos (point-max)
595 '(fontified nil jit-lock-defer-multiline nil)))
596 (setq jit-lock-context-unfontify-pos (point-max)))))))))
7b4d9d3b 597
663e1660
SM
598(defvar jit-lock-start) (defvar jit-lock-end) ; Dynamically scoped variables.
599(defvar jit-lock-after-change-extend-region-functions nil
600 "Hook that can extend the text to refontify after a change.
601This is run after every buffer change. The functions are called with
602the three arguments of `after-change-functions': START END OLD-LEN.
603The extended region to refontify is returned indirectly by modifying
604the variables `jit-lock-start' and `jit-lock-end'.
605
9fd762b0
SM
606Note that extending the region this way is not strictly necessary, except
607that the nature of the redisplay code tends to otherwise leave some of
608the rehighlighted text displayed with the old highlight until the next
609redisplay (see comment about repeated redisplay in `jit-lock-fontify-now').")
663e1660 610
7840ced1
GM
611(defun jit-lock-after-change (start end old-len)
612 "Mark the rest of the buffer as not fontified after a change.
613Installed on `after-change-functions'.
614START and END are the start and end of the changed text. OLD-LEN
615is the pre-change length.
616This function ensures that lines following the change will be refontified
617in case the syntax of those lines has changed. Refontification
618will take place when text is fontified stealthily."
74614ac6 619 (when (and jit-lock-mode (not memory-full))
663e1660
SM
620 (let ((jit-lock-start start)
621 (jit-lock-end end))
622 (with-buffer-prepared-for-jit-lock
623 (run-hook-with-args 'jit-lock-after-change-extend-region-functions
624 start end old-len)
625 ;; Make sure we change at least one char (in case of deletions).
626 (setq jit-lock-end (min (max jit-lock-end (1+ start)) (point-max)))
627 ;; Request refontification.
628 (put-text-property jit-lock-start jit-lock-end 'fontified nil))
629 ;; Mark the change for deferred contextual refontification.
630 (when jit-lock-context-unfontify-pos
631 (setq jit-lock-context-unfontify-pos
632 ;; Here we use `start' because nothing guarantees that the
633 ;; text between start and end will be otherwise refontified:
634 ;; usually it will be refontified by virtue of being
635 ;; displayed, but if it's outside of any displayed area in the
636 ;; buffer, only jit-lock-context-* will re-fontify it.
637 (min jit-lock-context-unfontify-pos jit-lock-start))))))
f1180544 638
7840ced1
GM
639(provide 'jit-lock)
640
e8af40ee 641;;; jit-lock.el ends here