;;; nxml-mode.el --- a new XML mode
-;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+;; Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: James Clark
;; Keywords: XML
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 2 of
-;; the License, or (at your option) any later version.
+;; This file is part of GNU Emacs.
-;; This program is distributed in the hope that it will be
-;; useful, but WITHOUT ANY WARRANTY; without even the implied
-;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-;; PURPOSE. See the GNU General Public License for more details.
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
-;; You should have received a copy of the GNU General Public
-;; License along with this program; if not, write to the Free
-;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-;; MA 02111-1307 USA
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
-;;; Commentary:
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
-;; To use this include rng-auto.el in your .emacs.
+;;; Commentary:
;; See nxml-rap.el for description of parsing strategy.
-;; The font locking here is independent of font-lock.el. We want to
-;; do more sophisticated handling of changes and we want to use the
-;; same xmltok rather than regexps for parsing so that we parse
-;; consistently and correctly.
-
;;; Code:
(when (featurep 'mucs)
(error "nxml-mode is not compatible with Mule-UCS"))
+(eval-when-compile (require 'cl)) ; for assert
+
(require 'xmltok)
(require 'nxml-enc)
(require 'nxml-glyph)
(require 'nxml-rap)
(require 'nxml-outln)
+(declare-function rng-nxml-mode-init "rng-nxml")
+(declare-function nxml-enable-unicode-char-name-sets "nxml-uchnm")
+
;;; Customization
(defgroup nxml nil
- "New XML editing mode"
- :group 'languages
- :group 'wp)
+ "New XML editing mode."
+ :group 'languages)
-(defgroup nxml-highlighting-faces nil
+(defgroup nxml-faces nil
"Faces for XML syntax highlighting."
- :group 'nxml
- :group 'font-lock-highlighting-faces)
-
-(defcustom nxml-syntax-highlight-flag t
- "*Non-nil means nxml-mode should perform syntax highlighting."
- :group 'nxml
- :type 'boolean)
+ :group 'nxml)
(defcustom nxml-char-ref-display-glyph-flag t
"*Non-nil means display glyph following character reference.
-The glyph is displayed in `nxml-glyph-face'. The hook
+The glyph is displayed in face `nxml-glyph'. The hook
`nxml-glyph-set-hook' can be used to customize for which characters
glyphs are displayed."
:group 'nxml
(defcustom nxml-attribute-indent 4
"*Indentation for the attributes of an element relative to the start-tag.
-This only applies when the first attribute of a tag starts a line. In other
-cases, the first attribute on one line is indented the same as the first
-attribute on the previous line."
+This only applies when the first attribute of a tag starts a line.
+In other cases, the first attribute on one line is indented the same
+as the first attribute on the previous line."
:group 'nxml
:type 'integer)
-(defvar nxml-fontify-chunk-size 500)
-
(defcustom nxml-bind-meta-tab-to-complete-flag (not window-system)
"*Non-nil means bind M-TAB in `nxml-mode-map' to `nxml-complete'.
C-return will be bound to `nxml-complete' in any case.
M-TAB gets swallowed by many window systems/managers, and
`documentation' will show M-TAB rather than C-return as the
-binding `rng-complete' when both are bound. So it's better
+binding for `nxml-complete' when both are bound. So it's better
to bind M-TAB only when it will work."
:group 'nxml
:set (lambda (sym flag)
(defcustom nxml-default-buffer-file-coding-system nil
"*Default value for `buffer-file-coding-system' for a buffer for a new file.
-Nil means use the default value of `buffer-file-coding-system' as normal.
+A value of nil means use the default value of `buffer-file-coding-system' as normal.
A buffer's `buffer-file-coding-system' affects what \\[nxml-insert-xml-declaration] inserts."
:group 'nxml
:type 'coding-system)
:group 'nxml
:type 'boolean)
-;; The following are the colors we use with a light background.
-;; The two blues have the same hue but contrasting saturation/value.
-;; The hue of the green is 120 degrees different from that of the
-;; blue. The red used for highlighting errors is 120 degrees
-;; different again. We use the light blue only for refs and
-;; delimiters, since these are short (long stretches in a light color
-;; would be too hard to read). The dark blue is closest to black
-;; (which we use by default for text), so we use it for attribute
-;; values, which are similar to text.
-
-(defconst nxml-light-blue-color "#9292C9") ; hue 240
-(defconst nxml-dark-blue-color "#3A3A7B") ; hue 240
-(defconst nxml-green-color "#257A25") ; hue 120
-
-;; Similar principles apply with a dark background. However,
-;; we switch green and blue, because darker blues are very hard to
-;; read (for me anyway) on a dark background.
-
-(defconst nxml-sky-blue-color "#ACACFC") ; hue 240
-(defconst nxml-dark-green-color "#00AD00") ; hue 120
-(defconst nxml-light-green-color "#70F170") ; hue 120
-
-(defface nxml-delimited-data-face
- `((((class color) (background light)) (:foreground ,nxml-dark-blue-color))
- (((class color) (background dark)) (:foreground ,nxml-light-green-color)))
+(defface nxml-delimited-data
+ '((t (:inherit font-lock-doc-face)))
"Face used to highlight data enclosed between delimiters.
-By default, this is inherited by `nxml-attribute-value-face'
-and `nxml-processing-instruction-content-face'."
- :group 'nxml-highlighting-faces)
+This is not used directly, but only via inheritance by other faces."
+ :group 'nxml-faces)
-(defface nxml-name-face
- `((((class color) (background light)) (:foreground ,nxml-green-color))
- (((class color) (background dark)) (:foreground ,nxml-sky-blue-color)))
+(defface nxml-name
+ '((t (:inherit font-lock-builtin-face)))
"Face used to highlight various names.
This includes element and attribute names, processing
instruction targets and the CDATA keyword in a CDATA section.
This is not used directly, but only via inheritance by other faces."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-ref-face
- `((((class color) (background light)) (:foreground ,nxml-light-blue-color))
- (((class color) (background dark)) (:foreground ,nxml-dark-green-color)))
+(defface nxml-ref
+ '((t (:inherit font-lock-constant-face)))
"Face used to highlight character and entity references.
This is not used directly, but only via inheritance by other faces."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-delimiter-face
- `((((class color) (background light)) (:foreground ,nxml-light-blue-color))
- (((class color) (background dark)) (:foreground ,nxml-dark-green-color))
- (t (:bold t)))
+(defface nxml-delimiter
+ nil
"Face used to highlight delimiters.
This is not used directly, but only via inheritance by other faces."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-text-face
+(defface nxml-text
nil
"Face used to highlight text."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-comment-content-face
- '((t (:italic t)))
+(defface nxml-comment-content
+ '((t (:inherit font-lock-comment-face)))
"Face used to highlight the content of comments."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-comment-delimiter-face
- '((t (:inherit nxml-delimiter-face)))
+(defface nxml-comment-delimiter
+ '((t (:inherit font-lock-comment-delimiter-face)))
"Face used for the delimiters of comments, i.e <!-- and -->."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-processing-instruction-delimiter-face
- '((t (:inherit nxml-delimiter-face)))
+(defface nxml-processing-instruction-delimiter
+ '((t (:inherit nxml-delimiter)))
"Face used for the delimiters of processing instructions, i.e <? and ?>."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-processing-instruction-target-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-processing-instruction-target
+ '((t (:inherit font-lock-keyword-face)))
"Face used for the target of processing instructions."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-processing-instruction-content-face
- '((t (:inherit nxml-delimited-data-face)))
+(defface nxml-processing-instruction-content
+ '((t (:inherit nxml-delimited-data)))
"Face used for the content of processing instructions."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-cdata-section-delimiter-face
- '((t (:inherit nxml-delimiter-face)))
+(defface nxml-cdata-section-delimiter
+ '((t (:inherit nxml-delimiter)))
"Face used for the delimiters of CDATA sections, i.e <![, [, and ]]>."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-cdata-section-CDATA-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-cdata-section-CDATA
+ '((t (:inherit nxml-name)))
"Face used for the CDATA keyword in CDATA sections."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-cdata-section-content-face
- '((t (:inherit nxml-text-face)))
+(defface nxml-cdata-section-content
+ '((t (:inherit nxml-text)))
"Face used for the content of CDATA sections."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-char-ref-number-face
- '((t (:inherit nxml-ref-face)))
+(defface nxml-char-ref-number
+ '((t (:inherit nxml-ref)))
"Face used for the number in character references.
This includes ths `x' in hex references."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-char-ref-delimiter-face
- '((t (:inherit nxml-ref-face)))
+(defface nxml-char-ref-delimiter
+ '((t (:inherit nxml-ref)))
"Face used for the delimiters of character references, i.e &# and ;."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-entity-ref-name-face
- '((t (:inherit nxml-ref-face)))
+(defface nxml-entity-ref-name
+ '((t (:inherit nxml-ref)))
"Face used for the entity name in general entity references."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-entity-ref-delimiter-face
- '((t (:inherit nxml-ref-face)))
+(defface nxml-entity-ref-delimiter
+ '((t (:inherit nxml-ref)))
"Face used for the delimiters of entity references, i.e & and ;."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-tag-delimiter-face
- '((t (:inherit nxml-delimiter-face)))
+(defface nxml-tag-delimiter
+ '((t (:inherit nxml-delimiter)))
"Face used for the angle brackets delimiting tags.
-`nxml-tag-slash-face' is used for slashes."
- :group 'nxml-highlighting-faces)
+`nxml-tag-slash' is used for slashes."
+ :group 'nxml-faces)
-(defface nxml-tag-slash-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-tag-slash
+ '((t (:inherit nxml-tag-delimiter)))
"Face used for slashes in tags, both in end-tags and empty-elements."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-element-prefix-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-element-prefix
+ '((t (:inherit nxml-name)))
"Face used for the prefix of elements."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-element-colon-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-element-colon
+ nil
"Face used for the colon in element names."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-element-local-name-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-element-local-name
+ '((t (:inherit font-lock-function-name-face)))
"Face used for the local name of elements."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-attribute-prefix-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-attribute-prefix
+ '((t (:inherit nxml-name)))
"Face used for the prefix of attributes."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-attribute-colon-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-attribute-colon
+ '((t (:inherit nxml-delimiter)))
"Face used for the colon in attribute names."
- :group 'nxml-highlighting-faces)
-
-(defface nxml-attribute-local-name-face
- '((t (:inherit nxml-name-face)))
+ :group 'nxml-faces)
+
+(defface nxml-attribute-local-name
+ '((t (:inherit font-lock-variable-name-face)))
"Face used for the local name of attributes."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-namespace-attribute-xmlns-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-namespace-attribute-xmlns
+ '((t (:inherit nxml-attribute-prefix)))
"Face used for `xmlns' in namespace attributes."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-namespace-attribute-colon-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-namespace-attribute-colon
+ '((t (:inherit nxml-attribute-colon)))
"Face used for the colon in namespace attributes."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-namespace-attribute-prefix-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-namespace-attribute-prefix
+ '((t (:inherit nxml-attribute-local-name)))
"Face used for the prefix declared in namespace attributes."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-attribute-value-face
- '((t (:inherit nxml-delimited-data-face)))
+(defface nxml-attribute-value
+ '((t (:inherit font-lock-string-face)))
"Face used for the value of attributes."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-attribute-value-delimiter-face
- '((t (:inherit nxml-delimiter-face)))
+(defface nxml-attribute-value-delimiter
+ '((t (:inherit nxml-attribute-value)))
"Face used for the delimiters of attribute values."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-namespace-attribute-value-face
- '((t (:inherit nxml-attribute-value-face)))
+(defface nxml-namespace-attribute-value
+ '((t (:inherit nxml-attribute-value)))
"Face used for the value of namespace attributes."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-namespace-attribute-value-delimiter-face
- '((t (:inherit nxml-attribute-value-delimiter-face)))
+(defface nxml-namespace-attribute-value-delimiter
+ '((t (:inherit nxml-attribute-value-delimiter)))
"Face used for the delimiters of namespace attribute values."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-prolog-literal-delimiter-face
- '((t (:inherit nxml-delimiter-face)))
+(defface nxml-prolog-literal-delimiter
+ '((t (:inherit nxml-delimited-data)))
"Face used for the delimiters of literals in the prolog."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-prolog-literal-content-face
- '((t (:inherit nxml-delimited-data-face)))
+(defface nxml-prolog-literal-content
+ '((t (:inherit nxml-delimited-data)))
"Face used for the content of literals in the prolog."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-prolog-keyword-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-prolog-keyword
+ '((t (:inherit font-lock-keyword-face)))
"Face used for keywords in the prolog."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-markup-declaration-delimiter-face
- '((t (:inherit nxml-delimiter-face)))
+(defface nxml-markup-declaration-delimiter
+ '((t (:inherit nxml-delimiter)))
"Face used for the delimiters of markup declarations in the prolog.
The delimiters are <! and >."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-hash-face
- '((t (:inherit nxml-name-face)))
+(defface nxml-hash
+ '((t (:inherit nxml-name)))
"Face used for # before a name in the prolog."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
-(defface nxml-glyph-face
+(defface nxml-glyph
'((((type x))
(:family
"misc-fixed"
:foreground
"black"
:weight
- normal
+ normal
:slant
normal))
(t
:foreground
"black"
:weight
- normal
+ normal
:slant
normal)))
"Face used for glyph for char references."
- :group 'nxml-highlighting-faces)
+ :group 'nxml-faces)
;;; Global variables
-;; This is initialized in rng-auto.el.
-(defvar nxml-version nil
- "*The version of nxml-mode that is being used.")
-
(defvar nxml-prolog-regions nil
"List of regions in the prolog to be fontified.
See the function `xmltok-forward-prolog' for more information.")
(defvar nxml-last-fontify-end nil
"Position where fontification last ended.
-Nil if the buffer changed since the last fontification.")
+It is nil if the buffer changed since the last fontification.")
(make-variable-buffer-local 'nxml-last-fontify-end)
(defvar nxml-degraded nil
(define-key map "\C-c\C-o" nxml-outline-prefix-map)
(define-key map [S-mouse-2] 'nxml-mouse-hide-direct-text-content)
(define-key map "/" 'nxml-electric-slash)
- (define-key map [C-return] 'nxml-complete)
+ (define-key map [C-return] 'nxml-complete)
(when nxml-bind-meta-tab-to-complete-flag
(define-key map "\M-\t" 'nxml-complete))
map)
"Keymap for nxml-mode.")
+(defvar nxml-font-lock-keywords
+ '(nxml-fontify-matcher)
+ "Default font lock keywords for nxml-mode.")
+
(defsubst nxml-set-face (start end face)
(when (and face (< start end))
- (put-text-property start end 'face face)))
-
-(defun nxml-clear-face (start end)
- (remove-text-properties start end '(face nil))
- (nxml-clear-char-ref-extra-display start end))
-
-(defsubst nxml-set-fontified (start end)
- (put-text-property start end 'fontified t))
-
-(defsubst nxml-clear-fontified (start end)
- (remove-text-properties start end '(fontified nil)))
+ (font-lock-append-text-property start end 'face face)))
;;;###autoload
(defun nxml-mode ()
;; not mnemonic.
"Major mode for editing XML.
-Syntax highlighting is performed unless the variable
-`nxml-syntax-highlight-flag' is nil.
-
\\[nxml-finish-element] finishes the current element by inserting an end-tag.
C-c C-i closes a start-tag with `>' and then inserts a balancing end-tag
-leaving point between the start-tag and end-tag.
+leaving point between the start-tag and end-tag.
\\[nxml-balanced-close-start-tag-block] is similar but for block rather than inline elements:
the start-tag, point, and end-tag are all left on separate lines.
If `nxml-slash-auto-complete-flag' is non-nil, then inserting a `</'
Validation is provided by the related minor-mode `rng-validate-mode'.
This also makes completion schema- and context- sensitive. Element
names, attribute names, attribute values and namespace URIs can all be
-completed. By default, `rng-validate-mode' is automatically enabled by
-`rng-nxml-mode-init' which is normally added to `nxml-mode-hook'. You
-can toggle it using \\[rng-validate-mode].
+completed. By default, `rng-validate-mode' is automatically enabled.
+You can toggle it using \\[rng-validate-mode] or change the default by
+customizing `rng-nxml-auto-validate-flag'.
\\[indent-for-tab-command] indents the current line appropriately.
This can be customized using the variable `nxml-child-indent'
and the variable `nxml-attribute-indent'.
\\[nxml-insert-named-char] inserts a character reference using
-the character's name (by default, the Unicode name). \\[universal-argument] \\[nxml-insert-named-char]
-inserts the character directly.
+the character's name (by default, the Unicode name).
+\\[universal-argument] \\[nxml-insert-named-char] inserts the character directly.
The Emacs commands that normally operate on balanced expressions will
operate on XML markup items. Thus \\[forward-sexp] will move forward
(kill-all-local-variables)
(setq major-mode 'nxml-mode)
(setq mode-name "nXML")
+ (set (make-local-variable 'mode-line-process) '((nxml-degraded "/degraded")))
;; We'll determine the fill prefix ourselves
(make-local-variable 'adaptive-fill-mode)
(setq adaptive-fill-mode nil)
(nxml-clear-dependent-regions (point-min) (point-max))
(setq nxml-scan-end (copy-marker (point-min) nil))
(nxml-with-unmodifying-text-property-changes
- (when nxml-syntax-highlight-flag
- (nxml-clear-fontified (point-min) (point-max)))
- (nxml-clear-inside (point-min) (point-max))
+ (nxml-clear-inside (point-min) (point-max))
(nxml-with-invisible-motion
(nxml-scan-prolog)))))
- (when nxml-syntax-highlight-flag
- (add-hook 'fontification-functions 'nxml-fontify nil t))
(add-hook 'after-change-functions 'nxml-after-change nil t)
- (add-hook 'write-contents-hooks 'nxml-prepare-to-save)
+ (add-hook 'change-major-mode-hook 'nxml-cleanup nil t)
+
+ ;; Emacs 23 handles the encoding attribute on the xml declaration
+ ;; transparently to nxml-mode, so there is no longer a need for the below
+ ;; hook. The hook also had the drawback of overriding explicit user
+ ;; instruction to save as some encoding other than utf-8.
+;;; (add-hook 'write-contents-hooks 'nxml-prepare-to-save)
(when (not (and (buffer-file-name) (file-exists-p (buffer-file-name))))
(when (and nxml-default-buffer-file-coding-system
(not (local-variable-p 'buffer-file-coding-system)))
(setq buffer-file-coding-system nxml-default-buffer-file-coding-system))
(when nxml-auto-insert-xml-declaration-flag
(nxml-insert-xml-declaration)))
- (run-hooks 'nxml-mode-hook))
+
+ (setq font-lock-defaults
+ '(nxml-font-lock-keywords
+ t ; keywords-only; we highlight comments and strings here
+ nil ; font-lock-keywords-case-fold-search. XML is case sensitive
+ nil ; no special syntax table
+ nil ; no automatic syntactic fontification
+ (font-lock-extend-after-change-region-function
+ . nxml-extend-after-change-region)
+ (font-lock-extend-region-functions . (nxml-extend-region))
+ (jit-lock-contextually . t)
+ (font-lock-unfontify-region-function . nxml-unfontify-region)))
+
+ (rng-nxml-mode-init)
+ (nxml-enable-unicode-char-name-sets)
+ (run-mode-hooks 'nxml-mode-hook))
+
+(defun nxml-cleanup ()
+ "Clean up after nxml-mode."
+ ;; Disable associated minor modes.
+ (rng-validate-mode -1)
+ ;; Clean up fontification.
+ (save-excursion
+ (widen)
+ (let ((inhibit-read-only t)
+ (buffer-undo-list t)
+ (modified (buffer-modified-p)))
+ (nxml-with-invisible-motion
+ (remove-text-properties (point-min) (point-max) '(face)))
+ (set-buffer-modified-p modified)))
+ (remove-hook 'change-major-mode-hook 'nxml-cleanup t))
(defun nxml-degrade (context err)
(message "Internal nXML mode error in %s (%s), degrading"
(save-restriction
(widen)
(nxml-with-unmodifying-text-property-changes
- (nxml-clear-face (point-min) (point-max))
- (nxml-set-fontified (point-min) (point-max))
- (nxml-clear-inside (point-min) (point-max)))
- (setq mode-name "nXML/degraded"))))
+ (nxml-clear-inside (point-min) (point-max))))))
;;; Change management
+(defun nxml-debug-region (start end)
+ (interactive "r")
+ (let ((font-lock-beg start)
+ (font-lock-end end))
+ (nxml-extend-region)
+ (goto-char font-lock-beg)
+ (set-mark font-lock-end)))
+
(defun nxml-after-change (start end pre-change-length)
- ;; Work around bug in insert-file-contents.
- (when (> end (1+ (buffer-size)))
- (setq start 1)
- (setq end (1+ (buffer-size))))
- (unless nxml-degraded
- (condition-case err
- (save-excursion
- (save-restriction
- (widen)
- (save-match-data
- (nxml-with-invisible-motion
- (nxml-with-unmodifying-text-property-changes
- (nxml-after-change1 start end pre-change-length))))))
- (error
- (nxml-degrade 'nxml-after-change err)))))
+ ; In font-lock mode, nxml-after-change1 is called via
+ ; nxml-extend-after-change-region instead so that the updated
+ ; book-keeping information is available for fontification.
+ (unless (or font-lock-mode nxml-degraded)
+ (nxml-with-degradation-on-error 'nxml-after-change
+ (save-excursion
+ (save-restriction
+ (widen)
+ (save-match-data
+ (nxml-with-invisible-motion
+ (nxml-with-unmodifying-text-property-changes
+ (nxml-after-change1
+ start end pre-change-length)))))))))
(defun nxml-after-change1 (start end pre-change-length)
- (setq nxml-last-fontify-end nil)
+ "After-change bookkeeping.
+Returns a cons cell containing a possibly-enlarged change region.
+You must call `nxml-extend-region' on this expanded region to obtain
+the full extent of the area needing refontification.
+
+For bookkeeping, call this function even when fontification is
+disabled."
(let ((pre-change-end (+ start pre-change-length)))
(setq start
(nxml-adjust-start-for-dependent-regions start
end
pre-change-length))
+ ;; If the prolog might have changed, rescan the prolog
(when (<= start
- ;; Add 2 so as to include the < and following char
- ;; that start the instance, since changing these
- ;; can change where the prolog ends.
+ ;; Add 2 so as to include the < and following char that
+ ;; start the instance (document element), since changing
+ ;; these can change where the prolog ends.
(+ nxml-prolog-end 2))
- ;; end must be extended to at least the end of the old prolog
+ ;; end must be extended to at least the end of the old prolog in
+ ;; case the new prolog is shorter
(when (< pre-change-end nxml-prolog-end)
(setq end
;; don't let end get out of range even if pre-change-length
;; is bogus
(min (point-max)
(+ end (- nxml-prolog-end pre-change-end)))))
- (nxml-scan-prolog)))
- (cond ((<= end nxml-prolog-end)
- (setq end nxml-prolog-end)
- (goto-char start)
- ;; This is so that Emacs redisplay works
- (setq start (line-beginning-position)))
- ((and (<= start nxml-scan-end)
- (> start (point-min))
- (nxml-get-inside (1- start)))
- ;; The closing delimiter might have been removed.
- ;; So we may need to redisplay from the beginning
- ;; of the token.
- (goto-char (1- start))
- (nxml-move-outside-backwards)
- ;; This is so that Emacs redisplay works
- (setq start (line-beginning-position))
- (setq end (max (nxml-scan-after-change (point) end)
- end)))
- (t
- (goto-char start)
- ;; This is both for redisplay and to move back
- ;; past any incomplete opening delimiters
- (setq start (line-beginning-position))
- (setq end (max (nxml-scan-after-change start end)
- end))))
- (when nxml-syntax-highlight-flag
- (when (>= start end)
- ;; Must clear at least one char so as to trigger redisplay.
- (cond ((< start (point-max))
- (setq end (1+ start)))
- (t
- (setq end (point-max))
- (goto-char end)
- (setq start (line-beginning-position)))))
- (nxml-clear-fontified start end)))
-
+ (nxml-scan-prolog)
+ (setq start (point-min))))
+
+ (when (> end nxml-prolog-end)
+ (goto-char start)
+ (nxml-move-tag-backwards (point-min))
+ (setq start (point))
+ (setq end (max (nxml-scan-after-change start end)
+ end)))
+
+ (nxml-debug-change "nxml-after-change1" start end)
+ (cons start end))
+
;;; Encodings
(defun nxml-insert-xml-declaration ()
(setq suitable-coding-systems (cdr suitable-coding-systems))))
ret)))
-(defun nxml-choose-utf-coding-system ()
+(defun nxml-choose-utf-coding-system ()
(let ((cur (and (local-variable-p 'buffer-file-coding-system)
buffer-file-coding-system
(coding-system-base buffer-file-coding-system))))
;;; Fontification
-(defun nxml-fontify (start)
- (condition-case err
- (save-excursion
- (save-restriction
- (widen)
- (save-match-data
- (nxml-with-invisible-motion
- (nxml-with-unmodifying-text-property-changes
- (if (or nxml-degraded
- ;; just in case we get called in the wrong buffer
- (not nxml-prolog-end))
- (nxml-set-fontified start (point-max))
- (nxml-fontify1 start)))))))
- (error
- (nxml-degrade 'nxml-fontify err))))
-
-(defun nxml-fontify1 (start)
- (cond ((< start nxml-prolog-end)
- (nxml-fontify-prolog)
- (nxml-set-fontified (point-min)
- nxml-prolog-end))
- (t
- (goto-char start)
- (when (not (eq nxml-last-fontify-end start))
- (when (not (equal (char-after) ?\<))
- (search-backward "<" nxml-prolog-end t))
- (nxml-ensure-scan-up-to-date)
- (nxml-move-outside-backwards))
- (let ((start (point)))
- (nxml-do-fontify (min (point-max)
- (+ start nxml-fontify-chunk-size)))
- (setq nxml-last-fontify-end (point))
- (nxml-set-fontified start nxml-last-fontify-end)))))
-
-(defun nxml-fontify-buffer ()
- (interactive)
- (save-excursion
- (save-restriction
- (widen)
- (nxml-with-invisible-motion
- (goto-char (point-min))
- (nxml-with-unmodifying-text-property-changes
- (nxml-fontify-prolog)
- (goto-char nxml-prolog-end)
- (nxml-do-fontify))))))
+(defun nxml-unfontify-region (start end)
+ (font-lock-default-unfontify-region start end)
+ (nxml-clear-char-ref-extra-display start end))
+
+(defvar font-lock-beg) (defvar font-lock-end)
+(defun nxml-extend-region ()
+ "Extend the region to hold the minimum area we can fontify with nXML.
+Called with `font-lock-beg' and `font-lock-end' dynamically bound."
+ (let ((start font-lock-beg)
+ (end font-lock-end))
+
+ (nxml-debug-change "nxml-extend-region(input)" start end)
+
+ (when (< start nxml-prolog-end)
+ (setq start (point-min)))
+
+ (cond ((<= end nxml-prolog-end)
+ (setq end nxml-prolog-end))
+
+ (t
+ (goto-char start)
+ ;; some font-lock backends (like Emacs 22 jit-lock) snap
+ ;; the region to the beginning of the line no matter what
+ ;; we say here. To mitigate the resulting excess
+ ;; fontification, ignore leading whitespace.
+ (skip-syntax-forward " ")
+
+ ;; find the beginning of the previous tag
+ (when (not (equal (char-after) ?\<))
+ (search-backward "<" nxml-prolog-end t))
+ (nxml-ensure-scan-up-to-date)
+ (nxml-move-outside-backwards)
+ (setq start (point))
+
+ (while (< (point) end)
+ (nxml-tokenize-forward))
+
+ (setq end (point))))
+
+ (when (or (< start font-lock-beg)
+ (> end font-lock-end))
+ (setq font-lock-beg start
+ font-lock-end end)
+ (nxml-debug-change "nxml-extend-region" start end)
+ t)))
+
+(defun nxml-extend-after-change-region (start end pre-change-length)
+ (unless nxml-degraded
+ (setq nxml-last-fontify-end nil)
+ (let ((region (nxml-with-degradation-on-error
+ 'nxml-extend-after-change-region
+ (save-excursion
+ (save-restriction
+ (widen)
+ (save-match-data
+ (nxml-with-invisible-motion
+ (nxml-with-unmodifying-text-property-changes
+ (nxml-extend-after-change-region1
+ start end pre-change-length)))))))))
+ (if (consp region) region))))
+
+(defun nxml-extend-after-change-region1 (start end pre-change-length)
+ (let* ((region (nxml-after-change1 start end pre-change-length))
+ (font-lock-beg (car region))
+ (font-lock-end (cdr region)))
+
+ (nxml-extend-region)
+ (cons font-lock-beg font-lock-end)))
+
+(defun nxml-fontify-matcher (bound)
+ "Called as font-lock keyword matcher."
+
+ (unless nxml-degraded
+ (nxml-debug-change "nxml-fontify-matcher" (point) bound)
+
+ (when (< (point) nxml-prolog-end)
+ ;; prolog needs to be fontified in one go, and
+ ;; nxml-extend-region makes sure we start at BOB.
+ (assert (bobp))
+ (nxml-fontify-prolog)
+ (goto-char nxml-prolog-end))
+
+ (let (xmltok-dependent-regions
+ xmltok-errors)
+ (while (and (nxml-tokenize-forward)
+ (<= (point) bound)) ; intervals are open-ended
+ (nxml-apply-fontify-rule)))
+
+ (setq nxml-last-fontify-end (point)))
+
+ ;; Since we did the fontification internally, tell font-lock to not
+ ;; do anything itself.
+ nil)
(defun nxml-fontify-prolog ()
"Fontify the prolog.
This does not set the fontified property, but it does clear
faces appropriately."
(let ((regions nxml-prolog-regions))
- (nxml-clear-face (point-min) nxml-prolog-end)
(while regions
(let ((region (car regions)))
(nxml-apply-fontify-rule (aref region 0)
(aref region 2)))
(setq regions (cdr regions)))))
-(defun nxml-do-fontify (&optional bound)
- "Fontify at least as far as bound.
-Leave point after last fontified position."
- (unless bound (setq bound (point-max)))
- (let (xmltok-dependent-regions
- xmltok-errors)
- (while (and (< (point) bound)
- (nxml-tokenize-forward))
- (nxml-clear-face xmltok-start (point))
- (nxml-apply-fontify-rule))))
-
;; Vectors identify a substring of the token to be highlighted in some face.
;; Token types returned by xmltok-forward.
(put 'start-tag
'nxml-fontify-rule
- '([nil 1 nxml-tag-delimiter-face]
- [-1 nil nxml-tag-delimiter-face]
+ '([nil 1 nxml-tag-delimiter]
+ [-1 nil nxml-tag-delimiter]
(element-qname . 1)
attributes))
(put 'partial-start-tag
'nxml-fontify-rule
- '([nil 1 nxml-tag-delimiter-face]
+ '([nil 1 nxml-tag-delimiter]
(element-qname . 1)
attributes))
(put 'end-tag
'nxml-fontify-rule
- '([nil 1 nxml-tag-delimiter-face]
- [1 2 nxml-tag-slash-face]
- [-1 nil nxml-tag-delimiter-face]
+ '([nil 1 nxml-tag-delimiter]
+ [1 2 nxml-tag-slash]
+ [-1 nil nxml-tag-delimiter]
(element-qname . 2)))
(put 'partial-end-tag
'nxml-fontify-rule
- '([nil 1 nxml-tag-delimiter-face]
- [1 2 nxml-tag-slash-face]
+ '([nil 1 nxml-tag-delimiter]
+ [1 2 nxml-tag-slash]
(element-qname . 2)))
(put 'empty-element
'nxml-fontify-rule
- '([nil 1 nxml-tag-delimiter-face]
- [-2 -1 nxml-tag-slash-face]
- [-1 nil nxml-tag-delimiter-face]
+ '([nil 1 nxml-tag-delimiter]
+ [-2 -1 nxml-tag-slash]
+ [-1 nil nxml-tag-delimiter]
(element-qname . 1)
attributes))
(put 'partial-empty-element
'nxml-fontify-rule
- '([nil 1 nxml-tag-delimiter-face]
- [-1 nil nxml-tag-slash-face]
+ '([nil 1 nxml-tag-delimiter]
+ [-1 nil nxml-tag-slash]
(element-qname . 1)
attributes))
(put 'char-ref
'nxml-fontify-rule
- '([nil 2 nxml-char-ref-delimiter-face]
- [2 -1 nxml-char-ref-number-face]
- [-1 nil nxml-char-ref-delimiter-face]
+ '([nil 2 nxml-char-ref-delimiter]
+ [2 -1 nxml-char-ref-number]
+ [-1 nil nxml-char-ref-delimiter]
char-ref))
(put 'entity-ref
'nxml-fontify-rule
- '([nil 1 nxml-entity-ref-delimiter-face]
- [1 -1 nxml-entity-ref-name-face]
- [-1 nil nxml-entity-ref-delimiter-face]))
+ '([nil 1 nxml-entity-ref-delimiter]
+ [1 -1 nxml-entity-ref-name]
+ [-1 nil nxml-entity-ref-delimiter]))
(put 'comment
'nxml-fontify-rule
- '([nil 4 nxml-comment-delimiter-face]
- [4 -3 nxml-comment-content-face]
- [-3 nil nxml-comment-delimiter-face]))
+ '([nil 4 nxml-comment-delimiter]
+ [4 -3 nxml-comment-content]
+ [-3 nil nxml-comment-delimiter]))
(put 'processing-instruction
'nxml-fontify-rule
- '([nil 2 nxml-processing-instruction-delimiter-face]
- [-2 nil nxml-processing-instruction-delimiter-face]
+ '([nil 2 nxml-processing-instruction-delimiter]
+ [-2 nil nxml-processing-instruction-delimiter]
processing-instruction-content))
(put 'cdata-section
'nxml-fontify-rule
- '([nil 3 nxml-cdata-section-delimiter-face] ; <![
- [3 8 nxml-cdata-section-CDATA-face] ; CDATA
- [8 9 nxml-cdata-section-delimiter-face] ; [
- [9 -3 nxml-cdata-section-content-face] ; ]]>
- [-3 nil nxml-cdata-section-delimiter-face]))
+ '([nil 3 nxml-cdata-section-delimiter] ; <![
+ [3 8 nxml-cdata-section-CDATA] ; CDATA
+ [8 9 nxml-cdata-section-delimiter] ; [
+ [9 -3 nxml-cdata-section-content] ; ]]>
+ [-3 nil nxml-cdata-section-delimiter]))
(put 'data
'nxml-fontify-rule
- '([nil nil nxml-text-face]))
+ '([nil nil nxml-text]))
;; Prolog region types in list returned by xmltok-forward-prolog.
(put 'xml-declaration
'nxml-fontify-rule
- '([nil 2 nxml-processing-instruction-delimiter-face]
- [2 5 nxml-processing-instruction-target-face]
- [-2 nil nxml-processing-instruction-delimiter-face]))
+ '([nil 2 nxml-processing-instruction-delimiter]
+ [2 5 nxml-processing-instruction-target]
+ [-2 nil nxml-processing-instruction-delimiter]))
(put 'xml-declaration-attribute-name
'nxml-fontify-rule
- '([nil nil nxml-attribute-local-name-face]))
+ '([nil nil nxml-attribute-local-name]))
(put 'xml-declaration-attribute-value
'nxml-fontify-rule
- '([nil 1 nxml-attribute-value-delimiter-face]
- [1 -1 nxml-attribute-value-face]
- [-1 nil nxml-attribute-value-delimiter-face]))
+ '([nil 1 nxml-attribute-value-delimiter]
+ [1 -1 nxml-attribute-value]
+ [-1 nil nxml-attribute-value-delimiter]))
(put 'processing-instruction-left
'nxml-fontify-rule
- '([nil 2 nxml-processing-instruction-delimiter-face]
- [2 nil nxml-processing-instruction-target-face]))
+ '([nil 2 nxml-processing-instruction-delimiter]
+ [2 nil nxml-processing-instruction-target]))
(put 'processing-instruction-right
'nxml-fontify-rule
- '([nil -2 nxml-processing-instruction-content-face]
- [-2 nil nxml-processing-instruction-delimiter-face]))
+ '([nil -2 nxml-processing-instruction-content]
+ [-2 nil nxml-processing-instruction-delimiter]))
(put 'literal
'nxml-fontify-rule
- '([nil 1 nxml-prolog-literal-delimiter-face]
- [1 -1 nxml-prolog-literal-content-face]
- [-1 nil nxml-prolog-literal-delimiter-face]))
+ '([nil 1 nxml-prolog-literal-delimiter]
+ [1 -1 nxml-prolog-literal-content]
+ [-1 nil nxml-prolog-literal-delimiter]))
(put 'keyword
'nxml-fontify-rule
- '([nil nil nxml-prolog-keyword-face]))
+ '([nil nil nxml-prolog-keyword]))
(put 'markup-declaration-open
'nxml-fontify-rule
- '([0 2 nxml-markup-declaration-delimiter-face]
- [2 nil nxml-prolog-keyword-face]))
+ '([0 2 nxml-markup-declaration-delimiter]
+ [2 nil nxml-prolog-keyword]))
(put 'markup-declaration-close
'nxml-fontify-rule
- '([nil nil nxml-markup-declaration-delimiter-face]))
+ '([nil nil nxml-markup-declaration-delimiter]))
(put 'internal-subset-open
'nxml-fontify-rule
- '([nil nil nxml-markup-declaration-delimiter-face]))
+ '([nil nil nxml-markup-declaration-delimiter]))
(put 'internal-subset-close
'nxml-fontify-rule
- '([nil 1 nxml-markup-declaration-delimiter-face]
- [-1 nil nxml-markup-declaration-delimiter-face]))
+ '([nil 1 nxml-markup-declaration-delimiter]
+ [-1 nil nxml-markup-declaration-delimiter]))
(put 'hash-name
'nxml-fontify-rule
- '([nil 1 nxml-hash-face]
- [1 nil nxml-prolog-keyword-face]))
+ '([nil 1 nxml-hash]
+ [1 nil nxml-prolog-keyword]))
(defun nxml-apply-fontify-rule (&optional type start end)
(let ((rule (get (or type xmltok-type) 'nxml-fontify-rule)))
(nxml-fontify-qname (+ start (cdr action))
xmltok-name-colon
xmltok-name-end
- 'nxml-element-prefix-face
- 'nxml-element-colon-face
- 'nxml-element-local-name-face)))
+ 'nxml-element-prefix
+ 'nxml-element-colon
+ 'nxml-element-local-name)))
((eq action 'attributes)
(nxml-fontify-attributes))
((eq action 'processing-instruction-content)
(nxml-set-face (+ start 2)
xmltok-name-end
- 'nxml-processing-instruction-target-face)
+ 'nxml-processing-instruction-target)
(nxml-set-face (save-excursion
(goto-char xmltok-name-end)
(skip-chars-forward " \t\r\n")
(point))
(- end 2)
- 'nxml-processing-instruction-content-face))
+ 'nxml-processing-instruction-content))
((eq action 'char-ref)
(nxml-char-ref-display-extra start
end
(nxml-fontify-qname (xmltok-attribute-name-start att)
(xmltok-attribute-name-colon att)
(xmltok-attribute-name-end att)
- 'nxml-namespace-attribute-xmlns-face
- 'nxml-namespace-attribute-colon-face
- 'nxml-namespace-attribute-prefix-face
- 'nxml-namespace-attribute-xmlns-face)
+ 'nxml-namespace-attribute-xmlns
+ 'nxml-namespace-attribute-colon
+ 'nxml-namespace-attribute-prefix
+ 'nxml-namespace-attribute-xmlns)
(nxml-fontify-qname (xmltok-attribute-name-start att)
(xmltok-attribute-name-colon att)
(xmltok-attribute-name-end att)
- 'nxml-attribute-prefix-face
- 'nxml-attribute-colon-face
- 'nxml-attribute-local-name-face))
+ 'nxml-attribute-prefix
+ 'nxml-attribute-colon
+ 'nxml-attribute-local-name))
(let ((start (xmltok-attribute-value-start att))
(end (xmltok-attribute-value-end att))
(refs (xmltok-attribute-refs att))
(delimiter-face (if namespace-declaration
- 'nxml-namespace-attribute-value-delimiter-face
- 'nxml-attribute-value-delimiter-face))
+ 'nxml-namespace-attribute-value-delimiter
+ 'nxml-attribute-value-delimiter))
(value-face (if namespace-declaration
- 'nxml-namespace-attribute-value-face
- 'nxml-attribute-value-face)))
+ 'nxml-namespace-attribute-value
+ 'nxml-attribute-value)))
(when start
(nxml-set-face (1- start) start delimiter-face)
(nxml-set-face end (1+ end) delimiter-face)
(defun nxml-balanced-close-start-tag (block-or-inline)
(let ((token-end (nxml-token-before))
- (pos (1+ (point))))
+ (pos (1+ (point)))
+ (token-start xmltok-start))
(unless (or (eq xmltok-type 'partial-start-tag)
(and (memq xmltok-type '(start-tag
empty-element
partial-empty-element))
(>= token-end pos)))
(error "Not in a start-tag"))
+ ;; Note that this insertion changes xmltok-start.
(insert "></"
(buffer-substring-no-properties (+ xmltok-start 1)
(min xmltok-name-end (point)))
">")
(if (eq block-or-inline 'inline)
(goto-char pos)
- (goto-char xmltok-start)
+ (goto-char token-start)
(back-to-indentation)
- (if (= (point) xmltok-start)
+ (if (= (point) token-start)
(let ((indent (current-column)))
- (goto-char pos)
- (insert "\n")
- (indent-line-to indent)
- (goto-char pos)
- (insert "\n")
- (indent-line-to (+ nxml-child-indent indent)))
+ (goto-char pos)
+ (insert "\n")
+ (indent-line-to indent)
+ (goto-char pos)
+ (insert "\n")
+ (indent-line-to (+ nxml-child-indent indent)))
(goto-char pos)))))
-
+
(defun nxml-finish-element ()
"Finish the current element by inserting an end-tag."
(interactive "*")
"Indent current line as XML."
(let ((indent (nxml-compute-indent))
(from-end (- (point-max) (point))))
- (when indent
+ (when (and indent
+ (/= indent (current-indentation)))
(beginning-of-line)
(let ((bol (point)))
(skip-chars-forward " \t")
(defun nxml-merge-indent-context-type (context)
"Merge the indent context type CONTEXT with the token in `xmltok-type'.
Return the merged indent context type. An indent context type is
-either nil or one of the symbols start-tag, end-tag, markup, comment,
-mixed."
+either nil or one of the symbols `start-tag', `end-tag', `markup',
+`comment', `mixed'."
(cond ((memq xmltok-type '(start-tag partial-start-tag))
(if (memq context '(nil start-tag comment))
'start-tag
(setq atts nil))
(t (setq atts (cdr atts)))))
value-boundary))
-
+
(defun nxml-compute-indent-in-delimited-token (pos open-delim close-delim)
"Return the indent for a line that starts inside a token with delimiters.
OPEN-DELIM and CLOSE-DELIM are strings giving the opening and closing
Inserts as many characters as can be completed. However, if not even
one character can be completed, then a buffer with the possibilities
is popped up and the symbol is read from the minibuffer with
-completion. If the symbol is complete, then any characters that must
+completion. If the symbol is complete, then any characters that must
follow the symbol are also inserted.
The name space used for completion and what is treated as a symbol
An element contains as items strings with no markup, tags, processing
instructions, comments, CDATA sections, entity references and
-characters references. However, if the variable
+characters references. However, if the variable
`nxml-sexp-element-flag' is non-nil, then an element is treated as a
single markup item. A start-tag contains an element name followed by
-one or more attributes. An end-tag contains just an element name. An
-attribute value literals contains strings with no markup, entity
+one or more attributes. An end-tag contains just an element name.
+An attribute value literals contains strings with no markup, entity
references and character references. A processing instruction
consists of a target and a content string. A comment or a CDATA
section contains a single string. An entity reference contains a
(goto-char (+ xmltok-start offset))
(and (re-search-forward "^[ \t]*$" end t)
(match-beginning 0)))))
- ((and (memq xmltok-type '(start-tag
+ ((and (memq xmltok-type '(start-tag
end-tag
empty-element
comment
(looking-at "[ \t]*$")
(not (nxml-in-mixed-content-p t)))
(save-excursion
- (or (search-forward "\n" nil t)
+ (or (search-forward "\n" nil t)
(point-max))))))
(defun nxml-paragraph-start-pos (had-data offset)
(goto-char (- (point) offset))
(and (re-search-backward "^[ \t]*$" xmltok-start t)
(match-beginning 0))))
- ((and (memq xmltok-type '(start-tag
+ ((and (memq xmltok-type '(start-tag
end-tag
empty-element
comment
entity-ref))
(nxml-token-ends-line-p)
(nxml-token-begins-line-p))
- (or (search-forward "\n" nil t)
+ (or (search-forward "\n" nil t)
(point-max)))
((and (eq xmltok-type 'start-tag)
(nxml-token-begins-line-p)
(fill-region-as-paragraph start end arg))
(skip-line-prefix fill-prefix)
fill-prefix))
-
+
(defun nxml-newline-and-indent (soft)
(delete-horizontal-space)
(if soft (insert-and-inherit ?\n) (newline 1))
the word before point; the contents of the current buffer is used to
decide where.
-It works in a similar way to \\[dabbrev-expand]. It searches first
+It works in a similar way to \\[dabbrev-expand]. It searches first
backwards from point, then forwards from point for an element whose
content is a string which matches the contents of the buffer before
-point and which includes at least the word before point. It then
+point and which includes at least the word before point. It then
copies the start- and end-tags from that element and uses them to
surround the matching string before point.
(- start-tag-close-pos xmltok-start)))
(insert "</" name ">")
(setq nxml-dynamic-markup-prev-pos (point))))))))))
-
+
;;; Character names
-(defvar nxml-char-name-ignore-case nil)
+(defvar nxml-char-name-ignore-case t)
(defvar nxml-char-name-alist nil
"Alist of character names.
(defvar nxml-autoload-char-name-set-list nil
"List of char namesets that can be autoloaded.")
-(defun nxml-enable-char-name-set (nameset)
+(defun nxml-enable-char-name-set (nameset)
(put nameset 'nxml-char-name-set-enabled t))
-(defun nxml-disable-char-name-set (nameset)
+(defun nxml-disable-char-name-set (nameset)
(put nameset 'nxml-char-name-set-enabled nil))
(defun nxml-char-name-set-enabled-p (nameset)
(defun nxml-define-char-name-set (nameset alist)
"Define a set of character names.
NAMESET is a symbol identifying the set.
-Alist is a list where each member has the form (NAME CODE),
-where NAME is a string naming a character and code
-is an integer giving the Unicode scalar value of the character."
+ALIST is a list where each member has the form (NAME CODE),
+where NAME is a string naming a character and code is an
+integer giving the Unicode scalar value of the character."
(when (get nameset 'nxml-char-name-set-defined)
(error "Nameset `%s' already defined" nameset))
(let ((iter alist))
(put nameset 'nxml-char-name-set-defined t))
(defun nxml-get-char-name (code)
- (mapcar 'nxml-maybe-load-char-name-set nxml-autoload-char-name-set-list)
+ (mapc 'nxml-maybe-load-char-name-set nxml-autoload-char-name-set-list)
(let ((names (gethash code nxml-char-name-table))
name)
(while (and names (not name))
Normally, inserts the character as a numeric character reference.
With a prefix argument, inserts the character directly."
(interactive "*P")
- (mapcar 'nxml-maybe-load-char-name-set nxml-autoload-char-name-set-list)
+ (mapc 'nxml-maybe-load-char-name-set nxml-autoload-char-name-set-list)
(let ((name
(let ((completion-ignore-case nxml-char-name-ignore-case))
(completing-read "Character name: "
(error "Character %x is not supported by Emacs"
code))
(format "&#x%X;" code))))))
-
+
(defun nxml-maybe-load-char-name-set (sym)
(when (and (get sym 'nxml-char-name-set-enabled)
(not (get sym 'nxml-char-name-set-defined))
(load (get sym 'nxml-char-name-set-file))))
(defun nxml-toggle-char-ref-extra-display (arg)
- "*Toggle the display of extra information for character references."
+ "Toggle the display of extra information for character references."
(interactive "P")
(let ((new (if (null arg)
(not nxml-char-ref-extra-display)
(> (prefix-numeric-value arg) 0))))
(when (not (eq new nxml-char-ref-extra-display))
(setq nxml-char-ref-extra-display new)
- (save-excursion
- (save-restriction
- (widen)
- (if nxml-char-ref-extra-display
- (nxml-with-unmodifying-text-property-changes
- (nxml-clear-fontified (point-min) (point-max)))
- (nxml-clear-char-ref-extra-display (point-min) (point-max))))))))
+ (font-lock-fontify-buffer))))
(put 'nxml-char-ref 'evaporate t)
(when nxml-char-ref-extra-display
(let ((name (nxml-get-char-name n))
(glyph-string (and nxml-char-ref-display-glyph-flag
- (nxml-glyph-display-string n 'nxml-glyph-face)))
+ (nxml-glyph-display-string n 'nxml-glyph)))
ov)
(when (or name glyph-string)
(setq ov (make-overlay start end nil t))
(when glyph-string
(overlay-put ov
'after-string
- (propertize glyph-string 'face 'nxml-glyph-face)))))))
+ (propertize glyph-string 'face 'nxml-glyph)))))))
(defun nxml-clear-char-ref-extra-display (start end)
(let ((ov (overlays-in start end)))
(delete-overlay (car ov)))
(setq ov (cdr ov)))))
-;;; Versioning
-
-(defun nxml-version ()
- "Show the version of nXML mode that is being used."
- (interactive)
- (if nxml-version
- (message "nXML mode version %s" nxml-version)
- (message "nXML mode version unknown")))
-
(defun nxml-start-delimiter-length (type)
(or (get type 'nxml-start-delimiter-length)
0))
-
+
(put 'cdata-section 'nxml-start-delimiter-length 9)
(put 'comment 'nxml-start-delimiter-length 4)
(put 'processing-instruction 'nxml-start-delimiter-length 2)
(defun nxml-end-delimiter-length (type)
(or (get type 'nxml-end-delimiter-length)
0))
-
+
(put 'cdata-section 'nxml-end-delimiter-length 3)
(put 'comment 'nxml-end-delimiter-length 3)
(put 'processing-instruction 'nxml-end-delimiter-length 2)
(put 'entity-ref 'nxml-friendly-name "entity reference")
(put 'char-ref 'nxml-friendly-name "character reference")
+;;;###autoload
+(defalias 'xml-mode 'nxml-mode)
+
(provide 'nxml-mode)
;; arch-tag: 8603bc5f-1ef9-4021-b223-322fb2ca708e