diff options
| author | Stefan Monnier | 2002-03-27 00:06:42 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-03-27 00:06:42 +0000 |
| commit | 63080afce880a4c067dfc2e7c5b04817070b82fe (patch) | |
| tree | 90dc253c2e73753e87f9733d32eee135b3d18fb7 | |
| parent | 5e73ebb4f7da7f3ab28ee7b28c84e34cd06dc877 (diff) | |
| download | emacs-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/ChangeLog | 16 | ||||
| -rw-r--r-- | lisp/textmodes/xml-lite.el | 205 |
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 @@ | |||
| 1 | 2002-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 | |||
| 1 | 2002-03-26 Juanma Barranquero <lektu@terra.es> | 12 | 2002-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 | ||
| 40 | 2002-03-24 Eli Zaretskii <eliz@is.elta.co.il> | 51 | 2002-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. | |||
| 185 | The context is a list of tag-info structures. The last one is the tag | 229 | The context is a list of tag-info structures. The last one is the tag |
| 186 | immediately enclosing the current position." | 230 | immediately 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 |