comparison lisp/fast-lock.el @ 18023:12fc8bc96c58

Update for syntax-table text properties. fast-lock.el now saves and restores them.
author Simon Marshall <simon@gnu.org>
date Thu, 29 May 1997 07:01:36 +0000
parents b9ca2d28765c
children 6156115816da
comparison
equal deleted inserted replaced
18022:85119f319971 18023:12fc8bc96c58
2 2
3 ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1994, 1995, 1996, 1997 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.12.01 7 ;; Version: 3.12.02
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
164 ;; - Added Custom support (Hrvoje Niksic help) 164 ;; - Added Custom support (Hrvoje Niksic help)
165 ;; - Made `save-buffer-state' wrap `inhibit-point-motion-hooks' 165 ;; - Made `save-buffer-state' wrap `inhibit-point-motion-hooks'
166 ;; - Made `fast-lock-cache-data' simplify calls of `font-lock-compile-keywords' 166 ;; - Made `fast-lock-cache-data' simplify calls of `font-lock-compile-keywords'
167 ;; 3.12--3.13: 167 ;; 3.12--3.13:
168 ;; - Removed `byte-*' variables from `eval-when-compile' (Erik Naggum hint) 168 ;; - Removed `byte-*' variables from `eval-when-compile' (Erik Naggum hint)
169 ;; - Changed structure of cache to include `font-lock-syntactic-keywords'
170 ;; - Made `fast-lock-save-cache-1' save syntactic fontification data
171 ;; - Made `fast-lock-cache-data' take syntactic fontification data
172 ;; - Added `fast-lock-get-syntactic-properties'
173 ;; - Renamed `fast-lock-set-face-properties' to `fast-lock-add-properties'
174 ;; - Made `fast-lock-add-properties' add syntactic and face fontification data
169 175
170 ;;; Code: 176 ;;; Code:
171 177
172 (require 'font-lock) 178 (require 'font-lock)
173 179
211 217
212 ;(defun fast-lock-submit-bug-report () 218 ;(defun fast-lock-submit-bug-report ()
213 ; "Submit via mail a bug report on fast-lock.el." 219 ; "Submit via mail a bug report on fast-lock.el."
214 ; (interactive) 220 ; (interactive)
215 ; (let ((reporter-prompt-for-summary-p t)) 221 ; (let ((reporter-prompt-for-summary-p t))
216 ; (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "fast-lock 3.12.01" 222 ; (reporter-submit-bug-report "simon@gnu.ai.mit.edu" "fast-lock 3.12.02"
217 ; '(fast-lock-cache-directories fast-lock-minimum-size 223 ; '(fast-lock-cache-directories fast-lock-minimum-size
218 ; fast-lock-save-others fast-lock-save-events fast-lock-save-faces 224 ; fast-lock-save-others fast-lock-save-events fast-lock-save-faces
219 ; fast-lock-verbose) 225 ; fast-lock-verbose)
220 ; nil nil 226 ; nil nil
221 ; (concat "Hi Si., 227 ; (concat "Hi Si.,
539 (mapconcat 'char-to-string (apply 'append (mapcar mapchars bufile)) "") 545 (mapconcat 'char-to-string (apply 'append (mapcar mapchars bufile)) "")
540 ".flc")))) 546 ".flc"))))
541 547
542 ;; Font Lock Cache Processing Functions: 548 ;; Font Lock Cache Processing Functions:
543 549
550 ;; The version 3 format of the cache is:
551 ;;
552 ;; (fast-lock-cache-data VERSION TIMESTAMP
553 ;; font-lock-syntactic-keywords SYNTACTIC-PROPERTIES
554 ;; font-lock-keywords FACE-PROPERTIES)
555
544 (defun fast-lock-save-cache-1 (file timestamp) 556 (defun fast-lock-save-cache-1 (file timestamp)
545 ;; Save the FILE with the TIMESTAMP as: 557 ;; Save the FILE with the TIMESTAMP plus fontification data.
546 ;; (fast-lock-cache-data Version=2 TIMESTAMP font-lock-keywords PROPERTIES).
547 ;; Returns non-nil if a save was attempted to a writable cache file. 558 ;; Returns non-nil if a save was attempted to a writable cache file.
548 (let ((tpbuf (generate-new-buffer " *fast-lock*")) 559 (let ((tpbuf (generate-new-buffer " *fast-lock*"))
549 (verbose (if (numberp fast-lock-verbose) 560 (verbose (if (numberp fast-lock-verbose)
550 (> (buffer-size) fast-lock-verbose) 561 (> (buffer-size) fast-lock-verbose)
551 fast-lock-verbose)) 562 fast-lock-verbose))
552 (saved t)) 563 (saved t))
553 (if verbose (message "Saving %s font lock cache..." (buffer-name))) 564 (if verbose (message "Saving %s font lock cache..." (buffer-name)))
554 (condition-case nil 565 (condition-case nil
555 (save-excursion 566 (save-excursion
556 (print (list 'fast-lock-cache-data 2 567 (print (list 'fast-lock-cache-data 3
557 (list 'quote timestamp) 568 (list 'quote timestamp)
569 (list 'quote font-lock-syntactic-keywords)
570 (list 'quote (fast-lock-get-syntactic-properties))
558 (list 'quote font-lock-keywords) 571 (list 'quote font-lock-keywords)
559 (list 'quote (fast-lock-get-face-properties))) 572 (list 'quote (fast-lock-get-face-properties)))
560 tpbuf) 573 tpbuf)
561 (set-buffer tpbuf) 574 (set-buffer tpbuf)
562 (write-region (point-min) (point-max) file nil 'quietly) 575 (write-region (point-min) (point-max) file nil 'quietly)
569 ((eq saved 'quit) "aborted") 582 ((eq saved 'quit) "aborted")
570 (t "done")))) 583 (t "done"))))
571 ;; We return non-nil regardless of whether a failure occurred. 584 ;; We return non-nil regardless of whether a failure occurred.
572 saved)) 585 saved))
573 586
574 (defun fast-lock-cache-data (version timestamp keywords properties 587 (defun fast-lock-cache-data (version timestamp
588 syntactic-keywords syntactic-properties
589 keywords face-properties
575 &rest ignored) 590 &rest ignored)
576 ;; Change from (HIGH LOW) for back compatibility. Remove for version 3! 591 ;; Find value of syntactic keywords in case it is a symbol.
577 (when (consp (cdr-safe timestamp)) 592 (setq font-lock-syntactic-keywords (font-lock-eval-keywords
578 (setcdr timestamp (nth 1 timestamp))) 593 font-lock-syntactic-keywords))
579 ;; Compile `font-lock-keywords' and KEYWORDS in case one is and one isn't. 594 ;; Compile all keywords in case some are and some aren't.
580 (setq font-lock-keywords (font-lock-compile-keywords font-lock-keywords) 595 (setq font-lock-syntactic-keywords (font-lock-compile-keywords
596 font-lock-syntactic-keywords)
597 syntactic-keywords (font-lock-compile-keywords syntactic-keywords)
598
599 font-lock-keywords (font-lock-compile-keywords font-lock-keywords)
581 keywords (font-lock-compile-keywords keywords)) 600 keywords (font-lock-compile-keywords keywords))
582 ;; Use the Font Lock cache PROPERTIES if we're using cache VERSION format 2, 601 ;; Use the Font Lock cache SYNTACTIC-PROPERTIES and FACE-PROPERTIES if we're
583 ;; the current buffer's file timestamp matches the TIMESTAMP, and the current 602 ;; using cache VERSION format 3, the current buffer's file timestamp matches
584 ;; buffer's font-lock-keywords are the same as KEYWORDS. 603 ;; the TIMESTAMP, the current buffer's `font-lock-syntactic-keywords' are the
604 ;; same as SYNTACTIC-KEYWORDS, and the current buffer's `font-lock-keywords'
605 ;; are the same as KEYWORDS.
585 (let ((buf-timestamp (visited-file-modtime)) 606 (let ((buf-timestamp (visited-file-modtime))
586 (verbose (if (numberp fast-lock-verbose) 607 (verbose (if (numberp fast-lock-verbose)
587 (> (buffer-size) fast-lock-verbose) 608 (> (buffer-size) fast-lock-verbose)
588 fast-lock-verbose)) 609 fast-lock-verbose))
589 (loaded t)) 610 (loaded t))
590 (if (or (/= version 2) 611 (if (or (/= version 3)
591 (buffer-modified-p) 612 (buffer-modified-p)
592 (not (equal timestamp buf-timestamp)) 613 (not (equal timestamp buf-timestamp))
614 (not (equal syntactic-keywords font-lock-syntactic-keywords))
593 (not (equal keywords font-lock-keywords))) 615 (not (equal keywords font-lock-keywords)))
594 (setq loaded nil) 616 (setq loaded nil)
595 (if verbose (message "Loading %s font lock cache..." (buffer-name))) 617 (if verbose (message "Loading %s font lock cache..." (buffer-name)))
596 (condition-case nil 618 (condition-case nil
597 (fast-lock-set-face-properties properties) 619 (fast-lock-add-properties syntactic-properties face-properties)
598 (error (setq loaded 'error)) (quit (setq loaded 'quit))) 620 (error (setq loaded 'error)) (quit (setq loaded 'quit)))
599 (if verbose (message "Loading %s font lock cache...%s" (buffer-name) 621 (if verbose (message "Loading %s font lock cache...%s" (buffer-name)
600 (cond ((eq loaded 'error) "failed") 622 (cond ((eq loaded 'error) "failed")
601 ((eq loaded 'quit) "aborted") 623 ((eq loaded 'quit) "aborted")
602 (t "done"))))) 624 (t "done")))))
606 ;; Text Properties Processing Functions: 628 ;; Text Properties Processing Functions:
607 629
608 ;; This is fast, but fails if adjacent characters have different `face' text 630 ;; This is fast, but fails if adjacent characters have different `face' text
609 ;; properties. Maybe that's why I dropped it in the first place? 631 ;; properties. Maybe that's why I dropped it in the first place?
610 ;(defun fast-lock-get-face-properties () 632 ;(defun fast-lock-get-face-properties ()
611 ; "Return a list of all `face' text properties in the current buffer. 633 ; "Return a list of `face' text properties in the current buffer.
612 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) 634 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...)
613 ;where VALUE is a `face' property value and STARTx and ENDx are positions." 635 ;where VALUE is a `face' property value and STARTx and ENDx are positions."
614 ; (save-restriction 636 ; (save-restriction
615 ; (widen) 637 ; (widen)
616 ; (let ((start (text-property-not-all (point-min) (point-max) 'face nil)) 638 ; (let ((start (text-property-not-all (point-min) (point-max) 'face nil))
626 ; properties))) 648 ; properties)))
627 649
628 ;; This is slow, but copes if adjacent characters have different `face' text 650 ;; This is slow, but copes if adjacent characters have different `face' text
629 ;; properties, but fails if they are lists. 651 ;; properties, but fails if they are lists.
630 ;(defun fast-lock-get-face-properties () 652 ;(defun fast-lock-get-face-properties ()
631 ; "Return a list of all `face' text properties in the current buffer. 653 ; "Return a list of `face' text properties in the current buffer.
632 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) 654 ;Each element of the list is of the form (VALUE START1 END1 START2 END2 ...)
633 ;where VALUE is a `face' property value and STARTx and ENDx are positions. 655 ;where VALUE is a `face' property value and STARTx and ENDx are positions.
634 ;Only those `face' VALUEs in `fast-lock-save-faces' are returned." 656 ;Only those `face' VALUEs in `fast-lock-save-faces' are returned."
635 ; (save-restriction 657 ; (save-restriction
636 ; (widen) 658 ; (widen)
646 ; (when regions 668 ; (when regions
647 ; (push (cons face regions) properties))) 669 ; (push (cons face regions) properties)))
648 ; properties))) 670 ; properties)))
649 671
650 (defun fast-lock-get-face-properties () 672 (defun fast-lock-get-face-properties ()
651 "Return a list of all `face' text properties in the current buffer. 673 "Return a list of `face' text properties in the current buffer.
652 Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) 674 Each element of the list is of the form (VALUE START1 END1 START2 END2 ...)
653 where VALUE is a `face' property value and STARTx and ENDx are positions." 675 where VALUE is a `face' property value and STARTx and ENDx are positions."
654 (save-restriction 676 (save-restriction
655 (widen) 677 (widen)
656 (let ((start (text-property-not-all (point-min) (point-max) 'face nil)) 678 (let ((start (text-property-not-all (point-min) (point-max) 'face nil))
664 ((fast-lock-save-facep value) 686 ((fast-lock-save-facep value)
665 (push (list value start end) properties))) 687 (push (list value start end) properties)))
666 (setq start (text-property-not-all end (point-max) 'face nil))) 688 (setq start (text-property-not-all end (point-max) 'face nil)))
667 properties))) 689 properties)))
668 690
669 (defun fast-lock-set-face-properties (properties) 691 (defun fast-lock-get-syntactic-properties ()
670 "Set all `face' text properties to PROPERTIES in the current buffer. 692 "Return a list of `syntax-table' text properties in the current buffer.
671 Any existing `face' text properties are removed first. 693 See `fast-lock-get-face-properties'."
672 See `fast-lock-get-face-properties' for the format of PROPERTIES." 694 (save-restriction
695 (widen)
696 (let ((start (text-property-not-all (point-min) (point-max) 'syntax-table
697 nil))
698 end properties value cell)
699 (while start
700 (setq end (next-single-property-change start 'syntax-table nil
701 (point-max))
702 value (get-text-property start 'syntax-table))
703 ;; Make, or add to existing, list of regions with same `syntax-table'.
704 (if (setq cell (assoc value properties))
705 (setcdr cell (cons start (cons end (cdr cell))))
706 (push (list value start end) properties))
707 (setq start (text-property-not-all end (point-max) 'syntax-table nil)))
708 properties)))
709
710 (defun fast-lock-add-properties (syntactic-properties face-properties)
711 "Add `syntax-table' and `face' text properties to the current buffer.
712 Any existing `syntax-table' and `face' text properties are removed first.
713 See `fast-lock-get-face-properties'."
673 (save-buffer-state (plist regions) 714 (save-buffer-state (plist regions)
674 (save-restriction 715 (save-restriction
675 (widen) 716 (widen)
676 (font-lock-unfontify-region (point-min) (point-max)) 717 (font-lock-unfontify-region (point-min) (point-max))
677 (while properties 718 ;;
678 (setq plist (list 'face (car (car properties))) 719 ;; Set the `syntax-table' property for each start/end region.
679 regions (cdr (car properties)) 720 (while syntactic-properties
680 properties (cdr properties)) 721 (setq plist (list 'syntax-table (car (car syntactic-properties)))
681 ;; Set the `face' property for each start/end region. 722 regions (cdr (car syntactic-properties))
723 syntactic-properties (cdr syntactic-properties))
682 (while regions 724 (while regions
683 (set-text-properties (nth 0 regions) (nth 1 regions) plist) 725 (add-text-properties (nth 0 regions) (nth 1 regions) plist)
726 (setq regions (nthcdr 2 regions))))
727 ;;
728 ;; Set the `face' property for each start/end region.
729 (while face-properties
730 (setq plist (list 'face (car (car face-properties)))
731 regions (cdr (car face-properties))
732 face-properties (cdr face-properties))
733 (while regions
734 (add-text-properties (nth 0 regions) (nth 1 regions) plist)
684 (setq regions (nthcdr 2 regions))))))) 735 (setq regions (nthcdr 2 regions)))))))
685 736
686 ;; Functions for XEmacs: 737 ;; Functions for XEmacs:
687 738
688 (when (save-match-data (string-match "XEmacs" (emacs-version))) 739 (when (save-match-data (string-match "XEmacs" (emacs-version)))
689 ;; 740 ;;
690 ;; It would be better to use XEmacs' `map-extents' over extents with a 741 ;; It would be better to use XEmacs' `map-extents' over extents with a
691 ;; `font-lock' property, but `face' properties are on different extents. 742 ;; `font-lock' property, but `face' properties are on different extents.
692 (defun fast-lock-get-face-properties () 743 (defun fast-lock-get-face-properties ()
693 "Return a list of all `face' text properties in the current buffer. 744 "Return a list of `face' text properties in the current buffer.
694 Each element of the list is of the form (VALUE START1 END1 START2 END2 ...) 745 Each element of the list is of the form (VALUE START1 END1 START2 END2 ...)
695 where VALUE is a `face' property value and STARTx and ENDx are positions. 746 where VALUE is a `face' property value and STARTx and ENDx are positions.
696 Only those `face' VALUEs in `fast-lock-save-faces' are returned." 747 Only those `face' VALUEs in `fast-lock-save-faces' are returned."
697 (save-restriction 748 (save-restriction
698 (widen) 749 (widen)
711 (push (list value start end) properties)))) 762 (push (list value start end) properties))))
712 ;; Return nil to keep `map-extents' going. 763 ;; Return nil to keep `map-extents' going.
713 nil)))) 764 nil))))
714 properties))) 765 properties)))
715 ;; 766 ;;
767 ;; XEmacs does not support the `syntax-table' text property.
768 (defalias 'fast-lock-get-syntactic-properties
769 'ignore)
770 ;;
716 ;; Make extents just like XEmacs' font-lock.el does. 771 ;; Make extents just like XEmacs' font-lock.el does.
717 (defun fast-lock-set-face-properties (properties) 772 (defun fast-lock-add-properties (syntactic-properties face-properties)
718 "Set all `face' text properties to PROPERTIES in the current buffer. 773 "Set `face' text properties in the current buffer.
719 Any existing `face' text properties are removed first. 774 Any existing `face' text properties are removed first.
720 See `fast-lock-get-face-properties' for the format of PROPERTIES." 775 See `fast-lock-get-face-properties'."
721 (save-restriction 776 (save-restriction
722 (widen) 777 (widen)
723 (font-lock-unfontify-region (point-min) (point-max)) 778 (font-lock-unfontify-region (point-min) (point-max))
724 (while properties 779 ;; Set the `face' property, etc., for each start/end region.
725 (let ((face (car (car properties))) 780 (while face-properties
726 (regions (cdr (car properties)))) 781 (let ((face (car (car face-properties)))
727 ;; Set the `face' property, etc., for each start/end region. 782 (regions (cdr (car face-properties))))
728 (while regions 783 (while regions
729 (font-lock-set-face (nth 0 regions) (nth 1 regions) face) 784 (font-lock-set-face (nth 0 regions) (nth 1 regions) face)
730 (setq regions (nthcdr 2 regions))) 785 (setq regions (nthcdr 2 regions)))
731 (setq properties (cdr properties)))))) 786 (setq face-properties (cdr face-properties))))
787 ;; XEmacs does not support the `syntax-table' text property.
788 ))
732 ;; 789 ;;
733 ;; XEmacs 19.12 font-lock.el's `font-lock-fontify-buffer' runs a hook. 790 ;; XEmacs 19.12 font-lock.el's `font-lock-fontify-buffer' runs a hook.
734 (add-hook 'font-lock-after-fontify-buffer-hook 791 (add-hook 'font-lock-after-fontify-buffer-hook
735 'fast-lock-after-fontify-buffer)) 792 'fast-lock-after-fontify-buffer))
736 793
794 (unless (boundp 'font-lock-syntactic-keywords)
795 (defvar font-lock-syntactic-keywords nil))
796
737 (unless (boundp 'font-lock-inhibit-thing-lock) 797 (unless (boundp 'font-lock-inhibit-thing-lock)
738 (defvar font-lock-inhibit-thing-lock nil 798 (defvar font-lock-inhibit-thing-lock nil))
739 "List of Font Lock mode related modes that should not be turned on.")) 799
800 (unless (fboundp 'font-lock-compile-keywords)
801 (defalias 'font-lock-compile-keywords 'identity))
802
803 (unless (fboundp 'font-lock-eval-keywords)
804 (defun font-lock-eval-keywords (keywords)
805 (if (symbolp keywords)
806 (font-lock-eval-keywords (if (fboundp keywords)
807 (funcall keywords)
808 (eval keywords)))
809 keywords)))
740 810
741 (unless (fboundp 'font-lock-value-in-major-mode) 811 (unless (fboundp 'font-lock-value-in-major-mode)
742 (defun font-lock-value-in-major-mode (alist) 812 (defun font-lock-value-in-major-mode (alist)
743 ;; Return value in ALIST for `major-mode'.
744 (if (consp alist) 813 (if (consp alist)
745 (cdr (or (assq major-mode alist) (assq t alist))) 814 (cdr (or (assq major-mode alist) (assq t alist)))
746 alist))) 815 alist)))
747
748 (unless (fboundp 'font-lock-compile-keywords)
749 (defalias 'font-lock-compile-keywords 'identity))
750 816
751 ;; Install ourselves: 817 ;; Install ourselves:
752 818
753 (add-hook 'after-save-hook 'fast-lock-save-cache-after-save-file) 819 (add-hook 'after-save-hook 'fast-lock-save-cache-after-save-file)
754 (add-hook 'kill-buffer-hook 'fast-lock-save-cache-before-kill-buffer) 820 (add-hook 'kill-buffer-hook 'fast-lock-save-cache-before-kill-buffer)