aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Olson2008-06-06 16:14:49 +0000
committerMichael Olson2008-06-06 16:14:49 +0000
commite8ec402f1b86a1ed2c61bbc7de27aaefa2adb496 (patch)
tree5f38efb237d6a61a93748ebee3028643e2fb49b9
parent0a3a94b3d28f55ceb4d443da17c00c9bda83eb4a (diff)
downloademacs-e8ec402f1b86a1ed2c61bbc7de27aaefa2adb496.tar.gz
emacs-e8ec402f1b86a1ed2c61bbc7de27aaefa2adb496.zip
nXML: Use font lock
-rw-r--r--lisp/nxml/nxml-mode.el312
-rw-r--r--lisp/nxml/nxml-rap.el24
-rw-r--r--lisp/nxml/nxml-util.el40
3 files changed, 217 insertions, 159 deletions
diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el
index b1c6194cfa3..cb13d588c04 100644
--- a/lisp/nxml/nxml-mode.el
+++ b/lisp/nxml/nxml-mode.el
@@ -24,11 +24,6 @@
24 24
25;; See nxml-rap.el for description of parsing strategy. 25;; See nxml-rap.el for description of parsing strategy.
26 26
27;; The font locking here is independent of font-lock.el. We want to
28;; do more sophisticated handling of changes and we want to use the
29;; same xmltok rather than regexps for parsing so that we parse
30;; consistently and correctly.
31
32;;; Code: 27;;; Code:
33 28
34(when (featurep 'mucs) 29(when (featurep 'mucs)
@@ -56,11 +51,6 @@
56 :group 'nxml 51 :group 'nxml
57 :group 'font-lock-faces) 52 :group 'font-lock-faces)
58 53
59(defcustom nxml-syntax-highlight-flag t
60 "*Non-nil means nxml-mode should perform syntax highlighting."
61 :group 'nxml
62 :type 'boolean)
63
64(defcustom nxml-char-ref-display-glyph-flag t 54(defcustom nxml-char-ref-display-glyph-flag t
65 "*Non-nil means display glyph following character reference. 55 "*Non-nil means display glyph following character reference.
66The glyph is displayed in face `nxml-glyph'. The hook 56The glyph is displayed in face `nxml-glyph'. The hook
@@ -100,8 +90,6 @@ attribute on the previous line."
100 :group 'nxml 90 :group 'nxml
101 :type 'integer) 91 :type 'integer)
102 92
103(defvar nxml-fontify-chunk-size 500)
104
105(defcustom nxml-bind-meta-tab-to-complete-flag (not window-system) 93(defcustom nxml-bind-meta-tab-to-complete-flag (not window-system)
106 "*Non-nil means bind M-TAB in `nxml-mode-map' to `nxml-complete'. 94 "*Non-nil means bind M-TAB in `nxml-mode-map' to `nxml-complete'.
107C-return will be bound to `nxml-complete' in any case. 95C-return will be bound to `nxml-complete' in any case.
@@ -432,19 +420,13 @@ reference.")
432 map) 420 map)
433 "Keymap for nxml-mode.") 421 "Keymap for nxml-mode.")
434 422
423(defvar nxml-font-lock-keywords
424 '(nxml-fontify-matcher)
425 "Default font lock keywords for nxml-mode.")
426
435(defsubst nxml-set-face (start end face) 427(defsubst nxml-set-face (start end face)
436 (when (and face (< start end)) 428 (when (and face (< start end))
437 (put-text-property start end 'face face))) 429 (font-lock-append-text-property start end 'face face)))
438
439(defun nxml-clear-face (start end)
440 (remove-text-properties start end '(face nil))
441 (nxml-clear-char-ref-extra-display start end))
442
443(defsubst nxml-set-fontified (start end)
444 (put-text-property start end 'fontified t))
445
446(defsubst nxml-clear-fontified (start end)
447 (remove-text-properties start end '(fontified nil)))
448 430
449;;;###autoload 431;;;###autoload
450(defun nxml-mode () 432(defun nxml-mode ()
@@ -453,9 +435,6 @@ reference.")
453 ;; not mnemonic. 435 ;; not mnemonic.
454 "Major mode for editing XML. 436 "Major mode for editing XML.
455 437
456Syntax highlighting is performed unless the variable
457`nxml-syntax-highlight-flag' is nil.
458
459\\[nxml-finish-element] finishes the current element by inserting an end-tag. 438\\[nxml-finish-element] finishes the current element by inserting an end-tag.
460C-c C-i closes a start-tag with `>' and then inserts a balancing end-tag 439C-c C-i closes a start-tag with `>' and then inserts a balancing end-tag
461leaving point between the start-tag and end-tag. 440leaving point between the start-tag and end-tag.
@@ -540,13 +519,9 @@ Many aspects this mode can be customized using
540 (nxml-clear-dependent-regions (point-min) (point-max)) 519 (nxml-clear-dependent-regions (point-min) (point-max))
541 (setq nxml-scan-end (copy-marker (point-min) nil)) 520 (setq nxml-scan-end (copy-marker (point-min) nil))
542 (nxml-with-unmodifying-text-property-changes 521 (nxml-with-unmodifying-text-property-changes
543 (when nxml-syntax-highlight-flag 522 (nxml-clear-inside (point-min) (point-max))
544 (nxml-clear-fontified (point-min) (point-max)))
545 (nxml-clear-inside (point-min) (point-max))
546 (nxml-with-invisible-motion 523 (nxml-with-invisible-motion
547 (nxml-scan-prolog))))) 524 (nxml-scan-prolog)))))
548 (when nxml-syntax-highlight-flag
549 (add-hook 'fontification-functions 'nxml-fontify nil t))
550 (add-hook 'after-change-functions 'nxml-after-change nil t) 525 (add-hook 'after-change-functions 'nxml-after-change nil t)
551 (add-hook 'change-major-mode-hook 'nxml-cleanup nil t) 526 (add-hook 'change-major-mode-hook 'nxml-cleanup nil t)
552 527
@@ -561,6 +536,19 @@ Many aspects this mode can be customized using
561 (setq buffer-file-coding-system nxml-default-buffer-file-coding-system)) 536 (setq buffer-file-coding-system nxml-default-buffer-file-coding-system))
562 (when nxml-auto-insert-xml-declaration-flag 537 (when nxml-auto-insert-xml-declaration-flag
563 (nxml-insert-xml-declaration))) 538 (nxml-insert-xml-declaration)))
539
540 (setq font-lock-defaults
541 '(nxml-font-lock-keywords
542 t ; keywords-only; we highlight comments and strings here
543 nil ; font-lock-keywords-case-fold-search. XML is case sensitive
544 nil ; no special syntax table
545 nil ; no automatic syntactic fontification
546 (font-lock-extend-after-change-region-function
547 . nxml-extend-after-change-region)
548 (font-lock-extend-region-functions . (nxml-extend-region))
549 (jit-lock-contextually . t)
550 (font-lock-unfontify-region-function . nxml-unfontify-region)))
551
564 (rng-nxml-mode-init) 552 (rng-nxml-mode-init)
565 (nxml-enable-unicode-char-name-sets) 553 (nxml-enable-unicode-char-name-sets)
566 (run-hooks 'nxml-mode-hook)) 554 (run-hooks 'nxml-mode-hook))
@@ -591,84 +579,73 @@ Many aspects this mode can be customized using
591 (save-restriction 579 (save-restriction
592 (widen) 580 (widen)
593 (nxml-with-unmodifying-text-property-changes 581 (nxml-with-unmodifying-text-property-changes
594 (nxml-clear-face (point-min) (point-max))
595 (nxml-set-fontified (point-min) (point-max))
596 (nxml-clear-inside (point-min) (point-max)))))) 582 (nxml-clear-inside (point-min) (point-max))))))
597 583
598;;; Change management 584;;; Change management
599 585
586(defun nxml-debug-region (start end)
587 (interactive "r")
588 (let ((font-lock-beg start)
589 (font-lock-end end))
590 (nxml-extend-region)
591 (goto-char font-lock-beg)
592 (set-mark font-lock-end)))
593
600(defun nxml-after-change (start end pre-change-length) 594(defun nxml-after-change (start end pre-change-length)
601 ;; Work around bug in insert-file-contents. 595 ; In font-lock mode, nxml-after-change1 is called via
602 (when (> end (1+ (buffer-size))) 596 ; nxml-extend-after-change-region instead so that the updated
603 (setq start 1) 597 ; book-keeping information is available for fontification.
604 (setq end (1+ (buffer-size)))) 598 (unless (or font-lock-mode nxml-degraded)
605 (unless nxml-degraded 599 (nxml-with-degradation-on-error 'nxml-after-change
606 (condition-case err 600 (save-excursion
607 (save-excursion 601 (save-restriction
608 (save-restriction 602 (widen)
609 (widen) 603 (save-match-data
610 (save-match-data 604 (nxml-with-invisible-motion
611 (nxml-with-invisible-motion 605 (nxml-with-unmodifying-text-property-changes
612 (nxml-with-unmodifying-text-property-changes 606 (nxml-after-change1
613 (nxml-after-change1 start end pre-change-length)))))) 607 start end pre-change-length)))))))))
614 (error
615 (nxml-degrade 'nxml-after-change err)))))
616 608
617(defun nxml-after-change1 (start end pre-change-length) 609(defun nxml-after-change1 (start end pre-change-length)
618 (setq nxml-last-fontify-end nil) 610 "After-change bookkeeping. Returns a cons cell containing a
611possibly-enlarged change region. You must call
612nxml-extend-region on this expanded region to obtain the full
613extent of the area needing refontification.
614
615For bookkeeping, call this function even when fontification is
616disabled."
619 (let ((pre-change-end (+ start pre-change-length))) 617 (let ((pre-change-end (+ start pre-change-length)))
620 (setq start 618 (setq start
621 (nxml-adjust-start-for-dependent-regions start 619 (nxml-adjust-start-for-dependent-regions start
622 end 620 end
623 pre-change-length)) 621 pre-change-length))
622 ;; If the prolog might have changed, rescan the prolog
624 (when (<= start 623 (when (<= start
625 ;; Add 2 so as to include the < and following char 624 ;; Add 2 so as to include the < and following char that
626 ;; that start the instance, since changing these 625 ;; start the instance (document element), since changing
627 ;; can change where the prolog ends. 626 ;; these can change where the prolog ends.
628 (+ nxml-prolog-end 2)) 627 (+ nxml-prolog-end 2))
629 ;; end must be extended to at least the end of the old prolog 628 ;; end must be extended to at least the end of the old prolog in
629 ;; case the new prolog is shorter
630 (when (< pre-change-end nxml-prolog-end) 630 (when (< pre-change-end nxml-prolog-end)
631 (setq end 631 (setq end
632 ;; don't let end get out of range even if pre-change-length 632 ;; don't let end get out of range even if pre-change-length
633 ;; is bogus 633 ;; is bogus
634 (min (point-max) 634 (min (point-max)
635 (+ end (- nxml-prolog-end pre-change-end))))) 635 (+ end (- nxml-prolog-end pre-change-end)))))
636 (nxml-scan-prolog))) 636 (nxml-scan-prolog)
637 (cond ((<= end nxml-prolog-end) 637 (setq start (point-min))))
638 (setq end nxml-prolog-end) 638
639 (goto-char start) 639 (when (> end nxml-prolog-end)
640 ;; This is so that Emacs redisplay works 640 (goto-char start)
641 (setq start (line-beginning-position))) 641 (nxml-move-tag-backwards (point-min))
642 ((and (<= start nxml-scan-end) 642 (setq start (point))
643 (> start (point-min)) 643 (setq end (max (nxml-scan-after-change start end)
644 (nxml-get-inside (1- start))) 644 end)))
645 ;; The closing delimiter might have been removed. 645
646 ;; So we may need to redisplay from the beginning 646 (nxml-debug-change "nxml-after-change1" start end)
647 ;; of the token. 647 (cons start end))
648 (goto-char (1- start)) 648
649 (nxml-move-outside-backwards)
650 ;; This is so that Emacs redisplay works
651 (setq start (line-beginning-position))
652 (setq end (max (nxml-scan-after-change (point) end)
653 end)))
654 (t
655 (goto-char start)
656 ;; This is both for redisplay and to move back
657 ;; past any incomplete opening delimiters
658 (setq start (line-beginning-position))
659 (setq end (max (nxml-scan-after-change start end)
660 end))))
661 (when nxml-syntax-highlight-flag
662 (when (>= start end)
663 ;; Must clear at least one char so as to trigger redisplay.
664 (cond ((< start (point-max))
665 (setq end (1+ start)))
666 (t
667 (setq end (point-max))
668 (goto-char end)
669 (setq start (line-beginning-position)))))
670 (nxml-clear-fontified start end)))
671
672;;; Encodings 649;;; Encodings
673 650
674(defun nxml-insert-xml-declaration () 651(defun nxml-insert-xml-declaration ()
@@ -854,51 +831,98 @@ The XML declaration will declare an encoding depending on the buffer's
854 831
855;;; Fontification 832;;; Fontification
856 833
857(defun nxml-fontify (start) 834(defun nxml-unfontify-region (start end)
858 (condition-case err 835 (font-lock-default-unfontify-region start end)
859 (save-excursion 836 (nxml-clear-char-ref-extra-display start end))
860 (save-restriction 837
861 (widen) 838(defvar font-lock-beg) (defvar font-lock-end)
862 (save-match-data 839(defun nxml-extend-region ()
863 (nxml-with-invisible-motion 840 "Extend the region to hold the minimum area we can fontify with nXML.
864 (nxml-with-unmodifying-text-property-changes 841Called with font-lock-beg and font-lock-end dynamically bound."
865 (if (or nxml-degraded 842 (let ((start font-lock-beg)
866 ;; just in case we get called in the wrong buffer 843 (end font-lock-end))
867 (not nxml-prolog-end)) 844
868 (nxml-set-fontified start (point-max)) 845 (nxml-debug-change "nxml-extend-region(input)" start end)
869 (nxml-fontify1 start))))))) 846
870 (error 847 (when (< start nxml-prolog-end)
871 (nxml-degrade 'nxml-fontify err)))) 848 (setq start (point-min)))
872 849
873(defun nxml-fontify1 (start) 850 (cond ((<= end nxml-prolog-end)
874 (cond ((< start nxml-prolog-end) 851 (setq end nxml-prolog-end))
875 (nxml-fontify-prolog) 852
876 (nxml-set-fontified (point-min) 853 (t
877 nxml-prolog-end)) 854 (goto-char start)
878 (t 855 ;; some font-lock backends (like Emacs 22 jit-lock) snap
879 (goto-char start) 856 ;; the region to the beginning of the line no matter what
880 (when (not (eq nxml-last-fontify-end start)) 857 ;; we say here. To mitigate the resulting excess
881 (when (not (equal (char-after) ?\<)) 858 ;; fontification, ignore leading whitespace.
882 (search-backward "<" nxml-prolog-end t)) 859 (skip-syntax-forward " ")
883 (nxml-ensure-scan-up-to-date) 860
884 (nxml-move-outside-backwards)) 861 ;; find the beginning of the previous tag
885 (let ((start (point))) 862 (when (not (equal (char-after) ?\<))
886 (nxml-do-fontify (min (point-max) 863 (search-backward "<" nxml-prolog-end t))
887 (+ start nxml-fontify-chunk-size))) 864 (nxml-ensure-scan-up-to-date)
888 (setq nxml-last-fontify-end (point)) 865 (nxml-move-outside-backwards)
889 (nxml-set-fontified start nxml-last-fontify-end))))) 866 (setq start (point))
890 867
891(defun nxml-fontify-buffer () 868 (while (< (point) end)
892 (interactive) 869 (nxml-tokenize-forward))
893 (save-excursion 870
894 (save-restriction 871 (setq end (point))))
895 (widen) 872
896 (nxml-with-invisible-motion 873 (when (or (< start font-lock-beg)
897 (goto-char (point-min)) 874 (> end font-lock-end))
898 (nxml-with-unmodifying-text-property-changes 875 (setq font-lock-beg start
899 (nxml-fontify-prolog) 876 font-lock-end end)
900 (goto-char nxml-prolog-end) 877 (nxml-debug-change "nxml-extend-region" start end)
901 (nxml-do-fontify)))))) 878 t)))
879
880(defun nxml-extend-after-change-region (start end pre-change-length)
881 (unless nxml-degraded
882 (setq nxml-last-fontify-end nil)
883
884 (nxml-with-degradation-on-error 'nxml-extend-after-change-region
885 (save-excursion
886 (save-restriction
887 (widen)
888 (save-match-data
889 (nxml-with-invisible-motion
890 (nxml-with-unmodifying-text-property-changes
891 (nxml-extend-after-change-region1
892 start end pre-change-length)))))))))
893
894(defun nxml-extend-after-change-region1 (start end pre-change-length)
895 (let* ((region (nxml-after-change1 start end pre-change-length))
896 (font-lock-beg (car region))
897 (font-lock-end (cdr region)))
898
899 (nxml-extend-region)
900 (cons font-lock-beg font-lock-end)))
901
902(defun nxml-fontify-matcher (bound)
903 "Called as font-lock keyword matcher."
904
905 (unless nxml-degraded
906 (nxml-debug-change "nxml-fontify-matcher" (point) bound)
907
908 (when (< (point) nxml-prolog-end)
909 ;; prolog needs to be fontified in one go, and
910 ;; nxml-extend-region makes sure we start at BOB.
911 (assert (bobp))
912 (nxml-fontify-prolog)
913 (goto-char nxml-prolog-end))
914
915 (let (xmltok-dependent-regions
916 xmltok-errors)
917 (while (and (nxml-tokenize-forward)
918 (<= (point) bound)) ; intervals are open-ended
919 (nxml-apply-fontify-rule)))
920
921 (setq nxml-last-fontify-end (point)))
922
923 ;; Since we did the fontification internally, tell font-lock to not
924 ;; do anything itself.
925 nil)
902 926
903(defun nxml-fontify-prolog () 927(defun nxml-fontify-prolog ()
904 "Fontify the prolog. 928 "Fontify the prolog.
@@ -906,7 +930,6 @@ The buffer is assumed to be prepared for fontification.
906This does not set the fontified property, but it does clear 930This does not set the fontified property, but it does clear
907faces appropriately." 931faces appropriately."
908 (let ((regions nxml-prolog-regions)) 932 (let ((regions nxml-prolog-regions))
909 (nxml-clear-face (point-min) nxml-prolog-end)
910 (while regions 933 (while regions
911 (let ((region (car regions))) 934 (let ((region (car regions)))
912 (nxml-apply-fontify-rule (aref region 0) 935 (nxml-apply-fontify-rule (aref region 0)
@@ -914,17 +937,6 @@ faces appropriately."
914 (aref region 2))) 937 (aref region 2)))
915 (setq regions (cdr regions))))) 938 (setq regions (cdr regions)))))
916 939
917(defun nxml-do-fontify (&optional bound)
918 "Fontify at least as far as bound.
919Leave point after last fontified position."
920 (unless bound (setq bound (point-max)))
921 (let (xmltok-dependent-regions
922 xmltok-errors)
923 (while (and (< (point) bound)
924 (nxml-tokenize-forward))
925 (nxml-clear-face xmltok-start (point))
926 (nxml-apply-fontify-rule))))
927
928;; Vectors identify a substring of the token to be highlighted in some face. 940;; Vectors identify a substring of the token to be highlighted in some face.
929 941
930;; Token types returned by xmltok-forward. 942;; Token types returned by xmltok-forward.
@@ -2574,13 +2586,7 @@ With a prefix argument, inserts the character directly."
2574 (> (prefix-numeric-value arg) 0)))) 2586 (> (prefix-numeric-value arg) 0))))
2575 (when (not (eq new nxml-char-ref-extra-display)) 2587 (when (not (eq new nxml-char-ref-extra-display))
2576 (setq nxml-char-ref-extra-display new) 2588 (setq nxml-char-ref-extra-display new)
2577 (save-excursion 2589 (font-lock-fontify-buffer))))
2578 (save-restriction
2579 (widen)
2580 (if nxml-char-ref-extra-display
2581 (nxml-with-unmodifying-text-property-changes
2582 (nxml-clear-fontified (point-min) (point-max)))
2583 (nxml-clear-char-ref-extra-display (point-min) (point-max))))))))
2584 2590
2585(put 'nxml-char-ref 'evaporate t) 2591(put 'nxml-char-ref 'evaporate t)
2586 2592
diff --git a/lisp/nxml/nxml-rap.el b/lisp/nxml/nxml-rap.el
index 47ef53bbcbe..7d6078f1119 100644
--- a/lisp/nxml/nxml-rap.el
+++ b/lisp/nxml/nxml-rap.el
@@ -110,9 +110,11 @@ There must be no nxml-inside properties after nxml-scan-end.")
110 (get-text-property pos 'nxml-inside)) 110 (get-text-property pos 'nxml-inside))
111 111
112(defsubst nxml-clear-inside (start end) 112(defsubst nxml-clear-inside (start end)
113 (nxml-debug-clear-inside start end)
113 (remove-text-properties start end '(nxml-inside nil))) 114 (remove-text-properties start end '(nxml-inside nil)))
114 115
115(defsubst nxml-set-inside (start end type) 116(defsubst nxml-set-inside (start end type)
117 (nxml-debug-set-inside start end)
116 (put-text-property start end 'nxml-inside type)) 118 (put-text-property start end 'nxml-inside type))
117 119
118(defun nxml-inside-end (pos) 120(defun nxml-inside-end (pos)
@@ -137,12 +139,10 @@ Return nil if the character at POS is not inside."
137 "Restore `nxml-scan-end' invariants after a change. 139 "Restore `nxml-scan-end' invariants after a change.
138The change happened between START and END. 140The change happened between START and END.
139Return position after which lexical state is unchanged. 141Return position after which lexical state is unchanged.
140END must be > nxml-prolog-end." 142END must be > nxml-prolog-end. START must be outside
143any 'inside' regions and at the beginning of a token."
141 (if (>= start nxml-scan-end) 144 (if (>= start nxml-scan-end)
142 nxml-scan-end 145 nxml-scan-end
143 (goto-char start)
144 (nxml-move-outside-backwards)
145 (setq start (point))
146 (let ((inside-remove-start start) 146 (let ((inside-remove-start start)
147 xmltok-errors 147 xmltok-errors
148 xmltok-dependent-regions) 148 xmltok-dependent-regions)
@@ -214,7 +214,7 @@ END must be > nxml-prolog-end."
214 (setq adjusted-start ostart))))) 214 (setq adjusted-start ostart)))))
215 (setq overlays (cdr overlays))) 215 (setq overlays (cdr overlays)))
216 adjusted-start)) 216 adjusted-start))
217 217
218(defun nxml-mark-parse-dependent-regions () 218(defun nxml-mark-parse-dependent-regions ()
219 (while xmltok-dependent-regions 219 (while xmltok-dependent-regions
220 (apply 'nxml-mark-parse-dependent-region 220 (apply 'nxml-mark-parse-dependent-region
@@ -300,6 +300,20 @@ Sets variables like `nxml-token-after'."
300 (set-marker nxml-scan-end (point))) 300 (set-marker nxml-scan-end (point)))
301 xmltok-type)) 301 xmltok-type))
302 302
303(defun nxml-move-tag-backwards (bound)
304 "Move point backwards outside any 'inside' regions or tags, up
305to nxml-prolog-end. Point will either be at bound or a '<'
306character starting a tag outside any 'inside' regions. Ignores
307dependent regions. As a precondition, point must be >= bound."
308 (nxml-move-outside-backwards)
309 (when (not (equal (char-after) ?<))
310 (if (search-backward "<" bound t)
311 (progn
312 (nxml-move-outside-backwards)
313 (when (not (equal (char-after) ?<))
314 (search-backward "<" bound t)))
315 (goto-char bound))))
316
303(defun nxml-move-outside-backwards () 317(defun nxml-move-outside-backwards ()
304 "Move point to first character of the containing special thing. 318 "Move point to first character of the containing special thing.
305Leave point unmoved if it is not inside anything special." 319Leave point unmoved if it is not inside anything special."
diff --git a/lisp/nxml/nxml-util.el b/lisp/nxml/nxml-util.el
index 3aab1ee6b8c..2e90dfc32dc 100644
--- a/lisp/nxml/nxml-util.el
+++ b/lisp/nxml/nxml-util.el
@@ -24,6 +24,35 @@
24 24
25;;; Code: 25;;; Code:
26 26
27(defconst nxml-debug nil
28 "enable nxml debugging. effective only at compile time")
29
30(eval-when-compile
31 (require 'cl))
32
33(defsubst nxml-debug (format &rest args)
34 (when nxml-debug
35 (apply #'message format args)))
36
37(defmacro nxml-debug-change (name start end)
38 (when nxml-debug
39 `(nxml-debug "%s: %S" ,name
40 (buffer-substring-no-properties ,start ,end))))
41
42(defmacro nxml-debug-set-inside (start end)
43 (when nxml-debug
44 `(let ((overlay (make-overlay ,start ,end)))
45 (overlay-put overlay 'face '(:background "red"))
46 (overlay-put overlay 'nxml-inside-debug t)
47 (nxml-debug-change "nxml-set-inside" ,start ,end))))
48
49(defmacro nxml-debug-clear-inside (start end)
50 (when nxml-debug
51 `(loop for overlay in (overlays-in ,start ,end)
52 if (overlay-get overlay 'nxml-inside-debug)
53 do (delete-overlay overlay)
54 finally (nxml-debug-change "nxml-clear-inside" ,start ,end))))
55
27(defun nxml-make-namespace (str) 56(defun nxml-make-namespace (str)
28 "Return a symbol for the namespace URI STR. 57 "Return a symbol for the namespace URI STR.
29STR must be a string. If STR is the empty string, return nil. 58STR must be a string. If STR is the empty string, return nil.
@@ -37,12 +66,21 @@ Otherwise, return the symbol whose name is STR prefixed with a colon."
37This is the inverse of `nxml-make-namespace'." 66This is the inverse of `nxml-make-namespace'."
38 (and ns (substring (symbol-name ns) 1))) 67 (and ns (substring (symbol-name ns) 1)))
39 68
40(defconst nxml-xml-namespace-uri 69(defconst nxml-xml-namespace-uri
41 (nxml-make-namespace "http://www.w3.org/XML/1998/namespace")) 70 (nxml-make-namespace "http://www.w3.org/XML/1998/namespace"))
42 71
43(defconst nxml-xmlns-namespace-uri 72(defconst nxml-xmlns-namespace-uri
44 (nxml-make-namespace "http://www.w3.org/2000/xmlns/")) 73 (nxml-make-namespace "http://www.w3.org/2000/xmlns/"))
45 74
75(defmacro nxml-with-degradation-on-error (context &rest body)
76 (if (not nxml-debug)
77 (let ((error-symbol (make-symbol "err")))
78 `(condition-case ,error-symbol
79 (progn ,@body)
80 (error
81 (nxml-degrade ,context ,error-symbol))))
82 `(progn ,@body)))
83
46(defmacro nxml-with-unmodifying-text-property-changes (&rest body) 84(defmacro nxml-with-unmodifying-text-property-changes (&rest body)
47 "Evaluate BODY without any text property changes modifying the buffer. 85 "Evaluate BODY without any text property changes modifying the buffer.
48Any text properties changes happen as usual but the changes are not treated as 86Any text properties changes happen as usual but the changes are not treated as