aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2002-03-29 20:10:46 +0000
committerStefan Monnier2002-03-29 20:10:46 +0000
commit83f1651d4f683badb8c3c6d4c825fb4e572d43e7 (patch)
tree7f6bf9bdd9b0eca0ed0bd942a542e5bef21e76d3
parent5f3d924defda210f55bde63c5d5f67f55e633dee (diff)
downloademacs-83f1651d4f683badb8c3c6d4c825fb4e572d43e7.tar.gz
emacs-83f1651d4f683badb8c3c6d4c825fb4e572d43e7.zip
(xml-lite-get-context): Allow stopping even with an empty context.
Don't save excursion any more. Ignore end-tags in sgml-empty-tags. Don't complain about unmatched start-tags in sgml-unclosed-tags. (xml-lite-get-context, xml-lite-calculate-indent) (xml-lite-insert-end-tag): Save excursion around xml-lite-get-context. (xml-lite-indent-line): Use back-to-indentation.
-rw-r--r--lisp/textmodes/xml-lite.el104
1 files changed, 53 insertions, 51 deletions
diff --git a/lisp/textmodes/xml-lite.el b/lisp/textmodes/xml-lite.el
index 4ce5ecdb1d2..0dfe41c6b2a 100644
--- a/lisp/textmodes/xml-lite.el
+++ b/lisp/textmodes/xml-lite.el
@@ -205,71 +205,75 @@ at the beginning of a line."
205 205
206(defun xml-lite-get-context (&optional full) 206(defun xml-lite-get-context (&optional full)
207 "Determine the context of the current position. 207 "Determine the context of the current position.
208If FULL is `empty', return even if the context is empty (i.e.
209we just skipped over some element and got to a beginning of line).
208If FULL is non-nil, parse back to the beginning of the buffer, otherwise 210If FULL is non-nil, parse back to the beginning of the buffer, otherwise
209parse until we find a start-tag as the first thing on a line. 211parse until we find a start-tag as the first thing on a line.
210 212
211The context is a list of tag-info structures. The last one is the tag 213The context is a list of tag-info structures. The last one is the tag
212immediately enclosing the current position." 214immediately enclosing the current position."
213 (let ((here (point)) 215 (let ((here (point))
214 (ignore nil) 216 (ignore nil)
215 tag-info context) 217 (context nil)
218 tag-info)
216 ;; CONTEXT keeps track of the tag-stack 219 ;; CONTEXT keeps track of the tag-stack
217 ;; IGNORE keeps track of the nesting level of point relative to the 220 ;; IGNORE keeps track of the nesting level of point relative to the
218 ;; first (outermost) tag on the context. This is the list of 221 ;; first (outermost) tag on the context. This is the list of
219 ;; enclosing start-tags we'll have to ignore. 222 ;; enclosing start-tags we'll have to ignore.
220 (save-excursion 223 (skip-chars-backward " \t\n") ; Make sure we're not at indentation.
221 224 (while
222 (while 225 (and (or ignore (not (if full (eq full 'empty) context))
223 (and (or (not context) 226 (not (xml-lite-at-indentation-p)))
224 ignore 227 (setq tag-info (xml-lite-parse-tag-backward)))
225 full 228
226 (not (xml-lite-at-indentation-p))) 229 ;; This tag may enclose things we thought were tags. If so,
227 (setq tag-info (xml-lite-parse-tag-backward))) 230 ;; discard them.
228 231 (while (and context
229 ;; This tag may enclose things we thought were tags. If so, 232 (> (xml-lite-tag-end tag-info)
230 ;; discard them. 233 (xml-lite-tag-end (car context))))
231 (while (and context 234 (setq context (cdr context)))
232 (> (xml-lite-tag-end tag-info)
233 (xml-lite-tag-end (car context))))
234 (setq context (cdr context)))
235 235
236 (cond 236 (cond
237 237
238 ;; inside a tag ... 238 ;; inside a tag ...
239 ((xml-lite-inside-tag-p tag-info here) 239 ((xml-lite-inside-tag-p tag-info here)
240 (push tag-info context)) 240 (push tag-info context))
241 241
242 ;; start-tag 242 ;; start-tag
243 ((eq (xml-lite-tag-type tag-info) 'open) 243 ((eq (xml-lite-tag-type tag-info) 'open)
244 (cond 244 (cond
245 ((null ignore) (push tag-info context)) 245 ((null ignore) (push tag-info context))
246 ((eq t (compare-strings (xml-lite-tag-name tag-info) nil nil 246 ((eq t (compare-strings (xml-lite-tag-name tag-info) nil nil
247 (car ignore) nil nil t)) 247 (car ignore) nil nil t))
248 (setq ignore (cdr ignore))) 248 (setq ignore (cdr ignore)))
249 (t 249 (t
250 ;; The open and close tags don't match. 250 ;; The open and close tags don't match.
251 (if (not sgml-xml-mode) 251 (if (not sgml-xml-mode)
252 ;; Assume the open tag is simply not closed. 252 ;; Assume the open tag is simply not closed.
253 (message "Unclosed tag <%s>" (xml-lite-tag-name tag-info)) 253 (unless (member-ignore-case (xml-lite-tag-name tag-info)
254 (message "Unmatched tags <%s> and </%s>" 254 sgml-unclosed-tags)
255 (xml-lite-tag-name tag-info) (pop ignore)))))) 255 (message "Unclosed tag <%s>" (xml-lite-tag-name tag-info)))
256 256 (message "Unmatched tags <%s> and </%s>"
257 ;; end-tag 257 (xml-lite-tag-name tag-info) (pop ignore))))))
258 ((eq (xml-lite-tag-type tag-info) 'close) 258
259 (push (xml-lite-tag-name tag-info) ignore)) 259 ;; end-tag
260 260 ((eq (xml-lite-tag-type tag-info) 'close)
261 ))) 261 (if (and (not sgml-xml-mode)
262 (member-ignore-case (xml-lite-tag-name tag-info)
263 sgml-empty-tags))
264 (message "Spurious </%s>: empty tag" (xml-lite-tag-name tag-info))
265 (push (xml-lite-tag-name tag-info) ignore)))
266 ))
262 267
263 ;; return context 268 ;; return context
264 context 269 context))
265 ))
266 270
267(defun xml-lite-show-context (&optional full) 271(defun xml-lite-show-context (&optional full)
268 "Display the current context. 272 "Display the current context.
269If FULL is non-nil, parse back to the beginning of the buffer." 273If FULL is non-nil, parse back to the beginning of the buffer."
270 (interactive "P") 274 (interactive "P")
271 (with-output-to-temp-buffer "*XML Context*" 275 (with-output-to-temp-buffer "*XML Context*"
272 (pp (xml-lite-get-context full)))) 276 (pp (save-excursion (xml-lite-get-context full)))))
273 277
274 278
275;; Indenting 279;; Indenting
@@ -277,7 +281,7 @@ If FULL is non-nil, parse back to the beginning of the buffer."
277(defun xml-lite-calculate-indent () 281(defun xml-lite-calculate-indent ()
278 "Calculate the column to which this line should be indented." 282 "Calculate the column to which this line should be indented."
279 (let* ((here (point)) 283 (let* ((here (point))
280 (context (xml-lite-get-context)) 284 (context (save-excursion (xml-lite-get-context)))
281 (ref-tag-info (car context)) 285 (ref-tag-info (car context))
282 (last-tag-info (car (last context)))) 286 (last-tag-info (car (last context))))
283 287
@@ -338,10 +342,8 @@ If FULL is non-nil, parse back to the beginning of the buffer."
338 (let* ((savep (point)) 342 (let* ((savep (point))
339 (indent-col 343 (indent-col
340 (save-excursion 344 (save-excursion
341 (beginning-of-line) 345 (back-to-indentation)
342 (skip-chars-forward " \t")
343 (if (>= (point) savep) (setq savep nil)) 346 (if (>= (point) savep) (setq savep nil))
344 ;; calculate basic indent
345 (xml-lite-calculate-indent)))) 347 (xml-lite-calculate-indent))))
346 (if savep 348 (if savep
347 (save-excursion (indent-line-to indent-col)) 349 (save-excursion (indent-line-to indent-col))
@@ -353,7 +355,7 @@ If FULL is non-nil, parse back to the beginning of the buffer."
353(defun xml-lite-insert-end-tag () 355(defun xml-lite-insert-end-tag ()
354 "Insert an end-tag for the current element." 356 "Insert an end-tag for the current element."
355 (interactive) 357 (interactive)
356 (let* ((context (xml-lite-get-context)) 358 (let* ((context (save-excursion (xml-lite-get-context)))
357 (tag-info (car (last context))) 359 (tag-info (car (last context)))
358 (type (and tag-info (xml-lite-tag-type tag-info)))) 360 (type (and tag-info (xml-lite-tag-type tag-info))))
359 361