summaryrefslogtreecommitdiff
path: root/lisp/nxml/nxml-rap.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/nxml/nxml-rap.el')
-rw-r--r--lisp/nxml/nxml-rap.el129
1 files changed, 19 insertions, 110 deletions
diff --git a/lisp/nxml/nxml-rap.el b/lisp/nxml/nxml-rap.el
index 47b23da62ad..e66289d042a 100644
--- a/lisp/nxml/nxml-rap.el
+++ b/lisp/nxml/nxml-rap.el
@@ -1,4 +1,4 @@
-;;; nxml-rap.el --- low-level support for random access parsing for nXML mode
+;;; nxml-rap.el --- low-level support for random access parsing for nXML mode -*- lexical-binding:t -*-
;; Copyright (C) 2003-2004, 2007-2016 Free Software Foundation, Inc.
@@ -46,8 +46,7 @@
;; look like it scales to large numbers of overlays in a buffer.
;;
;; We don't in fact track all these constructs, but only track them in
-;; some initial part of the instance. The variable `nxml-scan-end'
-;; contains the limit of where we have scanned up to for them.
+;; some initial part of the instance.
;;
;; Thus to parse some random point in the file we first ensure that we
;; have scanned up to that point. Then we search backwards for a
@@ -74,93 +73,33 @@
(require 'xmltok)
(require 'nxml-util)
+(require 'sgml-mode)
-(defvar nxml-prolog-end nil
+(defvar-local nxml-prolog-end nil
"Integer giving position following end of the prolog.")
-(make-variable-buffer-local 'nxml-prolog-end)
-
-(defvar nxml-scan-end nil
- "Marker giving position up to which we have scanned.
-nxml-scan-end must be >= nxml-prolog-end. Furthermore, nxml-scan-end
-must not be an inside position in the following sense. A position is
-inside if the following character is a part of, but not the first
-character of, a CDATA section, comment or processing instruction.
-Furthermore all positions >= nxml-prolog-end and < nxml-scan-end that
-are inside positions must have a non-nil `nxml-inside' property whose
-value is a symbol specifying what it is inside. Any characters with a
-non-nil `fontified' property must have position < nxml-scan-end and
-the correct face. Dependent regions must also be established for any
-unclosed constructs starting before nxml-scan-end.
-There must be no `nxml-inside' properties after nxml-scan-end.")
-(make-variable-buffer-local 'nxml-scan-end)
(defsubst nxml-get-inside (pos)
- (get-text-property pos 'nxml-inside))
-
-(defsubst nxml-clear-inside (start end)
- (nxml-debug-clear-inside start end)
- (remove-text-properties start end '(nxml-inside nil)))
-
-(defsubst nxml-set-inside (start end type)
- (nxml-debug-set-inside start end)
- (put-text-property start end 'nxml-inside type))
+ (save-excursion (nth 8 (syntax-ppss pos))))
(defun nxml-inside-end (pos)
"Return the end of the inside region containing POS.
Return nil if the character at POS is not inside."
- (if (nxml-get-inside pos)
- (or (next-single-property-change pos 'nxml-inside)
- (point-max))
- nil))
+ (save-excursion
+ (let ((ppss (syntax-ppss pos)))
+ (when (nth 8 ppss)
+ (goto-char (nth 8 ppss))
+ (with-syntax-table sgml-tag-syntax-table
+ (if (nth 3 ppss)
+ (progn (forward-comment 1) (point))
+ (or (scan-sexps (point) 1) (point-max))))))))
(defun nxml-inside-start (pos)
"Return the start of the inside region containing POS.
Return nil if the character at POS is not inside."
- (if (nxml-get-inside pos)
- (or (previous-single-property-change (1+ pos) 'nxml-inside)
- (point-min))
- nil))
+ (save-excursion (nth 8 (syntax-ppss pos))))
;;; Change management
-(defun nxml-scan-after-change (start end)
- "Restore `nxml-scan-end' invariants after a change.
-The change happened between START and END.
-Return position after which lexical state is unchanged.
-END must be > `nxml-prolog-end'. START must be outside
-any “inside” regions and at the beginning of a token."
- (if (>= start nxml-scan-end)
- nxml-scan-end
- (let ((inside-remove-start start)
- xmltok-errors)
- (while (or (when (xmltok-forward-special (min end nxml-scan-end))
- (when (memq xmltok-type
- '(comment
- cdata-section
- processing-instruction))
- (nxml-clear-inside inside-remove-start
- (1+ xmltok-start))
- (nxml-set-inside (1+ xmltok-start)
- (point)
- xmltok-type)
- (setq inside-remove-start (point)))
- (if (< (point) (min end nxml-scan-end))
- t
- (setq end (point))
- nil))
- ;; The end of the change was inside but is now outside.
- ;; Imagine something really weird like
- ;; <![CDATA[foo <!-- bar ]]> <![CDATA[ stuff --> <!-- ]]> -->
- ;; and suppose we deleted "<![CDATA[f"
- (let ((inside-end (nxml-inside-end end)))
- (when inside-end
- (setq end inside-end)
- t))))
- (nxml-clear-inside inside-remove-start end))
- (when (> end nxml-scan-end)
- (set-marker nxml-scan-end end))
- end))
-
;; n-s-p only called from nxml-mode.el, where this variable is defined.
(defvar nxml-prolog-regions)
@@ -169,10 +108,7 @@ any “inside” regions and at the beginning of a token."
(let (xmltok-dtd
xmltok-errors)
(setq nxml-prolog-regions (xmltok-forward-prolog))
- (setq nxml-prolog-end (point))
- (nxml-clear-inside (point-min) nxml-prolog-end))
- (when (< nxml-scan-end nxml-prolog-end)
- (set-marker nxml-scan-end nxml-prolog-end)))
+ (setq nxml-prolog-end (point))))
;;; Random access parsing
@@ -223,14 +159,7 @@ Sets variables like `nxml-token-after'."
(defun nxml-tokenize-forward ()
(let (xmltok-errors)
- (when (and (xmltok-forward)
- (> (point) nxml-scan-end))
- (cond ((memq xmltok-type '(comment
- cdata-section
- processing-instruction))
- (with-silent-modifications
- (nxml-set-inside (1+ xmltok-start) (point) xmltok-type))))
- (set-marker nxml-scan-end (point)))
+ (xmltok-forward)
xmltok-type))
(defun nxml-move-tag-backwards (bound)
@@ -253,32 +182,12 @@ As a precondition, point must be >= BOUND."
Leave point unmoved if it is not inside anything special."
(let ((start (nxml-inside-start (point))))
(when start
- (goto-char (1- start))
+ (goto-char start)
(when (nxml-get-inside (point))
- (error "Char before inside-start at %s had nxml-inside property %s"
- (point)
- (nxml-get-inside (point)))))))
+ (error "Char before inside-start at %s is still \"inside\"" (point))))))
(defun nxml-ensure-scan-up-to-date ()
- (let ((pos (point)))
- (when (< nxml-scan-end pos)
- (save-excursion
- (goto-char nxml-scan-end)
- (let (xmltok-errors)
- (while (when (xmltok-forward-special pos)
- (when (memq xmltok-type
- '(comment
- processing-instruction
- cdata-section))
- (with-silent-modifications
- (nxml-set-inside (1+ xmltok-start)
- (point)
- xmltok-type)))
- (if (< (point) pos)
- t
- (setq pos (point))
- nil)))
- (set-marker nxml-scan-end pos))))))
+ (syntax-propertize (point)))
;;; Element scanning