aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2006-08-01 19:01:24 +0000
committerStefan Monnier2006-08-01 19:01:24 +0000
commit663e16604c06d8c8961ef5716fc459be5ecfb4ff (patch)
tree5bbc7efa91dfe68b340e6ca4fdf22d8da6a0a227
parent4cffd2213707e403e379ec24934ec37edba3b6d3 (diff)
downloademacs-663e16604c06d8c8961ef5716fc459be5ecfb4ff.tar.gz
emacs-663e16604c06d8c8961ef5716fc459be5ecfb4ff.zip
(jit-lock-fontify-now): Cause a second redisplay if needed.
(jit-lock-start, jit-lock-end): New dynamic scoped vars. (jit-lock-after-change-extend-region-functions): New hook. (jit-lock-after-change): Use it instead of hard-coding font-lock code.
-rw-r--r--lisp/jit-lock.el86
1 files changed, 47 insertions, 39 deletions
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el
index 0e131b665ef..7077d7880eb 100644
--- a/lisp/jit-lock.el
+++ b/lisp/jit-lock.el
@@ -331,7 +331,7 @@ Defaults to the whole buffer. END can be out of bounds."
331 ;; from the end of a buffer to its start, can do repeated 331 ;; from the end of a buffer to its start, can do repeated
332 ;; `parse-partial-sexp' starting from `point-min', which can 332 ;; `parse-partial-sexp' starting from `point-min', which can
333 ;; take a long time in a large buffer. 333 ;; take a long time in a large buffer.
334 (let (next) 334 (let ((orig-start start) next)
335 (save-match-data 335 (save-match-data
336 ;; Fontify chunks beginning at START. The end of a 336 ;; Fontify chunks beginning at START. The end of a
337 ;; chunk is either `end', or the start of a region 337 ;; chunk is either `end', or the start of a region
@@ -374,6 +374,21 @@ Defaults to the whole buffer. END can be out of bounds."
374 (quit (put-text-property start next 'fontified nil) 374 (quit (put-text-property start next 'fontified nil)
375 (funcall 'signal (car err) (cdr err)))) 375 (funcall 'signal (car err) (cdr err))))
376 376
377 ;; The redisplay engine has already rendered the buffer up-to
378 ;; `orig-start' and won't notice if the above jit-lock-functions
379 ;; changed the appearance of any part of the buffer prior
380 ;; to that. So if `start' is before `orig-start', we need to
381 ;; cause a new redisplay cycle after this one so that any changes
382 ;; are properly reflected on screen.
383 ;; To make such repeated redisplay happen less often, we can
384 ;; eagerly extend the refontified region with
385 ;; jit-lock-after-change-extend-region-functions.
386 (when (< start orig-start)
387 (run-with-timer
388 0 nil `(lambda ()
389 (put-text-property ',start ',orig-start
390 'fontified t ',(current-buffer)))))
391
377 ;; Find the start of the next chunk, if any. 392 ;; Find the start of the next chunk, if any.
378 (setq start (text-property-any next end 'fontified nil)))))))) 393 (setq start (text-property-any next end 'fontified nil))))))))
379 394
@@ -548,6 +563,19 @@ This functions is called after Emacs has been idle for
548 '(fontified nil jit-lock-defer-multiline nil))) 563 '(fontified nil jit-lock-defer-multiline nil)))
549 (setq jit-lock-context-unfontify-pos (point-max))))))))) 564 (setq jit-lock-context-unfontify-pos (point-max)))))))))
550 565
566(defvar jit-lock-start) (defvar jit-lock-end) ; Dynamically scoped variables.
567(defvar jit-lock-after-change-extend-region-functions nil
568 "Hook that can extend the text to refontify after a change.
569This is run after every buffer change. The functions are called with
570the three arguments of `after-change-functions': START END OLD-LEN.
571The extended region to refontify is returned indirectly by modifying
572the variables `jit-lock-start' and `jit-lock-end'.
573
574Note that extending the region this way is not strictly necessary,
575except that the nature of the redisplay code tends to otherwise leave
576some of the rehighlighted text displayed with the old highlight until the
577next redisplay. See comment in `jit-lock-fontify-now'.")
578
551(defun jit-lock-after-change (start end old-len) 579(defun jit-lock-after-change (start end old-len)
552 "Mark the rest of the buffer as not fontified after a change. 580 "Mark the rest of the buffer as not fontified after a change.
553Installed on `after-change-functions'. 581Installed on `after-change-functions'.
@@ -557,44 +585,24 @@ This function ensures that lines following the change will be refontified
557in case the syntax of those lines has changed. Refontification 585in case the syntax of those lines has changed. Refontification
558will take place when text is fontified stealthily." 586will take place when text is fontified stealthily."
559 (when (and jit-lock-mode (not memory-full)) 587 (when (and jit-lock-mode (not memory-full))
560 (let ((region (font-lock-extend-region start end old-len))) 588 (let ((jit-lock-start start)
561 (save-excursion 589 (jit-lock-end end))
562 (with-buffer-prepared-for-jit-lock 590 (with-buffer-prepared-for-jit-lock
563 ;; It's important that the `fontified' property be set from the 591 (run-hook-with-args 'jit-lock-after-change-extend-region-functions
564 ;; beginning of the line, else font-lock will properly change the 592 start end old-len)
565 ;; text's face, but the display will have been done already and will 593 ;; Make sure we change at least one char (in case of deletions).
566 ;; be inconsistent with the buffer's content. 594 (setq jit-lock-end (min (max jit-lock-end (1+ start)) (point-max)))
567 ;; 595 ;; Request refontification.
568 ;; FIXME!!! (Alan Mackenzie, 2006-03-14): If start isn't at a BOL, 596 (put-text-property jit-lock-start jit-lock-end 'fontified nil))
569 ;; expanding the region to BOL might mis-fontify, should the BOL not 597 ;; Mark the change for deferred contextual refontification.
570 ;; be at a "safe" position. 598 (when jit-lock-context-unfontify-pos
571 (setq start (if region 599 (setq jit-lock-context-unfontify-pos
572 (car region) 600 ;; Here we use `start' because nothing guarantees that the
573 (goto-char start) 601 ;; text between start and end will be otherwise refontified:
574 (line-beginning-position))) 602 ;; usually it will be refontified by virtue of being
575 603 ;; displayed, but if it's outside of any displayed area in the
576 ;; If we're in text that matches a multi-line font-lock pattern, 604 ;; buffer, only jit-lock-context-* will re-fontify it.
577 ;; make sure the whole text will be redisplayed. 605 (min jit-lock-context-unfontify-pos jit-lock-start))))))
578 ;; I'm not sure this is ever necessary and/or sufficient. -stef
579 (when (get-text-property start 'font-lock-multiline)
580 (setq start (or (previous-single-property-change
581 start 'font-lock-multiline)
582 (point-min))))
583
584 (if region (setq end (cdr region)))
585 ;; Make sure we change at least one char (in case of deletions).
586 (setq end (min (max end (1+ start)) (point-max)))
587 ;; Request refontification.
588 (put-text-property start end 'fontified nil))
589 ;; Mark the change for deferred contextual refontification.
590 (when jit-lock-context-unfontify-pos
591 (setq jit-lock-context-unfontify-pos
592 ;; Here we use `start' because nothing guarantees that the
593 ;; text between start and end will be otherwise refontified:
594 ;; usually it will be refontified by virtue of being
595 ;; displayed, but if it's outside of any displayed area in the
596 ;; buffer, only jit-lock-context-* will re-fontify it.
597 (min jit-lock-context-unfontify-pos start)))))))
598 606
599(provide 'jit-lock) 607(provide 'jit-lock)
600 608