aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2002-03-27 00:06:42 +0000
committerStefan Monnier2002-03-27 00:06:42 +0000
commit63080afce880a4c067dfc2e7c5b04817070b82fe (patch)
tree90dc253c2e73753e87f9733d32eee135b3d18fb7
parent5e73ebb4f7da7f3ab28ee7b28c84e34cd06dc877 (diff)
downloademacs-63080afce880a4c067dfc2e7c5b04817070b82fe.tar.gz
emacs-63080afce880a4c067dfc2e7c5b04817070b82fe.zip
(xml-lite-at-indentation-p): Move.
(xml-lite-in-string-p, xml-lite-looking-back-at, xml-lite-looking-at): New functions. (forward-xml-tag, backward-xml-tag, beginning-of-xml-tag) (end-of-xml-tag): Remove. (xml-lite-get-context): Better handling of comments. (xml-lite-calculate-indent): Use xml-lite-in-string-p. (xml-lite-parse-tag-backward): Rewrite.
-rw-r--r--lisp/ChangeLog16
-rw-r--r--lisp/textmodes/xml-lite.el205
2 files changed, 128 insertions, 93 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index e22b8a04880..1b567083265 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,14 @@
12002-03-26 Stefan Monnier <monnier@cs.yale.edu>
2
3 * textmodes/xml-lite.el (xml-lite-at-indentation-p): Move.
4 (xml-lite-in-string-p, xml-lite-looking-back-at, xml-lite-looking-at):
5 New functions.
6 (forward-xml-tag, backward-xml-tag, beginning-of-xml-tag)
7 (end-of-xml-tag): Remove.
8 (xml-lite-get-context): Better handling of comments.
9 (xml-lite-calculate-indent): Use xml-lite-in-string-p.
10 (xml-lite-parse-tag-backward): Rewrite.
11
12002-03-26 Juanma Barranquero <lektu@terra.es> 122002-03-26 Juanma Barranquero <lektu@terra.es>
2 13
3 * makefile.w32-in (WINS): Add the toolbar directory. 14 * makefile.w32-in (WINS): Add the toolbar directory.
@@ -34,13 +45,12 @@
34 * subr.el (macro-declaration-function): New function. Set the 45 * subr.el (macro-declaration-function): New function. Set the
35 variable macro-declaration-function to it. 46 variable macro-declaration-function to it.
36 47
37 * emacs-lisp/bytecomp.el (byte-compile-file-form-defmumble): 48 * emacs-lisp/bytecomp.el (byte-compile-file-form-defmumble):
38 Handle declarations in macro definitions. 49 Handle declarations in macro definitions.
39 50
402002-03-24 Eli Zaretskii <eliz@is.elta.co.il> 512002-03-24 Eli Zaretskii <eliz@is.elta.co.il>
41 52
42 * facemenu.el (facemenu-get-face): Remove unused variable 53 * facemenu.el (facemenu-get-face): Remove unused variable `foreground'.
43 `foreground'.
44 54
45 * enriched.el (enriched-face-ans): Support FACE of the form 55 * enriched.el (enriched-face-ans): Support FACE of the form
46 (:foreground COLOR) and (:background COLOR). 56 (:foreground COLOR) and (:background COLOR).
diff --git a/lisp/textmodes/xml-lite.el b/lisp/textmodes/xml-lite.el
index fcf01c8f82a..3b777479277 100644
--- a/lisp/textmodes/xml-lite.el
+++ b/lisp/textmodes/xml-lite.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Mike Williams <mdub@bigfoot.com> 5;; Author: Mike Williams <mdub@bigfoot.com>
6;; Created: February 2001 6;; Created: February 2001
7;; Version: $Revision: 1.24 $ 7;; Version: $Revision: 1.28 $
8;; Keywords: xml 8;; Keywords: xml
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
@@ -99,6 +99,26 @@ Set this to nil if you don't want a modeline indicator for xml-lite-mode."
99(make-variable-buffer-local 'xml-lite-mode) 99(make-variable-buffer-local 'xml-lite-mode)
100 100
101 101
102;; Syntax analysis
103
104(defsubst xml-lite-at-indentation-p ()
105 "Return true if point is at the first non-whitespace character on the line."
106 (save-excursion
107 (skip-chars-backward " \t")
108 (bolp)))
109
110(defun xml-lite-in-string-p (&optional limit)
111 "Determine whether point is inside a string."
112 (let (syntax-info)
113 (or limit
114 (setq limit (or (save-excursion
115 (re-search-backward "^[ \t]*<" nil t))
116 (point-min))))
117 (setq syntax-info (parse-partial-sexp limit (point)))
118 (if (nth 3 syntax-info)
119 (list (nth 3 syntax-info) (nth 8 syntax-info)))))
120
121
102;; Parsing 122;; Parsing
103 123
104(defstruct (xml-lite-tag 124(defstruct (xml-lite-tag
@@ -111,64 +131,88 @@ Set this to nil if you don't want a modeline indicator for xml-lite-mode."
111 (if (> (skip-chars-forward "-._:A-Za-z0-9") 0) 131 (if (> (skip-chars-forward "-._:A-Za-z0-9") 0)
112 (buffer-substring-no-properties here (point))))) 132 (buffer-substring-no-properties here (point)))))
113 133
134(defsubst xml-lite-looking-back-at (s)
135 (let ((limit (max (- (point) (length s)) (point-min))))
136 (equal s (buffer-substring-no-properties limit (point)))))
137
138(defsubst xml-lite-looking-at (s)
139 (let ((limit (min (+ (point) (length s)))))
140 (equal s (buffer-substring-no-properties (point) limit))))
141
114(defun xml-lite-parse-tag-backward () 142(defun xml-lite-parse-tag-backward ()
115 "Get information about the parent tag." 143 "Get information about the parent tag."
116 (let ((limit (point)) 144 (let ((limit (point))
117 (tag-type 'open) 145 tag-type tag-start tag-end name name-end)
118 (tag-start (search-backward "<" nil t))
119 tag-end name name-end)
120 146
121 (if (not tag-start) nil 147 (cond
122 (setq tag-end (search-forward ">" limit t))
123 148
124 ;; determine tag type 149 ((null (re-search-backward "[<>]" nil t)))
150
151 ((= ?> (char-after)) ;--- found tag-end ---
152 (setq tag-end (1+ (point)))
153 (goto-char tag-end)
154 (cond
155 ((xml-lite-looking-back-at "--") ; comment
156 (setq tag-type 'comment
157 tag-start (search-backward "<!--" nil t)))
158 ((xml-lite-looking-back-at "]]>") ; cdata
159 (setq tag-type 'cdata
160 tag-start (search-backward "![CDATA[" nil t)))
161 (t
162 (setq tag-start
163 (ignore-errors (backward-sexp) (point))))))
164
165 ((= ?< (char-after)) ;--- found tag-start ---
166 (setq tag-start (point))
125 (goto-char (1+ tag-start)) 167 (goto-char (1+ tag-start))
126 (cond 168 (cond
127 169 ((xml-lite-looking-at "!--") ; comment
128 ((= ?? (char-after)) ; processing-instruction 170 (setq tag-type 'comment
129 (setq tag-type 'pi)) 171 tag-end (search-forward "-->" nil t)))
130 172 ((xml-lite-looking-at "![CDATA[") ; cdata
131 ((= ?! (char-after)) ; declaration 173 (setq tag-type 'cdata
132 (setq tag-type 'decl) 174 tag-end (search-forward "]]>" nil t)))
133 (cond
134 ((looking-at "!--") ; comment
135 (setq tag-type 'comment
136 tag-end (search-forward "-->" nil t)))
137 ((looking-at "!\\[CDATA\\[") ; cdata
138 (setq tag-type 'cdata
139 tag-end (search-forward "]]>" nil t)))
140 (t
141 (ignore-errors
142 (goto-char tag-start)
143 (forward-sexp 1)
144 (setq tag-end (point))))))
145
146 ((= ?% (char-after)) ; JSP tag
147 (setq tag-type 'jsp
148 tag-end (search-forward "%>" nil t)))
149
150 ((= ?/ (char-after)) ; close-tag
151 (goto-char (+ 2 tag-start))
152 (setq tag-type 'close
153 name (xml-lite-parse-tag-name)
154 name-end (point)))
155
156 (t 175 (t
157 (setq tag-type 'open 176 (goto-char tag-start)
158 name (xml-lite-parse-tag-name) 177 (setq tag-end
159 name-end (point)) 178 (ignore-errors (forward-sexp) (point))))))
160 ;; check whether it's an empty tag 179
161 (if (and tag-end (eq ?/ (char-before (- tag-end 1)))) 180 )
162 (setq tag-type 'empty)))) 181
182 (cond
183
184 ((or tag-type (null tag-start)))
185
186 ((= ?! (char-after (1+ tag-start))) ; declaration
187 (setq tag-type 'decl))
188
189 ((= ?? (char-after (1+ tag-start))) ; processing-instruction
190 (setq tag-type 'pi))
191
192 ((= ?/ (char-after (1+ tag-start))) ; close-tag
193 (goto-char (+ 2 tag-start))
194 (setq tag-type 'close
195 name (xml-lite-parse-tag-name)
196 name-end (point)))
197
198 ((member ; JSP tags etc
199 (char-after (1+ tag-start))
200 '(?% ?#))
201 (setq tag-type 'unknown))
163 202
203 (t
204 (goto-char (1+ tag-start))
205 (setq tag-type 'open
206 name (xml-lite-parse-tag-name)
207 name-end (point))
208 ;; check whether it's an empty tag
209 (if (and tag-end (eq ?/ (char-before (- tag-end 1))))
210 (setq tag-type 'empty))))
211
212 (cond
213 (tag-start
164 (goto-char tag-start) 214 (goto-char tag-start)
165 (xml-lite-make-tag tag-type tag-start tag-end name name-end)))) 215 (xml-lite-make-tag tag-type tag-start tag-end name name-end)))))
166
167(defsubst xml-lite-at-indentation-p ()
168 "Return true if point is at the first non-whitespace character on the line."
169 (save-excursion
170 (skip-chars-backward " \t")
171 (bolp)))
172 216
173(defsubst xml-lite-inside-tag-p (tag-info &optional point) 217(defsubst xml-lite-inside-tag-p (tag-info &optional point)
174 "Return true if TAG-INFO contains the POINT." 218 "Return true if TAG-INFO contains the POINT."
@@ -185,8 +229,12 @@ parse until we find a start-tag as the first thing on a line.
185The context is a list of tag-info structures. The last one is the tag 229The context is a list of tag-info structures. The last one is the tag
186immediately enclosing the current position." 230immediately enclosing the current position."
187 (let ((here (point)) 231 (let ((here (point))
188 (level 0) 232 (ignore-depth 0)
189 tag-info context) 233 tag-info context)
234 ;; CONTEXT keeps track of the tag-stack
235 ;; IGNORE-DEPTH keeps track of the nesting level of point relative to the
236 ;; first (outermost) tag on the context. This is the number of
237 ;; enclosing start-tags we'll have to ignore.
190 (save-excursion 238 (save-excursion
191 239
192 (while 240 (while
@@ -203,15 +251,22 @@ immediately enclosing the current position."
203 251
204 ;; start-tag 252 ;; start-tag
205 ((eq (xml-lite-tag-type tag-info) 'open) 253 ((eq (xml-lite-tag-type tag-info) 'open)
206 (setq level (1- level)) 254 (setq ignore-depth (1- ignore-depth))
207 (when (= level -1) 255 (when (= ignore-depth -1)
208 (setq context (cons tag-info context)) 256 (setq context (cons tag-info context))
209 (setq level 0))) 257 (setq ignore-depth 0)))
210 258
211 ;; end-tag 259 ;; end-tag
212 ((eq (xml-lite-tag-type tag-info) 'close) 260 ((eq (xml-lite-tag-type tag-info) 'close)
213 (setq level (1+ level))) 261 (setq ignore-depth (1+ ignore-depth)))
214 262
263 ((eq (xml-lite-tag-type tag-info) 'comment)
264 ;; this comment may enclose things we thought were tags
265 (while (and context
266 (> (xml-lite-tag-end tag-info)
267 (xml-lite-tag-end (car context))))
268 (setq context (cdr context))))
269
215 ))) 270 )))
216 271
217 ;; return context 272 ;; return context
@@ -249,13 +304,13 @@ If FULL is non-nil, parse back to the beginning of the buffer."
249 304
250 ;; inside a tag 305 ;; inside a tag
251 ((xml-lite-inside-tag-p last-tag-info here) 306 ((xml-lite-inside-tag-p last-tag-info here)
252 (let ((syntax-info 307
253 (parse-partial-sexp (xml-lite-tag-start last-tag-info) 308 (let ((in-string
254 (point)))) 309 (xml-lite-in-string-p (xml-lite-tag-start last-tag-info))))
255 (cond 310 (cond
256 ;; inside a string 311 ;; inside a string
257 ((nth 3 syntax-info) 312 (in-string
258 (goto-char (nth 8 syntax-info)) 313 (goto-char (nth 1 in-string))
259 (1+ (current-column))) 314 (1+ (current-column)))
260 ;; if we have a tag-name, base indent on that 315 ;; if we have a tag-name, base indent on that
261 ((and (xml-lite-tag-name-end last-tag-info) 316 ((and (xml-lite-tag-name-end last-tag-info)
@@ -362,36 +417,6 @@ Behaves electrically if `xml-lite-electric-slash' is non-nil."
362 (insert-char ?/ arg)))) 417 (insert-char ?/ arg))))
363 418
364 419
365;; Movement commands
366
367(defun forward-xml-tag (arg)
368 "Move forward ARG XML-tags."
369 (interactive "p")
370 (cond
371 ((> arg 0)
372 (search-forward ">" nil nil arg))
373 ((< arg 0)
374 (search-backward "<" nil nil (- arg)))
375 ))
376
377(defun backward-xml-tag (arg)
378 "Move backward ARG XML-tags."
379 (interactive "p")
380 (forward-xml-tag (- arg)))
381
382(defun beginning-of-xml-tag ()
383 "Move to the beginning of the current XML-tag."
384 (interactive)
385 (if (= ?< (char-after (point)))
386 (point)
387 (search-backward "<")))
388
389(defun end-of-xml-tag ()
390 "Move to the end of the current XML-tag."
391 (interactive)
392 (forward-xml-tag 1))
393
394
395;; Keymap 420;; Keymap
396 421
397(defvar xml-lite-mode-map 422(defvar xml-lite-mode-map