comparison lisp/packages/fast-lock.el @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents 4103f0995bd7
children 0d2f883870bc
comparison
equal deleted inserted replaced
69:804d1389bcd6 70:131b0175ea99
1 ;;; fast-lock.el --- Automagic text properties caching for fast Font Lock mode. 1 ;;; fast-lock.el --- Automagic text properties caching for fast Font Lock mode.
2 2
3 ;; Copyright (C) 1994, 1995, 1996, 1997 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.11.01 7 ;; Version: 3.10.01
8 8
9 ;;; This file is part of GNU Emacs. 9 ;; This file is part of XEmacs.
10 10 ;;
11 ;; GNU Emacs is free software; you can redistribute it and/or modify 11 ;; XEmacs 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
13 ;; the Free Software Foundation; either version 2, or (at your option) 13 ;; the Free Software Foundation; either version 2 of the License, or
14 ;; any later version. 14 ;; (at your option) any later version.
15 15 ;;
16 ;; GNU Emacs is distributed in the hope that it will be useful, 16 ;; XEmacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details. 19 ;; GNU General Public License for more details.
20 20 ;;
21 ;; You should have received a copy of the GNU General Public License 21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the 22 ;; along with XEmacs; see the file COPYING. If not, write to the
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 ;;; Synched up with: FSF 19.34.
27
26 ;;; Commentary: 28 ;;; Commentary:
27 29
28 ;; Lazy Lock mode is a Font Lock support mode. 30 ;; Purpose:
29 ;; It makes visiting a file in Font Lock mode faster by restoring its face text 31 ;;
30 ;; properties from automatically saved associated Font Lock cache files. 32 ;; To make visiting a file in `font-lock-mode' faster by restoring its face
33 ;; text properties from automatically saved associated Font Lock cache files.
31 ;; 34 ;;
32 ;; See caveats and feedback below. 35 ;; See caveats and feedback below.
33 ;; See also the lazy-lock package. (But don't use the two at the same time!) 36 ;; See also the lazy-lock package. (But don't use the two at the same time!)
34 37
35 ;; Installation: 38 ;; Installation:
50 ;; A cache will be saved when visiting a compressed file using crypt++, but not 53 ;; A cache will be saved when visiting a compressed file using crypt++, but not
51 ;; be read. This is a "feature"/"consequence"/"bug" of crypt++. 54 ;; be read. This is a "feature"/"consequence"/"bug" of crypt++.
52 ;; 55 ;;
53 ;; Version control packages are likely to stamp all over file modification 56 ;; Version control packages are likely to stamp all over file modification
54 ;; times. Therefore the act of checking out may invalidate a cache. 57 ;; times. Therefore the act of checking out may invalidate a cache.
58
59 ;; Feedback:
60 ;;
61 ;; Feedback is welcome.
62 ;; To submit a bug report (or make comments) please use the mechanism provided:
63 ;;
64 ;; M-x fast-lock-submit-bug-report RET
55 65
56 ;; History: 66 ;; History:
57 ;; 67 ;;
58 ;; 0.02--1.00: 68 ;; 0.02--1.00:
59 ;; - Changed name from turbo-prop to fast-lock. Automagic for font-lock only 69 ;; - Changed name from turbo-prop to fast-lock. Automagic for font-lock only
154 ;; - XEmacs: Made `fast-lock-save-faces' default to `font-lock-face-list' 164 ;; - XEmacs: Made `fast-lock-save-faces' default to `font-lock-face-list'
155 ;; - Made `fast-lock-save-cache' use `font-lock-value-in-major-mode' 165 ;; - Made `fast-lock-save-cache' use `font-lock-value-in-major-mode'
156 ;; - Wrap with `save-buffer-state' (Ray Van Tassle report) 166 ;; - Wrap with `save-buffer-state' (Ray Van Tassle report)
157 ;; - Made `fast-lock-mode' wrap `font-lock-support-mode' 167 ;; - Made `fast-lock-mode' wrap `font-lock-support-mode'
158 ;; 3.10--3.11: 168 ;; 3.10--3.11:
159 ;; - Made `fast-lock-get-face-properties' cope with face lists 169
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 ;; 3.10--3.11:
164
165 ;;; Code:
166
167 (require 'font-lock) 170 (require 'font-lock)
168 171
169 ;; Make sure fast-lock.el is supported. 172 ;; Make sure fast-lock.el is supported.
170 (if (and (eq system-type 'ms-dos) (not (msdos-long-file-names))) 173 (if (and (eq system-type 'ms-dos) (not (msdos-long-file-names)))
171 (error "`fast-lock' was written for long file name systems")) 174 (error "`fast-lock' was written for long file name systems"))
189 before-change-functions after-change-functions 192 before-change-functions after-change-functions
190 deactivate-mark buffer-file-name buffer-file-truename)))) 193 deactivate-mark buffer-file-name buffer-file-truename))))
191 (,@ body) 194 (,@ body)
192 (when (and (not modified) (buffer-modified-p)) 195 (when (and (not modified) (buffer-modified-p))
193 (set-buffer-modified-p nil))))) 196 (set-buffer-modified-p nil)))))
194 (put 'save-buffer-state 'lisp-indent-function 1) 197 (put 'save-buffer-state 'lisp-indent-function 1))
195 ;; 198
196 ;; We use this to verify that a face should be saved. 199 (defun fast-lock-submit-bug-report ()
197 (defmacro fast-lock-save-facep (face) 200 "Submit via mail a bug report on fast-lock.el."
198 "Return non-nil if FACE is one of `fast-lock-save-faces'." 201 (interactive)
199 (` (or (null fast-lock-save-faces) 202 (let ((reporter-prompt-for-summary-p t))
200 (if (symbolp (, face)) 203 (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "fast-lock 3.10.01"
201 (memq (, face) fast-lock-save-faces) 204 '(fast-lock-cache-directories fast-lock-minimum-size
202 (let ((faces (, face))) 205 fast-lock-save-others fast-lock-save-events fast-lock-save-faces)
203 (while (unless (memq (car faces) fast-lock-save-faces) 206 nil nil
204 (setq faces (cdr faces)))) 207 (concat "Hi Si.,
205 faces)))))) 208
206 209 I want to report a bug. I've read the `Bugs' section of `Info' on Emacs, so I
207 ;(defun fast-lock-submit-bug-report () 210 know how to make a clear and unambiguous report. To reproduce the bug:
208 ; "Submit via mail a bug report on fast-lock.el." 211
209 ; (interactive) 212 Start a fresh editor via `" invocation-name " -no-init-file -no-site-file'.
210 ; (let ((reporter-prompt-for-summary-p t)) 213 In the `*scratch*' buffer, evaluate:"))))
211 ; (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "fast-lock 3.11.01" 214
212 ; '(fast-lock-cache-directories fast-lock-minimum-size 215 ;;;###autoload
213 ; fast-lock-save-others fast-lock-save-events fast-lock-save-faces 216 (defvar fast-lock-mode nil)
214 ; fast-lock-verbose) 217 (defvar fast-lock-cache-timestamp nil) ; for saving/reading
215 ; nil nil 218 (defvar fast-lock-cache-filename nil) ; for deleting
216 ; (concat "Hi Si.,
217 ;
218 ;I want to report a bug. I've read the `Bugs' section of `Info' on Emacs, so I
219 ;know how to make a clear and unambiguous report. To reproduce the bug:
220 ;
221 ;Start a fresh editor via `" invocation-name " -no-init-file -no-site-file'.
222 ;In the `*scratch*' buffer, evaluate:"))))
223
224 (defvar fast-lock-mode nil) ; Whether we are turned on.
225 (defvar fast-lock-cache-timestamp nil) ; For saving/reading.
226 (defvar fast-lock-cache-filename nil) ; For deleting.
227 219
228 ;; User Variables: 220 ;; User Variables:
229 221
230 (defvar fast-lock-cache-directories '("." "~/.emacs-flc") 222 (defvar fast-lock-cache-directories '("." "~/.emacs-flc")
231 ; - `internal', keep each file's Font Lock cache file in the same file. 223 ; - `internal', keep each file's Font Lock cache file in the same file.
272 (when (save-match-data (string-match "XEmacs" (emacs-version))) 264 (when (save-match-data (string-match "XEmacs" (emacs-version)))
273 ;; XEmacs uses extents for everything, so we have to pick the right ones. 265 ;; XEmacs uses extents for everything, so we have to pick the right ones.
274 font-lock-face-list) 266 font-lock-face-list)
275 "Faces that will be saved in a Font Lock cache file. 267 "Faces that will be saved in a Font Lock cache file.
276 If nil, means information for all faces will be saved.") 268 If nil, means information for all faces will be saved.")
277
278 (defvar fast-lock-verbose font-lock-verbose
279 "*If non-nil, means show status messages for cache processing.
280 If a number, only buffers greater than this size have processing messages.")
281 269
282 ;; User Functions: 270 ;; User Functions:
283 271
284 ;;;###autoload 272 ;;;###autoload
285 (defun fast-lock-mode (&optional arg) 273 (defun fast-lock-mode (&optional arg)
292 If Fast Lock mode is enabled, and the current buffer does not contain any text 280 If Fast Lock mode is enabled, and the current buffer does not contain any text
293 properties, any associated Font Lock cache is used if its timestamp matches the 281 properties, any associated Font Lock cache is used if its timestamp matches the
294 buffer's file, and its `font-lock-keywords' match those that you are using. 282 buffer's file, and its `font-lock-keywords' match those that you are using.
295 283
296 Font Lock caches may be saved: 284 Font Lock caches may be saved:
297 - When you save the file's buffer. 285 - When you save the file's buffer.
298 - When you kill an unmodified file's buffer. 286 - When you kill an unmodified file's buffer.
299 - When you exit Emacs, for all unmodified or saved buffers. 287 - When you exit Emacs, for all unmodified or saved buffers.
300 Depending on the value of `fast-lock-save-events'. 288 Depending on the value of `fast-lock-save-events'.
301 See also the commands `fast-lock-read-cache' and `fast-lock-save-cache'. 289 See also the commands `fast-lock-read-cache' and `fast-lock-save-cache'.
302 290
303 Use \\[font-lock-fontify-buffer] to fontify the buffer if the cache is bad. 291 Use \\[font-lock-fontify-buffer] to fontify the buffer if the cache is bad.
304 292
305 Various methods of control are provided for the Font Lock cache. In general, 293 Various methods of control are provided for the Font Lock cache. In general,
306 see variable `fast-lock-cache-directories' and function `fast-lock-cache-name'. 294 see variable `fast-lock-cache-directories' and function `fast-lock-cache-name'.
307 For saving, see variables `fast-lock-minimum-size', `fast-lock-save-events', 295 For saving, see variables `fast-lock-minimum-size', `fast-lock-save-events',
308 `fast-lock-save-others' and `fast-lock-save-faces'." 296 `fast-lock-save-others' and `fast-lock-save-faces'.
297
298 Use \\[fast-lock-submit-bug-report] to send bug reports or feedback."
309 (interactive "P") 299 (interactive "P")
310 ;; Only turn on if we are visiting a file. We could use `buffer-file-name', 300 ;; Only turn on if we are visiting a file. We could use `buffer-file-name',
311 ;; but many packages temporarily wrap that to nil when doing their own thing. 301 ;; but many packages temporarily wrap that to nil when doing their own thing.
312 (set (make-local-variable 'fast-lock-mode) 302 (set (make-local-variable 'fast-lock-mode)
313 (and buffer-file-truename 303 (and buffer-file-truename
325 315
326 (defun fast-lock-read-cache () 316 (defun fast-lock-read-cache ()
327 "Read the Font Lock cache for the current buffer. 317 "Read the Font Lock cache for the current buffer.
328 318
329 The following criteria must be met for a Font Lock cache file to be read: 319 The following criteria must be met for a Font Lock cache file to be read:
330 - Fast Lock mode must be turned on in the buffer. 320 - Fast Lock mode must be turned on in the buffer.
331 - The buffer must not be modified. 321 - The buffer must not be modified.
332 - The buffer's `font-lock-keywords' must match the cache's. 322 - The buffer's `font-lock-keywords' must match the cache's.
333 - The buffer file's timestamp must match the cache's. 323 - The buffer file's timestamp must match the cache's.
334 - Criteria imposed by `fast-lock-cache-directories'. 324 - Criteria imposed by `fast-lock-cache-directories'.
335 325
336 See `fast-lock-mode'." 326 See `fast-lock-mode'."
337 (interactive) 327 (interactive)
338 (let ((directories fast-lock-cache-directories) 328 (let ((directories fast-lock-cache-directories)
339 (modified (buffer-modified-p)) (inhibit-read-only t) 329 (modified (buffer-modified-p)) (inhibit-read-only t)
358 348
359 (defun fast-lock-save-cache (&optional buffer) 349 (defun fast-lock-save-cache (&optional buffer)
360 "Save the Font Lock cache of BUFFER or the current buffer. 350 "Save the Font Lock cache of BUFFER or the current buffer.
361 351
362 The following criteria must be met for a Font Lock cache file to be saved: 352 The following criteria must be met for a Font Lock cache file to be saved:
363 - Fast Lock mode must be turned on in the buffer. 353 - Fast Lock mode must be turned on in the buffer.
364 - The event must be one of `fast-lock-save-events'. 354 - The event must be one of `fast-lock-save-events'.
365 - The buffer must be at least `fast-lock-minimum-size' bytes long. 355 - The buffer must be at least `fast-lock-minimum-size' bytes long.
366 - The buffer file must be owned by you, or `fast-lock-save-others' must be t. 356 - The buffer file must be owned by you, or `fast-lock-save-others' must be t.
367 - The buffer must contain at least one `face' text property. 357 - The buffer must contain at least one `face' text property.
368 - The buffer must not be modified. 358 - The buffer must not be modified.
369 - The buffer file's timestamp must be the same as the file's on disk. 359 - The buffer file's timestamp must be the same as the file's on disk.
370 - The on disk file's timestamp must be different than the buffer's cache. 360 - The on disk file's timestamp must be different than the buffer's cache.
371 - Criteria imposed by `fast-lock-cache-directories'. 361 - Criteria imposed by `fast-lock-cache-directories'.
372 362
373 See `fast-lock-mode'." 363 See `fast-lock-mode'."
374 (interactive) 364 (interactive)
375 (save-excursion 365 (save-excursion
376 (when buffer 366 (when buffer
512 (defun fast-lock-save-cache-1 (file timestamp) 502 (defun fast-lock-save-cache-1 (file timestamp)
513 ;; Save the FILE with the TIMESTAMP as: 503 ;; Save the FILE with the TIMESTAMP as:
514 ;; (fast-lock-cache-data Version=2 TIMESTAMP font-lock-keywords PROPERTIES). 504 ;; (fast-lock-cache-data Version=2 TIMESTAMP font-lock-keywords PROPERTIES).
515 ;; Returns non-nil if a save was attempted to a writable cache file. 505 ;; Returns non-nil if a save was attempted to a writable cache file.
516 (let ((tpbuf (generate-new-buffer " *fast-lock*")) 506 (let ((tpbuf (generate-new-buffer " *fast-lock*"))
517 (verbose (if (numberp fast-lock-verbose) 507 (buname (buffer-name)) (saved t))
518 (> (buffer-size) fast-lock-verbose) 508 (message "Saving %s font lock cache..." buname)
519 fast-lock-verbose))
520 (saved t))
521 (if verbose (message "Saving %s font lock cache..." (buffer-name)))
522 (condition-case nil 509 (condition-case nil
523 (save-excursion 510 (save-excursion
524 (print (list 'fast-lock-cache-data 2 511 (print (list 'fast-lock-cache-data 2
525 (list 'quote timestamp) 512 (list 'quote timestamp)
526 (list 'quote font-lock-keywords) 513 (list 'quote font-lock-keywords)
530 (write-region (point-min) (point-max) file nil 'quietly) 517 (write-region (point-min) (point-max) file nil 'quietly)
531 (setq fast-lock-cache-timestamp timestamp 518 (setq fast-lock-cache-timestamp timestamp
532 fast-lock-cache-filename file)) 519 fast-lock-cache-filename file))
533 (error (setq saved 'error)) (quit (setq saved 'quit))) 520 (error (setq saved 'error)) (quit (setq saved 'quit)))
534 (kill-buffer tpbuf) 521 (kill-buffer tpbuf)
535 (if verbose (message "Saving %s font lock cache...%s" (buffer-name) 522 (message "Saving %s font lock cache...%s" buname
536 (cond ((eq saved 'error) "failed") 523 (cond ((eq saved 'error) "failed")
537 ((eq saved 'quit) "aborted") 524 ((eq saved 'quit) "aborted")
538 (t "done")))) 525 (t "done")))
539 ;; We return non-nil regardless of whether a failure occurred. 526 ;; We return non-nil regardless of whether a failure occurred.
540 saved)) 527 saved))
541 528
542 (defun fast-lock-cache-data (version timestamp keywords properties 529 (defun fast-lock-cache-data (version timestamp keywords properties
543 &rest ignored) 530 &rest ignored)
550 font-lock-keywords (font-lock-compile-keywords current))) 537 font-lock-keywords (font-lock-compile-keywords current)))
551 ;; Use the Font Lock cache PROPERTIES if we're using cache VERSION format 2, 538 ;; Use the Font Lock cache PROPERTIES if we're using cache VERSION format 2,
552 ;; the current buffer's file timestamp matches the TIMESTAMP, and the current 539 ;; the current buffer's file timestamp matches the TIMESTAMP, and the current
553 ;; buffer's font-lock-keywords are the same as KEYWORDS. 540 ;; buffer's font-lock-keywords are the same as KEYWORDS.
554 (let ((buf-timestamp (visited-file-modtime)) 541 (let ((buf-timestamp (visited-file-modtime))
555 (verbose (if (numberp fast-lock-verbose) 542 (buname (buffer-name)) (loaded t))
556 (> (buffer-size) fast-lock-verbose)
557 fast-lock-verbose))
558 (loaded t))
559 (if (or (/= version 2) 543 (if (or (/= version 2)
560 (buffer-modified-p) 544 (buffer-modified-p)
561 (not (equal timestamp buf-timestamp)) 545 (not (equal timestamp buf-timestamp))
562 (not (equal keywords font-lock-keywords))) 546 (not (equal keywords font-lock-keywords)))
563 (setq loaded nil) 547 (setq loaded nil)
564 (if verbose (message "Loading %s font lock cache..." (buffer-name))) 548 (message "Loading %s font lock cache..." buname)
565 (condition-case nil 549 (condition-case nil
566 (fast-lock-set-face-properties properties) 550 (fast-lock-set-face-properties properties)
567 (error (setq loaded 'error)) (quit (setq loaded 'quit))) 551 (error (setq loaded 'error)) (quit (setq loaded 'quit)))
568 (if verbose (message "Loading %s font lock cache...%s" (buffer-name) 552 (message "Loading %s font lock cache...%s" buname
569 (cond ((eq loaded 'error) "failed") 553 (cond ((eq loaded 'error) "failed")
570 ((eq loaded 'quit) "aborted") 554 ((eq loaded 'quit) "aborted")
571 (t "done"))))) 555 (t "done"))))
572 (setq font-lock-fontified (eq loaded t) 556 (setq font-lock-fontified (eq loaded t)
573 fast-lock-cache-timestamp (and (eq loaded t) timestamp)))) 557 fast-lock-cache-timestamp (and (eq loaded t) timestamp))))
574 558
575 ;; Text Properties Processing Functions: 559 ;; Text Properties Processing Functions:
576 560
577 ;; This is fast, but fails if adjacent characters have different `face' text 561 ;; This is faster, but fails if adjacent characters have different `face' text
578 ;; properties. Maybe that's why I dropped it in the first place? 562 ;; properties. Maybe that's why I dropped it in the first place?
579 ;(defun fast-lock-get-face-properties () 563 ;(defun fast-lock-get-face-properties ()
580 ; "Return a list of all `face' text properties in the current buffer. 564 ; "Return a list of all `face' text properties in the current buffer.
581 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) 565 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...)
582 ;where VALUE is a `face' property value and STARTx and ENDx are positions." 566 ;where VALUE is a `face' property value and STARTx and ENDx are positions."
592 ; (setcdr cell (cons start (cons end (cdr cell)))) 576 ; (setcdr cell (cons start (cons end (cdr cell))))
593 ; (setq properties (cons (list value start end) properties))) 577 ; (setq properties (cons (list value start end) properties)))
594 ; (setq start (next-single-property-change end 'face))) 578 ; (setq start (next-single-property-change end 'face)))
595 ; properties))) 579 ; properties)))
596 580
597 ;; This is slow, but copes if adjacent characters have different `face' text
598 ;; properties, but fails if they are lists.
599 ;(defun fast-lock-get-face-properties ()
600 ; "Return a list of all `face' text properties in the current buffer.
601 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...)
602 ;where VALUE is a `face' property value and STARTx and ENDx are positions.
603 ;Only those `face' VALUEs in `fast-lock-save-faces' are returned."
604 ; (save-restriction
605 ; (widen)
606 ; (let ((faces (or fast-lock-save-faces (face-list))) (limit (point-max))
607 ; properties regions face start end)
608 ; (while faces
609 ; (setq face (car faces) faces (cdr faces) regions () end (point-min))
610 ; ;; Make a list of start/end regions with `face' property face.
611 ; (while (setq start (text-property-any end limit 'face face))
612 ; (setq end (or (text-property-not-all start limit 'face face) limit)
613 ; regions (cons start (cons end regions))))
614 ; ;; Add `face' face's regions, if any, to properties.
615 ; (when regions
616 ; (push (cons face regions) properties)))
617 ; properties)))
618
619 (defun fast-lock-get-face-properties () 581 (defun fast-lock-get-face-properties ()
620 "Return a list of all `face' text properties in the current buffer. 582 "Return a list of all `face' text properties in the current buffer.
621 Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) 583 Each element of the list is of the form (VALUE START1 END1 START2 END2 ...)
622 where VALUE is a `face' property value and STARTx and ENDx are positions." 584 where VALUE is a `face' property value and STARTx and ENDx are positions.
585 Only those `face' VALUEs in `fast-lock-save-faces' are returned."
623 (save-restriction 586 (save-restriction
624 (widen) 587 (widen)
625 (let ((start (text-property-not-all (point-min) (point-max) 'face nil)) 588 (let ((faces (or fast-lock-save-faces (face-list))) (limit (point-max))
626 end properties value cell) 589 properties regions face start end)
627 (while start 590 (while faces
628 (setq end (next-single-property-change start 'face nil (point-max)) 591 (setq face (car faces) faces (cdr faces) regions () end (point-min))
629 value (get-text-property start 'face)) 592 ;; Make a list of start/end regions with `face' property face.
630 ;; Make, or add to existing, list of regions with same `face'. 593 (while (setq start (text-property-any end limit 'face face))
631 (cond ((setq cell (assoc value properties)) 594 (setq end (or (text-property-not-all start limit 'face face) limit)
632 (setcdr cell (cons start (cons end (cdr cell))))) 595 regions (cons start (cons end regions))))
633 ((fast-lock-save-facep value) 596 ;; Add `face' face's regions, if any, to properties.
634 (push (list value start end) properties))) 597 (when regions
635 (setq start (text-property-not-all end (point-max) 'face nil))) 598 (push (cons face regions) properties)))
636 properties))) 599 properties)))
637 600
638 (defun fast-lock-set-face-properties (properties) 601 (defun fast-lock-set-face-properties (properties)
639 "Set all `face' text properties to PROPERTIES in the current buffer. 602 "Set all `face' text properties to PROPERTIES in the current buffer.
640 Any existing `face' text properties are removed first. 603 Any existing `face' text properties are removed first.
668 (let ((properties ()) cell) 631 (let ((properties ()) cell)
669 (map-extents 632 (map-extents
670 (function (lambda (extent ignore) 633 (function (lambda (extent ignore)
671 (let ((value (extent-face extent))) 634 (let ((value (extent-face extent)))
672 ;; We're only interested if it's one of `fast-lock-save-faces'. 635 ;; We're only interested if it's one of `fast-lock-save-faces'.
673 (when (and value (fast-lock-save-facep value)) 636 (when (and value (or (null fast-lock-save-faces)
637 (memq value fast-lock-save-faces)))
674 (let ((start (extent-start-position extent)) 638 (let ((start (extent-start-position extent))
675 (end (extent-end-position extent))) 639 (end (extent-end-position extent)))
676 ;; Make or add to existing list of regions with the same 640 ;; Make or add to existing list of regions with the same
677 ;; `face' property value. 641 ;; `face' property value.
678 (if (setq cell (assoc value properties)) 642 (if (setq cell (assq value properties))
679 (setcdr cell (cons start (cons end (cdr cell)))) 643 (setcdr cell (cons start (cons end (cdr cell))))
680 (push (list value start end) properties)))) 644 (push (list value start end) properties))))
681 ;; Return nil to keep `map-extents' going. 645 ;; Return nil to keep `map-extents' going.
682 nil)))) 646 nil))))
683 properties))) 647 properties)))
722 (add-hook 'after-save-hook 'fast-lock-save-cache-after-save-file) 686 (add-hook 'after-save-hook 'fast-lock-save-cache-after-save-file)
723 (add-hook 'kill-buffer-hook 'fast-lock-save-cache-before-kill-buffer) 687 (add-hook 'kill-buffer-hook 'fast-lock-save-cache-before-kill-buffer)
724 (add-hook 'kill-emacs-hook 'fast-lock-save-caches-before-kill-emacs) 688 (add-hook 'kill-emacs-hook 'fast-lock-save-caches-before-kill-emacs)
725 689
726 ;;;###autoload 690 ;;;###autoload
727 (when (fboundp 'add-minor-mode) 691 (if (fboundp 'add-minor-mode) (add-minor-mode 'fast-lock-mode nil))
728 (defvar fast-lock-mode nil)
729 (add-minor-mode 'fast-lock-mode nil))
730 ;;;###dont-autoload 692 ;;;###dont-autoload
731 (unless (assq 'fast-lock-mode minor-mode-alist) 693 (unless (assq 'fast-lock-mode minor-mode-alist)
732 (setq minor-mode-alist (append minor-mode-alist '((fast-lock-mode nil))))) 694 (setq minor-mode-alist (append minor-mode-alist '((fast-lock-mode nil)))))
733 695
734 ;; Provide ourselves: 696 ;; Provide ourselves: