Mercurial > emacs
comparison lisp/fast-lock.el @ 16579:aadb4abdeaaa
(a) make fast-lock-get-face-properties cope with face property lists, (b) add fast-lock-verbose to control messages.
author | Simon Marshall <simon@gnu.org> |
---|---|
date | Sat, 16 Nov 1996 13:31:02 +0000 |
parents | 4cd3efec2909 |
children | de68258fef5f |
comparison
equal
deleted
inserted
replaced
16578:c921b60ee783 | 16579:aadb4abdeaaa |
---|---|
2 | 2 |
3 ;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. |
4 | 4 |
5 ;; Author: Simon Marshall <simon@gnu.ai.mit.edu> | 5 ;; Author: Simon Marshall <simon@gnu.ai.mit.edu> |
6 ;; Keywords: faces files | 6 ;; Keywords: faces files |
7 ;; Version: 3.10 | 7 ;; Version: 3.11 |
8 | 8 |
9 ;;; This file is part of GNU Emacs. | 9 ;;; This file is part of GNU Emacs. |
10 | 10 |
11 ;; GNU Emacs is free software; you can redistribute it and/or modify | 11 ;; GNU Emacs is free software; you can redistribute it and/or modify |
12 ;; it under the terms of the GNU General Public License as published by | 12 ;; it under the terms of the GNU General Public License as published by |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
24 ;; Boston, MA 02111-1307, USA. | 24 ;; Boston, MA 02111-1307, USA. |
25 | 25 |
26 ;;; Commentary: | 26 ;;; Commentary: |
27 | 27 |
28 ;; Purpose: | 28 ;; Lazy Lock mode is a Font Lock support mode. |
29 ;; | 29 ;; It makes visiting a file in Font Lock mode faster by restoring its face text |
30 ;; To make visiting a file in `font-lock-mode' faster by restoring its face | 30 ;; properties from automatically saved associated Font Lock cache files. |
31 ;; text properties from automatically saved associated Font Lock cache files. | |
32 ;; | 31 ;; |
33 ;; See caveats and feedback below. | 32 ;; See caveats and feedback below. |
34 ;; See also the lazy-lock package. (But don't use the two at the same time!) | 33 ;; See also the lazy-lock package. (But don't use the two at the same time!) |
35 | 34 |
36 ;; Installation: | 35 ;; Installation: |
51 ;; A cache will be saved when visiting a compressed file using crypt++, but not | 50 ;; A cache will be saved when visiting a compressed file using crypt++, but not |
52 ;; be read. This is a "feature"/"consequence"/"bug" of crypt++. | 51 ;; be read. This is a "feature"/"consequence"/"bug" of crypt++. |
53 ;; | 52 ;; |
54 ;; Version control packages are likely to stamp all over file modification | 53 ;; Version control packages are likely to stamp all over file modification |
55 ;; times. Therefore the act of checking out may invalidate a cache. | 54 ;; times. Therefore the act of checking out may invalidate a cache. |
56 | |
57 ;; Feedback: | |
58 ;; | |
59 ;; Feedback is welcome. | |
60 ;; To submit a bug report (or make comments) please use the mechanism provided: | |
61 ;; | |
62 ;; M-x fast-lock-submit-bug-report RET | |
63 | 55 |
64 ;; History: | 56 ;; History: |
65 ;; | 57 ;; |
66 ;; 0.02--1.00: | 58 ;; 0.02--1.00: |
67 ;; - Changed name from turbo-prop to fast-lock. Automagic for font-lock only | 59 ;; - Changed name from turbo-prop to fast-lock. Automagic for font-lock only |
161 ;; - XEmacs: Made `add-minor-mode' succeed `autoload' cookie | 153 ;; - XEmacs: Made `add-minor-mode' succeed `autoload' cookie |
162 ;; - XEmacs: Made `fast-lock-save-faces' default to `font-lock-face-list' | 154 ;; - XEmacs: Made `fast-lock-save-faces' default to `font-lock-face-list' |
163 ;; - Made `fast-lock-save-cache' use `font-lock-value-in-major-mode' | 155 ;; - Made `fast-lock-save-cache' use `font-lock-value-in-major-mode' |
164 ;; - Wrap with `save-buffer-state' (Ray Van Tassle report) | 156 ;; - Wrap with `save-buffer-state' (Ray Van Tassle report) |
165 ;; - Made `fast-lock-mode' wrap `font-lock-support-mode' | 157 ;; - Made `fast-lock-mode' wrap `font-lock-support-mode' |
166 | 158 ;; 3.10--3.11: |
159 ;; - Made `fast-lock-get-face-properties' cope with face lists | |
160 ;; - Added `fast-lock-verbose' | |
161 ;; - XEmacs: Add `font-lock-value-in-major-mode' if necessary | |
162 ;; - Removed `fast-lock-submit-bug-report' and bade farewell | |
163 | |
164 ;;; Code: | |
165 | |
167 (require 'font-lock) | 166 (require 'font-lock) |
168 | 167 |
169 ;; Make sure fast-lock.el is supported. | 168 ;; Make sure fast-lock.el is supported. |
170 (if (and (eq system-type 'ms-dos) (not (msdos-long-file-names))) | 169 (if (and (eq system-type 'ms-dos) (not (msdos-long-file-names))) |
171 (error "`fast-lock' was written for long file name systems")) | 170 (error "`fast-lock' was written for long file name systems")) |
175 ;; We don't do this at the top-level as we only use non-autoloaded macros. | 174 ;; We don't do this at the top-level as we only use non-autoloaded macros. |
176 (require 'cl) | 175 (require 'cl) |
177 ;; | 176 ;; |
178 ;; I prefer lazy code---and lazy mode. | 177 ;; I prefer lazy code---and lazy mode. |
179 (setq byte-compile-dynamic t byte-compile-dynamic-docstrings t) | 178 (setq byte-compile-dynamic t byte-compile-dynamic-docstrings t) |
179 ;; But, we make sure that the code is as zippy as can be. | |
180 (setq byte-optimize t) | |
180 ;; | 181 ;; |
181 ;; We use this to preserve or protect things when modifying text properties. | 182 ;; We use this to preserve or protect things when modifying text properties. |
182 (defmacro save-buffer-state (varlist &rest body) | 183 (defmacro save-buffer-state (varlist &rest body) |
183 "Bind variables according to VARLIST and eval BODY restoring buffer state." | 184 "Bind variables according to VARLIST and eval BODY restoring buffer state." |
184 (` (let* ((,@ (append varlist | 185 (` (let* ((,@ (append varlist |
187 before-change-functions after-change-functions | 188 before-change-functions after-change-functions |
188 deactivate-mark buffer-file-name buffer-file-truename)))) | 189 deactivate-mark buffer-file-name buffer-file-truename)))) |
189 (,@ body) | 190 (,@ body) |
190 (when (and (not modified) (buffer-modified-p)) | 191 (when (and (not modified) (buffer-modified-p)) |
191 (set-buffer-modified-p nil))))) | 192 (set-buffer-modified-p nil))))) |
192 (put 'save-buffer-state 'lisp-indent-function 1)) | 193 (put 'save-buffer-state 'lisp-indent-function 1) |
193 | 194 ;; |
194 (defun fast-lock-submit-bug-report () | 195 ;; We use this to verify that a face should be saved. |
195 "Submit via mail a bug report on fast-lock.el." | 196 (defmacro fast-lock-save-facep (face) |
196 (interactive) | 197 "Return non-nil if FACE is one of `fast-lock-save-faces'." |
197 (let ((reporter-prompt-for-summary-p t)) | 198 (` (or (null fast-lock-save-faces) |
198 (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "fast-lock 3.10" | 199 (if (symbolp (, face)) |
199 '(fast-lock-cache-directories fast-lock-minimum-size | 200 (memq (, face) fast-lock-save-faces) |
200 fast-lock-save-others fast-lock-save-events fast-lock-save-faces) | 201 (let ((faces (, face))) |
201 nil nil | 202 (while (unless (memq (car faces) fast-lock-save-faces) |
202 (concat "Hi Si., | 203 (setq faces (cdr faces)))) |
203 | 204 faces)))))) |
204 I want to report a bug. I've read the `Bugs' section of `Info' on Emacs, so I | 205 |
205 know how to make a clear and unambiguous report. To reproduce the bug: | 206 ;(defun fast-lock-submit-bug-report () |
206 | 207 ; "Submit via mail a bug report on fast-lock.el." |
207 Start a fresh Emacs via `" invocation-name " -no-init-file -no-site-file'. | 208 ; (interactive) |
208 In the `*scratch*' buffer, evaluate:")))) | 209 ; (let ((reporter-prompt-for-summary-p t)) |
210 ; (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "fast-lock 3.11" | |
211 ; '(fast-lock-cache-directories fast-lock-minimum-size | |
212 ; fast-lock-save-others fast-lock-save-events fast-lock-save-faces | |
213 ; fast-lock-verbose) | |
214 ; nil nil | |
215 ; (concat "Hi Si., | |
216 ; | |
217 ;I want to report a bug. I've read the `Bugs' section of `Info' on Emacs, so I | |
218 ;know how to make a clear and unambiguous report. To reproduce the bug: | |
219 ; | |
220 ;Start a fresh editor via `" invocation-name " -no-init-file -no-site-file'. | |
221 ;In the `*scratch*' buffer, evaluate:")))) | |
209 | 222 |
210 (defvar fast-lock-mode nil) | 223 (defvar fast-lock-mode nil) |
211 (defvar fast-lock-cache-timestamp nil) ; for saving/reading | 224 (defvar fast-lock-cache-timestamp nil) ; for saving/reading |
212 (defvar fast-lock-cache-filename nil) ; for deleting | 225 (defvar fast-lock-cache-filename nil) ; for deleting |
213 | 226 |
258 (when (save-match-data (string-match "XEmacs" (emacs-version))) | 271 (when (save-match-data (string-match "XEmacs" (emacs-version))) |
259 ;; XEmacs uses extents for everything, so we have to pick the right ones. | 272 ;; XEmacs uses extents for everything, so we have to pick the right ones. |
260 font-lock-face-list) | 273 font-lock-face-list) |
261 "Faces that will be saved in a Font Lock cache file. | 274 "Faces that will be saved in a Font Lock cache file. |
262 If nil, means information for all faces will be saved.") | 275 If nil, means information for all faces will be saved.") |
276 | |
277 (defvar fast-lock-verbose font-lock-verbose | |
278 "*If non-nil, means show status messages for cache processing. | |
279 If a number, only buffers greater than this size have processing messages.") | |
263 | 280 |
264 ;; User Functions: | 281 ;; User Functions: |
265 | 282 |
266 ;;;###autoload | 283 ;;;###autoload |
267 (defun fast-lock-mode (&optional arg) | 284 (defun fast-lock-mode (&optional arg) |
274 If Fast Lock mode is enabled, and the current buffer does not contain any text | 291 If Fast Lock mode is enabled, and the current buffer does not contain any text |
275 properties, any associated Font Lock cache is used if its timestamp matches the | 292 properties, any associated Font Lock cache is used if its timestamp matches the |
276 buffer's file, and its `font-lock-keywords' match those that you are using. | 293 buffer's file, and its `font-lock-keywords' match those that you are using. |
277 | 294 |
278 Font Lock caches may be saved: | 295 Font Lock caches may be saved: |
279 - When you save the file's buffer. | 296 - When you save the file's buffer. |
280 - When you kill an unmodified file's buffer. | 297 - When you kill an unmodified file's buffer. |
281 - When you exit Emacs, for all unmodified or saved buffers. | 298 - When you exit Emacs, for all unmodified or saved buffers. |
282 Depending on the value of `fast-lock-save-events'. | 299 Depending on the value of `fast-lock-save-events'. |
283 See also the commands `fast-lock-read-cache' and `fast-lock-save-cache'. | 300 See also the commands `fast-lock-read-cache' and `fast-lock-save-cache'. |
284 | 301 |
285 Use \\[font-lock-fontify-buffer] to fontify the buffer if the cache is bad. | 302 Use \\[font-lock-fontify-buffer] to fontify the buffer if the cache is bad. |
286 | 303 |
287 Various methods of control are provided for the Font Lock cache. In general, | 304 Various methods of control are provided for the Font Lock cache. In general, |
288 see variable `fast-lock-cache-directories' and function `fast-lock-cache-name'. | 305 see variable `fast-lock-cache-directories' and function `fast-lock-cache-name'. |
289 For saving, see variables `fast-lock-minimum-size', `fast-lock-save-events', | 306 For saving, see variables `fast-lock-minimum-size', `fast-lock-save-events', |
290 `fast-lock-save-others' and `fast-lock-save-faces'. | 307 `fast-lock-save-others' and `fast-lock-save-faces'." |
291 | |
292 Use \\[fast-lock-submit-bug-report] to send bug reports or feedback." | |
293 (interactive "P") | 308 (interactive "P") |
294 ;; Only turn on if we are visiting a file. We could use `buffer-file-name', | 309 ;; Only turn on if we are visiting a file. We could use `buffer-file-name', |
295 ;; but many packages temporarily wrap that to nil when doing their own thing. | 310 ;; but many packages temporarily wrap that to nil when doing their own thing. |
296 (set (make-local-variable 'fast-lock-mode) | 311 (set (make-local-variable 'fast-lock-mode) |
297 (and buffer-file-truename | 312 (and buffer-file-truename |
309 | 324 |
310 (defun fast-lock-read-cache () | 325 (defun fast-lock-read-cache () |
311 "Read the Font Lock cache for the current buffer. | 326 "Read the Font Lock cache for the current buffer. |
312 | 327 |
313 The following criteria must be met for a Font Lock cache file to be read: | 328 The following criteria must be met for a Font Lock cache file to be read: |
314 - Fast Lock mode must be turned on in the buffer. | 329 - Fast Lock mode must be turned on in the buffer. |
315 - The buffer must not be modified. | 330 - The buffer must not be modified. |
316 - The buffer's `font-lock-keywords' must match the cache's. | 331 - The buffer's `font-lock-keywords' must match the cache's. |
317 - The buffer file's timestamp must match the cache's. | 332 - The buffer file's timestamp must match the cache's. |
318 - Criteria imposed by `fast-lock-cache-directories'. | 333 - Criteria imposed by `fast-lock-cache-directories'. |
319 | 334 |
320 See `fast-lock-mode'." | 335 See `fast-lock-mode'." |
321 (interactive) | 336 (interactive) |
322 (let ((directories fast-lock-cache-directories) | 337 (let ((directories fast-lock-cache-directories) |
323 (modified (buffer-modified-p)) (inhibit-read-only t) | 338 (modified (buffer-modified-p)) (inhibit-read-only t) |
342 | 357 |
343 (defun fast-lock-save-cache (&optional buffer) | 358 (defun fast-lock-save-cache (&optional buffer) |
344 "Save the Font Lock cache of BUFFER or the current buffer. | 359 "Save the Font Lock cache of BUFFER or the current buffer. |
345 | 360 |
346 The following criteria must be met for a Font Lock cache file to be saved: | 361 The following criteria must be met for a Font Lock cache file to be saved: |
347 - Fast Lock mode must be turned on in the buffer. | 362 - Fast Lock mode must be turned on in the buffer. |
348 - The event must be one of `fast-lock-save-events'. | 363 - The event must be one of `fast-lock-save-events'. |
349 - The buffer must be at least `fast-lock-minimum-size' bytes long. | 364 - The buffer must be at least `fast-lock-minimum-size' bytes long. |
350 - The buffer file must be owned by you, or `fast-lock-save-others' must be t. | 365 - The buffer file must be owned by you, or `fast-lock-save-others' must be t. |
351 - The buffer must contain at least one `face' text property. | 366 - The buffer must contain at least one `face' text property. |
352 - The buffer must not be modified. | 367 - The buffer must not be modified. |
353 - The buffer file's timestamp must be the same as the file's on disk. | 368 - The buffer file's timestamp must be the same as the file's on disk. |
354 - The on disk file's timestamp must be different than the buffer's cache. | 369 - The on disk file's timestamp must be different than the buffer's cache. |
355 - Criteria imposed by `fast-lock-cache-directories'. | 370 - Criteria imposed by `fast-lock-cache-directories'. |
356 | 371 |
357 See `fast-lock-mode'." | 372 See `fast-lock-mode'." |
358 (interactive) | 373 (interactive) |
359 (save-excursion | 374 (save-excursion |
360 (when buffer | 375 (when buffer |
496 (defun fast-lock-save-cache-1 (file timestamp) | 511 (defun fast-lock-save-cache-1 (file timestamp) |
497 ;; Save the FILE with the TIMESTAMP as: | 512 ;; Save the FILE with the TIMESTAMP as: |
498 ;; (fast-lock-cache-data Version=2 TIMESTAMP font-lock-keywords PROPERTIES). | 513 ;; (fast-lock-cache-data Version=2 TIMESTAMP font-lock-keywords PROPERTIES). |
499 ;; Returns non-nil if a save was attempted to a writable cache file. | 514 ;; Returns non-nil if a save was attempted to a writable cache file. |
500 (let ((tpbuf (generate-new-buffer " *fast-lock*")) | 515 (let ((tpbuf (generate-new-buffer " *fast-lock*")) |
501 (buname (buffer-name)) (saved t)) | 516 (verbose (if (numberp fast-lock-verbose) |
502 (message "Saving %s font lock cache..." buname) | 517 (> (buffer-size) fast-lock-verbose) |
518 fast-lock-verbose)) | |
519 (saved t)) | |
520 (if verbose (message "Saving %s font lock cache..." (buffer-name))) | |
503 (condition-case nil | 521 (condition-case nil |
504 (save-excursion | 522 (save-excursion |
505 (print (list 'fast-lock-cache-data 2 | 523 (print (list 'fast-lock-cache-data 2 |
506 (list 'quote timestamp) | 524 (list 'quote timestamp) |
507 (list 'quote font-lock-keywords) | 525 (list 'quote font-lock-keywords) |
511 (write-region (point-min) (point-max) file nil 'quietly) | 529 (write-region (point-min) (point-max) file nil 'quietly) |
512 (setq fast-lock-cache-timestamp timestamp | 530 (setq fast-lock-cache-timestamp timestamp |
513 fast-lock-cache-filename file)) | 531 fast-lock-cache-filename file)) |
514 (error (setq saved 'error)) (quit (setq saved 'quit))) | 532 (error (setq saved 'error)) (quit (setq saved 'quit))) |
515 (kill-buffer tpbuf) | 533 (kill-buffer tpbuf) |
516 (message "Saving %s font lock cache...%s" buname | 534 (if verbose (message "Saving %s font lock cache...%s" (buffer-name) |
517 (cond ((eq saved 'error) "failed") | 535 (cond ((eq saved 'error) "failed") |
518 ((eq saved 'quit) "aborted") | 536 ((eq saved 'quit) "aborted") |
519 (t "done"))) | 537 (t "done")))) |
520 ;; We return non-nil regardless of whether a failure occurred. | 538 ;; We return non-nil regardless of whether a failure occurred. |
521 saved)) | 539 saved)) |
522 | 540 |
523 (defun fast-lock-cache-data (version timestamp keywords properties | 541 (defun fast-lock-cache-data (version timestamp keywords properties |
524 &rest ignored) | 542 &rest ignored) |
531 font-lock-keywords (font-lock-compile-keywords current))) | 549 font-lock-keywords (font-lock-compile-keywords current))) |
532 ;; Use the Font Lock cache PROPERTIES if we're using cache VERSION format 2, | 550 ;; Use the Font Lock cache PROPERTIES if we're using cache VERSION format 2, |
533 ;; the current buffer's file timestamp matches the TIMESTAMP, and the current | 551 ;; the current buffer's file timestamp matches the TIMESTAMP, and the current |
534 ;; buffer's font-lock-keywords are the same as KEYWORDS. | 552 ;; buffer's font-lock-keywords are the same as KEYWORDS. |
535 (let ((buf-timestamp (visited-file-modtime)) | 553 (let ((buf-timestamp (visited-file-modtime)) |
536 (buname (buffer-name)) (loaded t)) | 554 (verbose (if (numberp fast-lock-verbose) |
555 (> (buffer-size) fast-lock-verbose) | |
556 fast-lock-verbose)) | |
557 (loaded t)) | |
537 (if (or (/= version 2) | 558 (if (or (/= version 2) |
538 (buffer-modified-p) | 559 (buffer-modified-p) |
539 (not (equal timestamp buf-timestamp)) | 560 (not (equal timestamp buf-timestamp)) |
540 (not (equal keywords font-lock-keywords))) | 561 (not (equal keywords font-lock-keywords))) |
541 (setq loaded nil) | 562 (setq loaded nil) |
542 (message "Loading %s font lock cache..." buname) | 563 (if verbose (message "Loading %s font lock cache..." (buffer-name))) |
543 (condition-case nil | 564 (condition-case nil |
544 (fast-lock-set-face-properties properties) | 565 (fast-lock-set-face-properties properties) |
545 (error (setq loaded 'error)) (quit (setq loaded 'quit))) | 566 (error (setq loaded 'error)) (quit (setq loaded 'quit))) |
546 (message "Loading %s font lock cache...%s" buname | 567 (if verbose (message "Loading %s font lock cache...%s" (buffer-name) |
547 (cond ((eq loaded 'error) "failed") | 568 (cond ((eq loaded 'error) "failed") |
548 ((eq loaded 'quit) "aborted") | 569 ((eq loaded 'quit) "aborted") |
549 (t "done")))) | 570 (t "done"))))) |
550 (setq font-lock-fontified (eq loaded t) | 571 (setq font-lock-fontified (eq loaded t) |
551 fast-lock-cache-timestamp (and (eq loaded t) timestamp)))) | 572 fast-lock-cache-timestamp (and (eq loaded t) timestamp)))) |
552 | 573 |
553 ;; Text Properties Processing Functions: | 574 ;; Text Properties Processing Functions: |
554 | 575 |
555 ;; This is faster, but fails if adjacent characters have different `face' text | 576 ;; This is fast, but fails if adjacent characters have different `face' text |
556 ;; properties. Maybe that's why I dropped it in the first place? | 577 ;; properties. Maybe that's why I dropped it in the first place? |
557 ;(defun fast-lock-get-face-properties () | 578 ;(defun fast-lock-get-face-properties () |
558 ; "Return a list of all `face' text properties in the current buffer. | 579 ; "Return a list of all `face' text properties in the current buffer. |
559 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) | 580 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) |
560 ;where VALUE is a `face' property value and STARTx and ENDx are positions." | 581 ;where VALUE is a `face' property value and STARTx and ENDx are positions." |
570 ; (setcdr cell (cons start (cons end (cdr cell)))) | 591 ; (setcdr cell (cons start (cons end (cdr cell)))) |
571 ; (setq properties (cons (list value start end) properties))) | 592 ; (setq properties (cons (list value start end) properties))) |
572 ; (setq start (next-single-property-change end 'face))) | 593 ; (setq start (next-single-property-change end 'face))) |
573 ; properties))) | 594 ; properties))) |
574 | 595 |
596 ;; This is slow, but copes if adjacent characters have different `face' text | |
597 ;; properties, but fails if they are lists. | |
598 ;(defun fast-lock-get-face-properties () | |
599 ; "Return a list of all `face' text properties in the current buffer. | |
600 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) | |
601 ;where VALUE is a `face' property value and STARTx and ENDx are positions. | |
602 ;Only those `face' VALUEs in `fast-lock-save-faces' are returned." | |
603 ; (save-restriction | |
604 ; (widen) | |
605 ; (let ((faces (or fast-lock-save-faces (face-list))) (limit (point-max)) | |
606 ; properties regions face start end) | |
607 ; (while faces | |
608 ; (setq face (car faces) faces (cdr faces) regions () end (point-min)) | |
609 ; ;; Make a list of start/end regions with `face' property face. | |
610 ; (while (setq start (text-property-any end limit 'face face)) | |
611 ; (setq end (or (text-property-not-all start limit 'face face) limit) | |
612 ; regions (cons start (cons end regions)))) | |
613 ; ;; Add `face' face's regions, if any, to properties. | |
614 ; (when regions | |
615 ; (push (cons face regions) properties))) | |
616 ; properties))) | |
617 | |
575 (defun fast-lock-get-face-properties () | 618 (defun fast-lock-get-face-properties () |
576 "Return a list of all `face' text properties in the current buffer. | 619 "Return a list of all `face' text properties in the current buffer. |
577 Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) | 620 Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) |
578 where VALUE is a `face' property value and STARTx and ENDx are positions. | 621 where VALUE is a `face' property value and STARTx and ENDx are positions." |
579 Only those `face' VALUEs in `fast-lock-save-faces' are returned." | |
580 (save-restriction | 622 (save-restriction |
581 (widen) | 623 (widen) |
582 (let ((faces (or fast-lock-save-faces (face-list))) (limit (point-max)) | 624 (let ((start (text-property-not-all (point-min) (point-max) 'face nil)) |
583 properties regions face start end) | 625 end properties value cell) |
584 (while faces | 626 (while start |
585 (setq face (car faces) faces (cdr faces) regions () end (point-min)) | 627 (setq end (next-single-property-change start 'face nil (point-max)) |
586 ;; Make a list of start/end regions with `face' property face. | 628 value (get-text-property start 'face)) |
587 (while (setq start (text-property-any end limit 'face face)) | 629 ;; Make, or add to existing, list of regions with same `face'. |
588 (setq end (or (text-property-not-all start limit 'face face) limit) | 630 (cond ((setq cell (assoc value properties)) |
589 regions (cons start (cons end regions)))) | 631 (setcdr cell (cons start (cons end (cdr cell))))) |
590 ;; Add `face' face's regions, if any, to properties. | 632 ((fast-lock-save-facep value) |
591 (when regions | 633 (push (list value start end) properties))) |
592 (push (cons face regions) properties))) | 634 (setq start (text-property-not-all end (point-max) 'face nil))) |
593 properties))) | 635 properties))) |
594 | 636 |
595 (defun fast-lock-set-face-properties (properties) | 637 (defun fast-lock-set-face-properties (properties) |
596 "Set all `face' text properties to PROPERTIES in the current buffer. | 638 "Set all `face' text properties to PROPERTIES in the current buffer. |
597 Any existing `face' text properties are removed first. | 639 Any existing `face' text properties are removed first. |
625 (let ((properties ()) cell) | 667 (let ((properties ()) cell) |
626 (map-extents | 668 (map-extents |
627 (function (lambda (extent ignore) | 669 (function (lambda (extent ignore) |
628 (let ((value (extent-face extent))) | 670 (let ((value (extent-face extent))) |
629 ;; We're only interested if it's one of `fast-lock-save-faces'. | 671 ;; We're only interested if it's one of `fast-lock-save-faces'. |
630 (when (and value (or (null fast-lock-save-faces) | 672 (when (and value (fast-lock-save-facep value)) |
631 (memq value fast-lock-save-faces))) | |
632 (let ((start (extent-start-position extent)) | 673 (let ((start (extent-start-position extent)) |
633 (end (extent-end-position extent))) | 674 (end (extent-end-position extent))) |
634 ;; Make or add to existing list of regions with the same | 675 ;; Make or add to existing list of regions with the same |
635 ;; `face' property value. | 676 ;; `face' property value. |
636 (if (setq cell (assq value properties)) | 677 (if (setq cell (assoc value properties)) |
637 (setcdr cell (cons start (cons end (cdr cell)))) | 678 (setcdr cell (cons start (cons end (cdr cell)))) |
638 (push (list value start end) properties)))) | 679 (push (list value start end) properties)))) |
639 ;; Return nil to keep `map-extents' going. | 680 ;; Return nil to keep `map-extents' going. |
640 nil)))) | 681 nil)))) |
641 properties))) | 682 properties))) |
663 | 704 |
664 (unless (boundp 'font-lock-inhibit-thing-lock) | 705 (unless (boundp 'font-lock-inhibit-thing-lock) |
665 (defvar font-lock-inhibit-thing-lock nil | 706 (defvar font-lock-inhibit-thing-lock nil |
666 "List of Font Lock mode related modes that should not be turned on.")) | 707 "List of Font Lock mode related modes that should not be turned on.")) |
667 | 708 |
709 (unless (fboundp 'font-lock-value-in-major-mode) | |
710 (defun font-lock-value-in-major-mode (alist) | |
711 ;; Return value in ALIST for `major-mode'. | |
712 (if (consp alist) | |
713 (cdr (or (assq major-mode alist) (assq t alist))) | |
714 alist))) | |
715 | |
668 (unless (fboundp 'font-lock-compile-keywords) | 716 (unless (fboundp 'font-lock-compile-keywords) |
669 (defalias 'font-lock-compile-keywords 'identity)) | 717 (defalias 'font-lock-compile-keywords 'identity)) |
670 | 718 |
671 ;; Install ourselves: | 719 ;; Install ourselves: |
672 | 720 |