;;; jit-lock.el --- just-in-time fontification
;; Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004,
-;; 2005 Free Software Foundation, Inc.
+;; 2005, 2006 Free Software Foundation, Inc.
;; Author: Gerd Moellmann <gerd@gnu.org>
;; Keywords: faces files
:group 'font-lock)
(defcustom jit-lock-chunk-size 500
- "*Jit-lock chunks of this many characters, or smaller."
+ "*Jit-lock fontifies chunks of at most this many characters at a time.
+
+This variable controls both display-time and stealth fontification."
:type 'integer
:group 'jit-lock)
(remove-hook 'after-change-functions 'jit-lock-after-change t)
(remove-hook 'fontification-functions 'jit-lock-function))))
-;;;###autoload
(defun jit-lock-register (fun &optional contextual)
"Register FUN as a fontification function to be called in this buffer.
FUN will be called with two arguments START and END indicating the region
"Fontify current buffer starting at position START.
This function is added to `fontification-functions' when `jit-lock-mode'
is active."
- (when (and jit-lock-mode (not (memory-full-p)))
- (if (null jit-lock-defer-time)
+ (when (and jit-lock-mode (not memory-full))
+ (if (null jit-lock-defer-timer)
;; No deferral.
(jit-lock-fontify-now start (+ start jit-lock-chunk-size))
;; Record the buffer for later fontification.
`jit-lock-stealth-time' seconds."
;; I used to check `inhibit-read-only' here, but I can't remember why. -stef
(unless (or executing-kbd-macro
+ memory-full
(window-minibuffer-p (selected-window)))
(let ((buffers (buffer-list))
(outer-buffer (current-buffer))
(defun jit-lock-deferred-fontify ()
"Fontify what was deferred."
- (when jit-lock-defer-buffers
+ (when (and jit-lock-defer-buffers (not memory-full))
;; Mark the deferred regions back to `fontified = nil'
(dolist (buffer jit-lock-defer-buffers)
(when (buffer-live-p buffer)
(setq pos (next-single-property-change pos 'fontified)))))))))
(setq jit-lock-defer-buffers nil)
;; Force fontification of the visible parts.
- (let ((jit-lock-defer-time nil))
+ (let ((jit-lock-defer-timer nil))
;; (message "Jit-Defer Now")
(sit-for 0)
;; (message "Jit-Defer Done")
(defun jit-lock-context-fontify ()
"Refresh fontification to take new context into account."
- (dolist (buffer (buffer-list))
- (with-current-buffer buffer
- (when jit-lock-context-unfontify-pos
- ;; (message "Jit-Context %s" (buffer-name))
- (save-restriction
- (widen)
- (when (and (>= jit-lock-context-unfontify-pos (point-min))
- (< jit-lock-context-unfontify-pos (point-max)))
- ;; If we're in text that matches a complex multi-line
- ;; font-lock pattern, make sure the whole text will be
- ;; redisplayed eventually.
- ;; Despite its name, we treat jit-lock-defer-multiline here
- ;; rather than in jit-lock-defer since it has to do with multiple
- ;; lines, i.e. with context.
- (when (get-text-property jit-lock-context-unfontify-pos
- 'jit-lock-defer-multiline)
- (setq jit-lock-context-unfontify-pos
- (or (previous-single-property-change
- jit-lock-context-unfontify-pos
- 'jit-lock-defer-multiline)
- (point-min))))
- (with-buffer-prepared-for-jit-lock
- ;; Force contextual refontification.
- (remove-text-properties
- jit-lock-context-unfontify-pos (point-max)
- '(fontified nil jit-lock-defer-multiline nil)))
- (setq jit-lock-context-unfontify-pos (point-max))))))))
+ (unless memory-full
+ (dolist (buffer (buffer-list))
+ (with-current-buffer buffer
+ (when jit-lock-context-unfontify-pos
+ ;; (message "Jit-Context %s" (buffer-name))
+ (save-restriction
+ (widen)
+ (when (and (>= jit-lock-context-unfontify-pos (point-min))
+ (< jit-lock-context-unfontify-pos (point-max)))
+ ;; If we're in text that matches a complex multi-line
+ ;; font-lock pattern, make sure the whole text will be
+ ;; redisplayed eventually.
+ ;; Despite its name, we treat jit-lock-defer-multiline here
+ ;; rather than in jit-lock-defer since it has to do with multiple
+ ;; lines, i.e. with context.
+ (when (get-text-property jit-lock-context-unfontify-pos
+ 'jit-lock-defer-multiline)
+ (setq jit-lock-context-unfontify-pos
+ (or (previous-single-property-change
+ jit-lock-context-unfontify-pos
+ 'jit-lock-defer-multiline)
+ (point-min))))
+ (with-buffer-prepared-for-jit-lock
+ ;; Force contextual refontification.
+ (remove-text-properties
+ jit-lock-context-unfontify-pos (point-max)
+ '(fontified nil jit-lock-defer-multiline nil)))
+ (setq jit-lock-context-unfontify-pos (point-max)))))))))
(defun jit-lock-after-change (start end old-len)
"Mark the rest of the buffer as not fontified after a change.
This function ensures that lines following the change will be refontified
in case the syntax of those lines has changed. Refontification
will take place when text is fontified stealthily."
- (when (and jit-lock-mode (not (memory-full-p)))
- (save-excursion
- (with-buffer-prepared-for-jit-lock
- ;; It's important that the `fontified' property be set from the
- ;; beginning of the line, else font-lock will properly change the
- ;; text's face, but the display will have been done already and will
- ;; be inconsistent with the buffer's content.
- (goto-char start)
- (setq start (line-beginning-position))
-
- ;; If we're in text that matches a multi-line font-lock pattern,
- ;; make sure the whole text will be redisplayed.
- ;; I'm not sure this is ever necessary and/or sufficient. -stef
- (when (get-text-property start 'font-lock-multiline)
- (setq start (or (previous-single-property-change
- start 'font-lock-multiline)
- (point-min))))
-
- ;; Make sure we change at least one char (in case of deletions).
- (setq end (min (max end (1+ start)) (point-max)))
- ;; Request refontification.
- (put-text-property start end 'fontified nil))
- ;; Mark the change for deferred contextual refontification.
- (when jit-lock-context-unfontify-pos
- (setq jit-lock-context-unfontify-pos
- ;; Here we use `start' because nothing guarantees that the
- ;; text between start and end will be otherwise refontified:
- ;; usually it will be refontified by virtue of being
- ;; displayed, but if it's outside of any displayed area in the
- ;; buffer, only jit-lock-context-* will re-fontify it.
- (min jit-lock-context-unfontify-pos start))))))
+ (when (and jit-lock-mode (not memory-full))
+ (let ((region (font-lock-extend-region start end old-len)))
+ (save-excursion
+ (with-buffer-prepared-for-jit-lock
+ ;; It's important that the `fontified' property be set from the
+ ;; beginning of the line, else font-lock will properly change the
+ ;; text's face, but the display will have been done already and will
+ ;; be inconsistent with the buffer's content.
+ ;;
+ ;; FIXME!!! (Alan Mackenzie, 2006-03-14): If start isn't at a BOL,
+ ;; expanding the region to BOL might mis-fontify, should the BOL not
+ ;; be at a "safe" position.
+ (setq start (if region
+ (car region)
+ (goto-char start)
+ (line-beginning-position)))
+
+ ;; If we're in text that matches a multi-line font-lock pattern,
+ ;; make sure the whole text will be redisplayed.
+ ;; I'm not sure this is ever necessary and/or sufficient. -stef
+ (when (get-text-property start 'font-lock-multiline)
+ (setq start (or (previous-single-property-change
+ start 'font-lock-multiline)
+ (point-min))))
+
+ (if region (setq end (cdr region)))
+ ;; Make sure we change at least one char (in case of deletions).
+ (setq end (min (max end (1+ start)) (point-max)))
+ ;; Request refontification.
+ (put-text-property start end 'fontified nil))
+ ;; Mark the change for deferred contextual refontification.
+ (when jit-lock-context-unfontify-pos
+ (setq jit-lock-context-unfontify-pos
+ ;; Here we use `start' because nothing guarantees that the
+ ;; text between start and end will be otherwise refontified:
+ ;; usually it will be refontified by virtue of being
+ ;; displayed, but if it's outside of any displayed area in the
+ ;; buffer, only jit-lock-context-* will re-fontify it.
+ (min jit-lock-context-unfontify-pos start)))))))
(provide 'jit-lock)