diff options
| -rw-r--r-- | lisp/jit-lock.el | 91 |
1 files changed, 27 insertions, 64 deletions
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el index 3b672aaf680..e4323a0bdde 100644 --- a/lisp/jit-lock.el +++ b/lisp/jit-lock.el | |||
| @@ -30,8 +30,6 @@ | |||
| 30 | ;;; Code: | 30 | ;;; Code: |
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | (require 'font-lock) | ||
| 34 | |||
| 35 | (eval-when-compile | 33 | (eval-when-compile |
| 36 | (defmacro with-buffer-unmodified (&rest body) | 34 | (defmacro with-buffer-unmodified (&rest body) |
| 37 | "Eval BODY, preserving the current buffer's modified state." | 35 | "Eval BODY, preserving the current buffer's modified state." |
| @@ -141,23 +139,19 @@ The value of this variable is used when JIT Lock mode is turned on." | |||
| 141 | (defvar jit-lock-functions nil | 139 | (defvar jit-lock-functions nil |
| 142 | "Functions to do the actual fontification. | 140 | "Functions to do the actual fontification. |
| 143 | They are called with two arguments: the START and END of the region to fontify.") | 141 | They are called with two arguments: the START and END of the region to fontify.") |
| 142 | (make-variable-buffer-local 'jit-lock-functions) | ||
| 144 | 143 | ||
| 145 | (defvar jit-lock-first-unfontify-pos nil | 144 | (defvar jit-lock-first-unfontify-pos nil |
| 146 | "Consider text after this position as unfontified. | 145 | "Consider text after this position as contextually unfontified. |
| 147 | If nil, contextual fontification is disabled.") | 146 | If nil, contextual fontification is disabled.") |
| 148 | (make-variable-buffer-local 'jit-lock-first-unfontify-pos) | 147 | (make-variable-buffer-local 'jit-lock-first-unfontify-pos) |
| 149 | 148 | ||
| 150 | 149 | ||
| 151 | (defvar jit-lock-stealth-timer nil | 150 | (defvar jit-lock-stealth-timer nil |
| 152 | "Timer for stealth fontification in Just-in-time Lock mode.") | 151 | "Timer for stealth fontification in Just-in-time Lock mode.") |
| 153 | |||
| 154 | (defvar jit-lock-saved-fontify-buffer-function nil | ||
| 155 | "Value of `font-lock-fontify-buffer-function' before jit-lock's activation.") | ||
| 156 | |||
| 157 | 152 | ||
| 158 | ;;; JIT lock mode | 153 | ;;; JIT lock mode |
| 159 | 154 | ||
| 160 | ;;;###autoload | ||
| 161 | (defun jit-lock-mode (arg) | 155 | (defun jit-lock-mode (arg) |
| 162 | "Toggle Just-in-time Lock mode. | 156 | "Toggle Just-in-time Lock mode. |
| 163 | Turn Just-in-time Lock mode on if and only if ARG is non-nil. | 157 | Turn Just-in-time Lock mode on if and only if ARG is non-nil. |
| @@ -193,21 +187,8 @@ the variable `jit-lock-stealth-nice'." | |||
| 193 | (cond (;; Turn Just-in-time Lock mode on. | 187 | (cond (;; Turn Just-in-time Lock mode on. |
| 194 | jit-lock-mode | 188 | jit-lock-mode |
| 195 | 189 | ||
| 196 | ;; Mark the buffer for refontification | 190 | ;; Mark the buffer for refontification |
| 197 | ;; (in case spurious `fontified' text-props were left around). | 191 | (jit-lock-refontify) |
| 198 | (jit-lock-fontify-buffer) | ||
| 199 | |||
| 200 | ;; Setting `font-lock-fontified' makes font-lock believe the | ||
| 201 | ;; buffer is already fontified, so that it won't highlight | ||
| 202 | ;; the whole buffer or bail out on a large buffer. | ||
| 203 | (set (make-local-variable 'font-lock-fontified) t) | ||
| 204 | |||
| 205 | ;; Setup JIT font-lock-fontify-buffer. | ||
| 206 | (unless jit-lock-saved-fontify-buffer-function | ||
| 207 | (set (make-local-variable 'jit-lock-saved-fontify-buffer-function) | ||
| 208 | font-lock-fontify-buffer-function) | ||
| 209 | (set (make-local-variable 'font-lock-fontify-buffer-function) | ||
| 210 | 'jit-lock-fontify-buffer)) | ||
| 211 | 192 | ||
| 212 | ;; Install an idle timer for stealth fontification. | 193 | ;; Install an idle timer for stealth fontification. |
| 213 | (when (and jit-lock-stealth-time (null jit-lock-stealth-timer)) | 194 | (when (and jit-lock-stealth-time (null jit-lock-stealth-timer)) |
| @@ -217,19 +198,12 @@ the variable `jit-lock-stealth-nice'." | |||
| 217 | 'jit-lock-stealth-fontify))) | 198 | 'jit-lock-stealth-fontify))) |
| 218 | 199 | ||
| 219 | ;; Initialize deferred contextual fontification if requested. | 200 | ;; Initialize deferred contextual fontification if requested. |
| 220 | (when (or (eq jit-lock-defer-contextually t) | 201 | (when (eq jit-lock-defer-contextually t) |
| 221 | (and jit-lock-defer-contextually | ||
| 222 | (boundp 'font-lock-keywords-only) | ||
| 223 | (null font-lock-keywords-only))) | ||
| 224 | (setq jit-lock-first-unfontify-pos | 202 | (setq jit-lock-first-unfontify-pos |
| 225 | (or jit-lock-first-unfontify-pos (point-max)))) | 203 | (or jit-lock-first-unfontify-pos (point-max)))) |
| 226 | 204 | ||
| 227 | ;; Setup our after-change-function | 205 | ;; Setup our hooks. |
| 228 | ;; and remove font-lock's (if any). | ||
| 229 | (remove-hook 'after-change-functions 'font-lock-after-change-function t) | ||
| 230 | (add-hook 'after-change-functions 'jit-lock-after-change nil t) | 206 | (add-hook 'after-change-functions 'jit-lock-after-change nil t) |
| 231 | |||
| 232 | ;; Install the fontification hook. | ||
| 233 | (add-hook 'fontification-functions 'jit-lock-function)) | 207 | (add-hook 'fontification-functions 'jit-lock-function)) |
| 234 | 208 | ||
| 235 | ;; Turn Just-in-time Lock mode off. | 209 | ;; Turn Just-in-time Lock mode off. |
| @@ -239,17 +213,8 @@ the variable `jit-lock-stealth-nice'." | |||
| 239 | (cancel-timer jit-lock-stealth-timer) | 213 | (cancel-timer jit-lock-stealth-timer) |
| 240 | (setq jit-lock-stealth-timer nil)) | 214 | (setq jit-lock-stealth-timer nil)) |
| 241 | 215 | ||
| 242 | ;; Restore non-JIT font-lock-fontify-buffer. | 216 | ;; Remove hooks. |
| 243 | (when jit-lock-saved-fontify-buffer-function | ||
| 244 | (set (make-local-variable 'font-lock-fontify-buffer-function) | ||
| 245 | jit-lock-saved-fontify-buffer-function) | ||
| 246 | (setq jit-lock-saved-fontify-buffer-function nil)) | ||
| 247 | |||
| 248 | ;; Remove hooks (and restore font-lock's if necessary). | ||
| 249 | (remove-hook 'after-change-functions 'jit-lock-after-change t) | 217 | (remove-hook 'after-change-functions 'jit-lock-after-change t) |
| 250 | (when font-lock-mode | ||
| 251 | (add-hook 'after-change-functions | ||
| 252 | 'font-lock-after-change-function nil t)) | ||
| 253 | (remove-hook 'fontification-functions 'jit-lock-function)))) | 218 | (remove-hook 'fontification-functions 'jit-lock-function)))) |
| 254 | 219 | ||
| 255 | ;;;###autoload | 220 | ;;;###autoload |
| @@ -267,21 +232,20 @@ If non-nil, CONTEXTUAL means that a contextual fontification would be useful." | |||
| 267 | "Unregister FUN as a fontification function. | 232 | "Unregister FUN as a fontification function. |
| 268 | Only applies to the current buffer." | 233 | Only applies to the current buffer." |
| 269 | (remove-hook 'jit-lock-functions fun t) | 234 | (remove-hook 'jit-lock-functions fun t) |
| 270 | (when (or (null jit-lock-functions) | 235 | (unless jit-lock-functions (jit-lock-mode nil))) |
| 271 | (and (equal jit-lock-functions '(t)) | ||
| 272 | (null (default-value 'jit-lock-functions)))) | ||
| 273 | (jit-lock-mode nil))) | ||
| 274 | 236 | ||
| 275 | ;; This function is used to prevent font-lock-fontify-buffer from | 237 | ;; This function is used to prevent font-lock-fontify-buffer from |
| 276 | ;; fontifying eagerly the whole buffer. This is important for | 238 | ;; fontifying eagerly the whole buffer. This is important for |
| 277 | ;; things like CWarn mode which adds/removes a few keywords and | 239 | ;; things like CWarn mode which adds/removes a few keywords and |
| 278 | ;; does a refontify (which takes ages on large files). | 240 | ;; does a refontify (which takes ages on large files). |
| 279 | (defun jit-lock-fontify-buffer () | 241 | (defalias 'jit-lock-fontify-buffer 'jit-lock-refontify) |
| 242 | (defun jit-lock-refontify (&optional beg end) | ||
| 243 | "Force refontification of the region BEG..END (default whole buffer)." | ||
| 280 | (with-buffer-prepared-for-jit-lock | 244 | (with-buffer-prepared-for-jit-lock |
| 281 | (save-restriction | 245 | (save-restriction |
| 282 | (widen) | 246 | (widen) |
| 283 | (add-text-properties (point-min) (point-max) '(fontified nil))))) | 247 | (add-text-properties (or beg (point-min)) (or end (point-max)) |
| 284 | 248 | '(fontified nil))))) | |
| 285 | 249 | ||
| 286 | ;;; On demand fontification. | 250 | ;;; On demand fontification. |
| 287 | 251 | ||
| @@ -290,17 +254,19 @@ Only applies to the current buffer." | |||
| 290 | This function is added to `fontification-functions' when `jit-lock-mode' | 254 | This function is added to `fontification-functions' when `jit-lock-mode' |
| 291 | is active." | 255 | is active." |
| 292 | (when jit-lock-mode | 256 | (when jit-lock-mode |
| 293 | (jit-lock-function-1 start))) | 257 | (jit-lock-fontify-now start (+ start jit-lock-chunk-size)))) |
| 294 | 258 | ||
| 295 | 259 | ||
| 296 | (defun jit-lock-function-1 (start) | 260 | (defun jit-lock-fontify-now (&optional start end) |
| 297 | "Fontify current buffer starting at position START." | 261 | "Fontify current buffer from START to END. |
| 262 | Defaults to the whole buffer. END can be out of bounds." | ||
| 298 | (with-buffer-prepared-for-jit-lock | 263 | (with-buffer-prepared-for-jit-lock |
| 299 | (save-excursion | 264 | (save-excursion |
| 300 | (save-restriction | 265 | (save-restriction |
| 301 | (widen) | 266 | (widen) |
| 302 | (let ((end (min (point-max) (+ start jit-lock-chunk-size))) | 267 | (unless start (setq start (point-min))) |
| 303 | (font-lock-beginning-of-syntax-function nil) | 268 | (setq end (if end (min end (point-max)) (point-max))) |
| 269 | (let ((font-lock-beginning-of-syntax-function nil) | ||
| 304 | next) | 270 | next) |
| 305 | (save-match-data | 271 | (save-match-data |
| 306 | ;; Fontify chunks beginning at START. The end of a | 272 | ;; Fontify chunks beginning at START. The end of a |
| @@ -317,18 +283,14 @@ is active." | |||
| 317 | ;; Until someone has a better idea, let's start | 283 | ;; Until someone has a better idea, let's start |
| 318 | ;; at the start of the line containing START and | 284 | ;; at the start of the line containing START and |
| 319 | ;; stop at the start of the line following NEXT. | 285 | ;; stop at the start of the line following NEXT. |
| 320 | (goto-char next) | 286 | (goto-char next) (setq next (line-beginning-position 2)) |
| 321 | (setq next (line-beginning-position 2)) | 287 | (goto-char start) (setq start (line-beginning-position)) |
| 322 | (goto-char start) | 288 | |
| 323 | (setq start (line-beginning-position)) | ||
| 324 | |||
| 325 | ;; Fontify the chunk, and mark it as fontified. | 289 | ;; Fontify the chunk, and mark it as fontified. |
| 326 | ;; We mark it first, to make sure that we don't indefinitely | 290 | ;; We mark it first, to make sure that we don't indefinitely |
| 327 | ;; re-execute this fontification if an error occurs. | 291 | ;; re-execute this fontification if an error occurs. |
| 328 | (add-text-properties start next '(fontified t)) | 292 | (add-text-properties start next '(fontified t)) |
| 329 | (if jit-lock-functions | 293 | (run-hook-with-args 'jit-lock-functions start next) |
| 330 | (run-hook-with-args 'jit-lock-functions start next) | ||
| 331 | (font-lock-fontify-region start next)) | ||
| 332 | 294 | ||
| 333 | ;; Find the start of the next chunk, if any. | 295 | ;; Find the start of the next chunk, if any. |
| 334 | (setq start (text-property-any next end 'fontified nil))))))))) | 296 | (setq start (text-property-any next end 'fontified nil))))))))) |
| @@ -441,7 +403,8 @@ This functions is called after Emacs has been idle for | |||
| 441 | 403 | ||
| 442 | ;; Unless there's input pending now, fontify. | 404 | ;; Unless there's input pending now, fontify. |
| 443 | (unless (input-pending-p) | 405 | (unless (input-pending-p) |
| 444 | (jit-lock-function-1 start)))))))))))) | 406 | (jit-lock-fontify-now |
| 407 | start (+ start jit-lock-chunk-size))))))))))))) | ||
| 445 | 408 | ||
| 446 | 409 | ||
| 447 | 410 | ||