emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: xml-mode (from sgml-mode) tag skipping fix


From: Stefan Monnier
Subject: Re: xml-mode (from sgml-mode) tag skipping fix
Date: Thu, 31 Oct 2002 15:51:18 -0500

> The included patch allows `xml-mode' from sgml-mode.el to understand
> how to skip around XML-style empty tags:
> 
> Example:
> 
> <?xml version="1.0"?>
> <foo>
>   <bar>
>     <foo/>
>     <bar/>
>   </bar>
> </foo>
> 
> `C-c C-f' before the first <bar> should go to the end of the </bar>.
> `C-c C-b' after the last </foo> should go to the beginning of the
> first <foo>.

Thanks.  I believe that SGML should handle that as well (although
I'm not quite sure what <foo/> means in SGML) so I think we
could/should use the patch below instead.

Does anybody know better ?


        Stefan


--- sgml-mode.el.~1.91.~        Wed Oct 30 20:55:54 2002
+++ sgml-mode.el        Thu Oct 31 15:47:20 2002
@@ -691,43 +691,46 @@
     (if (looking-at "</\\([^ \n\t>]+\\)")
        ;; end tag, skip any nested pairs
        (let ((case-fold-search t)
-             (re (concat "</?" (regexp-quote (match-string 1)))))
+             (re (concat "</?" (regexp-quote (match-string 1))
+                         ;; Ignore empty tags like <foo/>.
+                         "\\([^>]*[^/]\\)?>")))
          (while (and (re-search-backward re nil t)
                      (eq (char-after (1+ (point))) ?/))
            (forward-char 1)
            (sgml-skip-tag-backward 1))))
     (setq arg (1- arg))))
 
-(defun sgml-skip-tag-forward (arg &optional return)
+(defun sgml-skip-tag-forward (arg)
   "Skip to end of tag or matching closing tag if present.
 With prefix argument ARG, repeat this ARG times.
 Return t iff after a closing tag."
   (interactive "p")
-  (setq return t)
+  (let ((return t))
   (while (>= arg 1)
     (skip-chars-forward "^<>")
     (if (eq (following-char) ?>)
        (up-list -1))
-    (if (looking-at "<\\([^/ \n\t>]+\\)")
+      (if (looking-at "<\\([^/ \n\t>]+\\)\\([^>]*[^/]\\)?>")
        ;; start tag, skip any nested same pairs _and_ closing tag
        (let ((case-fold-search t)
-             (re (concat "</?" (regexp-quote (match-string 1))))
+               (re (concat "</?" (regexp-quote (match-string 1))
+                           ;; Ignore empty tags like <foo/>.
+                           "\\([^>]*[^/]\\)?>"))
              point close)
          (forward-list 1)
          (setq point (point))
          (while (and (re-search-forward re nil t)
                      (not (setq close
                                 (eq (char-after (1+ (match-beginning 0))) ?/)))
-                     (not (up-list -1))
+                       (goto-char (match-beginning 0))
                      (sgml-skip-tag-forward 1))
            (setq close nil))
-         (if close
-             (up-list 1)
+           (unless close
            (goto-char point)
-           (setq return)))
+             (setq return nil)))
       (forward-list 1))
     (setq arg (1- arg)))
-  return)
+    return))
 
 (defun sgml-delete-tag (arg)
   "Delete tag on or after cursor, and matching closing or opening tag.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]