Mercurial > emacs
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) |