Mercurial > emacs
comparison lisp/jit-lock.el @ 72508:5d642f9eff22
* emacs-lisp/timer.el (timer-set-idle-time, run-with-idle-timer):
Accept internal time format for SECS arg.
(timer-relative-time): Doc fix.
* jit-lock.el: "Stealth fontification by requeuing timers" patch,
adapted from Martin Rudalics.
(jit-lock-stealth-repeat-timer, jit-lock-stealth-buffers): New vars.
(jit-lock-mode): Create jit-lock-stealth-repeat-timer.
(jit-lock-stealth-fontify): Reschedule as a idle timer instead of
using sit-for.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Thu, 24 Aug 2006 23:40:00 +0000 |
parents | f13889b47192 |
children | 1ba9cc2a8b76 6823a91487f2 |
comparison
equal
deleted
inserted
replaced
72507:6f2157f30300 | 72508:5d642f9eff22 |
---|---|
169 (make-variable-buffer-local 'jit-lock-context-unfontify-pos) | 169 (make-variable-buffer-local 'jit-lock-context-unfontify-pos) |
170 | 170 |
171 | 171 |
172 (defvar jit-lock-stealth-timer nil | 172 (defvar jit-lock-stealth-timer nil |
173 "Timer for stealth fontification in Just-in-time Lock mode.") | 173 "Timer for stealth fontification in Just-in-time Lock mode.") |
174 (defvar jit-lock-stealth-repeat-timer nil | |
175 "Timer for repeated stealth fontification in Just-in-time Lock mode.") | |
174 (defvar jit-lock-context-timer nil | 176 (defvar jit-lock-context-timer nil |
175 "Timer for context fontification in Just-in-time Lock mode.") | 177 "Timer for context fontification in Just-in-time Lock mode.") |
176 (defvar jit-lock-defer-timer nil | 178 (defvar jit-lock-defer-timer nil |
177 "Timer for deferred fontification in Just-in-time Lock mode.") | 179 "Timer for deferred fontification in Just-in-time Lock mode.") |
178 | 180 |
179 (defvar jit-lock-defer-buffers nil | 181 (defvar jit-lock-defer-buffers nil |
180 "List of buffers with pending deferred fontification.") | 182 "List of buffers with pending deferred fontification.") |
183 (defvar jit-lock-stealth-buffers nil | |
184 "List of buffers that are being fontified stealthily.") | |
181 | 185 |
182 ;;; JIT lock mode | 186 ;;; JIT lock mode |
183 | 187 |
184 (defun jit-lock-mode (arg) | 188 (defun jit-lock-mode (arg) |
185 "Toggle Just-in-time Lock mode. | 189 "Toggle Just-in-time Lock mode. |
222 ;; Install an idle timer for stealth fontification. | 226 ;; Install an idle timer for stealth fontification. |
223 (when (and jit-lock-stealth-time (null jit-lock-stealth-timer)) | 227 (when (and jit-lock-stealth-time (null jit-lock-stealth-timer)) |
224 (setq jit-lock-stealth-timer | 228 (setq jit-lock-stealth-timer |
225 (run-with-idle-timer jit-lock-stealth-time t | 229 (run-with-idle-timer jit-lock-stealth-time t |
226 'jit-lock-stealth-fontify))) | 230 'jit-lock-stealth-fontify))) |
231 | |
232 ;; Create, but do not activate, the idle timer for repeated | |
233 ;; stealth fontification. | |
234 (when (and jit-lock-stealth-time (null jit-lock-stealth-repeat-timer)) | |
235 (setq jit-lock-stealth-repeat-timer (timer-create)) | |
236 (timer-set-function jit-lock-stealth-repeat-timer | |
237 'jit-lock-stealth-fontify '(t))) | |
227 | 238 |
228 ;; Init deferred fontification timer. | 239 ;; Init deferred fontification timer. |
229 (when (and jit-lock-defer-time (null jit-lock-defer-timer)) | 240 (when (and jit-lock-defer-time (null jit-lock-defer-timer)) |
230 (setq jit-lock-defer-timer | 241 (setq jit-lock-defer-timer |
231 (run-with-idle-timer jit-lock-defer-time t | 242 (run-with-idle-timer jit-lock-defer-time t |
441 ((null next) start) | 452 ((null next) start) |
442 ((< (- around start) (- next around)) start) | 453 ((< (- around start) (- next around)) start) |
443 (t next)))) | 454 (t next)))) |
444 result)))) | 455 result)))) |
445 | 456 |
446 | 457 (defun jit-lock-stealth-fontify (&optional repeat) |
447 (defun jit-lock-stealth-fontify () | |
448 "Fontify buffers stealthily. | 458 "Fontify buffers stealthily. |
449 This functions is called after Emacs has been idle for | 459 This function is called repeatedly after Emacs has become idle for |
450 `jit-lock-stealth-time' seconds." | 460 `jit-lock-stealth-time' seconds. Optional argument REPEAT is expected |
451 ;; I used to check `inhibit-read-only' here, but I can't remember why. -stef | 461 non-nil in a repeated invocation of this function." |
462 ;; Cancel timer for repeated invocations. | |
463 (unless repeat | |
464 (cancel-timer jit-lock-stealth-repeat-timer)) | |
452 (unless (or executing-kbd-macro | 465 (unless (or executing-kbd-macro |
453 memory-full | 466 memory-full |
454 (window-minibuffer-p (selected-window))) | 467 (window-minibuffer-p (selected-window)) |
455 (let ((buffers (buffer-list)) | 468 ;; For first invocation set up `jit-lock-stealth-buffers'. |
456 (outer-buffer (current-buffer)) | 469 ;; In repeated invocations it's already been set up. |
470 (null (if repeat | |
471 jit-lock-stealth-buffers | |
472 (setq jit-lock-stealth-buffers (buffer-list))))) | |
473 (let ((buffer (car jit-lock-stealth-buffers)) | |
474 (delay 0) | |
457 minibuffer-auto-raise | 475 minibuffer-auto-raise |
458 message-log-max) | 476 message-log-max |
459 (with-local-quit | 477 start) |
460 (while (and buffers (not (input-pending-p))) | 478 (if (and jit-lock-stealth-load |
461 (with-current-buffer (pop buffers) | 479 (> (car (load-average)) jit-lock-stealth-load)) |
462 (when jit-lock-mode | 480 ;; Wait a little if load is too high. |
463 ;; This is funny. Calling sit-for with 3rd arg non-nil | 481 (setq delay jit-lock-stealth-time) |
464 ;; so that it doesn't redisplay, internally calls | 482 (if (buffer-live-p buffer) |
465 ;; wait_reading_process_input also with a parameter | 483 (with-current-buffer buffer |
466 ;; saying "don't redisplay." Since this function here | 484 (if (and jit-lock-mode |
467 ;; is called periodically, this effectively leads to | 485 (setq start (jit-lock-stealth-chunk-start (point)))) |
468 ;; process output not being redisplayed at all because | 486 ;; Fontify one block of at most `jit-lock-chunk-size' |
469 ;; redisplay_internal is never called. (That didn't | 487 ;; characters. |
470 ;; work in the old redisplay either.) So, we learn that | 488 (with-temp-message (if jit-lock-stealth-verbose |
471 ;; we mustn't call sit-for that way here. But then, we | 489 (concat "JIT stealth lock " |
472 ;; have to be cautious not to call sit-for in a widened | 490 (buffer-name))) |
473 ;; buffer, since this could display hidden parts of that | 491 (jit-lock-fontify-now start |
474 ;; buffer. This explains the seemingly weird use of | 492 (+ start jit-lock-chunk-size)) |
475 ;; save-restriction/widen here. | 493 ;; Run again after `jit-lock-stealth-nice' seconds. |
476 | 494 (setq delay (or jit-lock-stealth-nice 0))) |
477 (with-temp-message (if jit-lock-stealth-verbose | 495 ;; Nothing to fontify here. Remove this buffer from |
478 (concat "JIT stealth lock " | 496 ;; `jit-lock-stealth-buffers' and run again immediately. |
479 (buffer-name))) | 497 (setq jit-lock-stealth-buffers (cdr jit-lock-stealth-buffers)))) |
480 | 498 ;; Buffer is no longer live. Remove it from |
481 ;; In the following code, the `sit-for' calls cause a | 499 ;; `jit-lock-stealth-buffers' and run again immediately. |
482 ;; redisplay, so it's required that the | 500 (setq jit-lock-stealth-buffers (cdr jit-lock-stealth-buffers)))) |
483 ;; buffer-modified flag of a buffer that is displayed | 501 ;; Call us again. |
484 ;; has the right value---otherwise the mode line of | 502 (when jit-lock-stealth-buffers |
485 ;; an unmodified buffer would show a `*'. | 503 (timer-set-idle-time jit-lock-stealth-repeat-timer (current-idle-time)) |
486 (let (start | 504 (timer-inc-time jit-lock-stealth-repeat-timer delay) |
487 (nice (or jit-lock-stealth-nice 0)) | 505 (timer-activate-when-idle jit-lock-stealth-repeat-timer t))))) |
488 (point (point-min))) | |
489 (while (and (setq start | |
490 (jit-lock-stealth-chunk-start point)) | |
491 ;; In case sit-for runs any timers, | |
492 ;; give them the expected current buffer. | |
493 (with-current-buffer outer-buffer | |
494 (sit-for nice))) | |
495 | |
496 ;; fontify a block. | |
497 (jit-lock-fontify-now start (+ start jit-lock-chunk-size)) | |
498 ;; If stealth jit-locking is done backwards, this leads to | |
499 ;; excessive O(n^2) refontification. -stef | |
500 ;; (when (>= jit-lock-context-unfontify-pos start) | |
501 ;; (setq jit-lock-context-unfontify-pos end)) | |
502 | |
503 ;; Wait a little if load is too high. | |
504 (when (and jit-lock-stealth-load | |
505 (> (car (load-average)) jit-lock-stealth-load)) | |
506 ;; In case sit-for runs any timers, | |
507 ;; give them the expected current buffer. | |
508 (with-current-buffer outer-buffer | |
509 (sit-for (or jit-lock-stealth-time 30)))))))))))))) | |
510 | |
511 | 506 |
512 | 507 |
513 ;;; Deferred fontification. | 508 ;;; Deferred fontification. |
514 | 509 |
515 (defun jit-lock-deferred-fontify () | 510 (defun jit-lock-deferred-fontify () |