Mercurial > emacs
annotate lisp/textmodes/xml-lite.el @ 44242:84ff52bf6d2f
(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.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Fri, 29 Mar 2002 20:10:46 +0000 |
parents | 2eeb8d7f1161 |
children | c3ee131a3ab1 |
rev | line source |
---|---|
43687 | 1 ;;; xml-lite.el --- an indentation-engine for XML |
2 | |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
3 ;; Copyright (C) 2002 Free Software Foundation, Inc. |
43687 | 4 |
5 ;; Author: Mike Williams <mdub@bigfoot.com> | |
6 ;; Created: February 2001 | |
7 ;; Keywords: xml | |
8 | |
9 ;; This file is part of GNU Emacs. | |
10 | |
11 ;; This program is free software; you can redistribute it and/or modify | |
12 ;; it under the terms of the GNU General Public License as published by | |
13 ;; the Free Software Foundation; either version 2 of the License, or | |
14 ;; (at your option) any later version. | |
15 ;; | |
16 ;; This program is distributed in the hope that it will be useful, | |
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 ;; GNU General Public License for more details. | |
20 ;; | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
24 ;; Boston, MA 02111-1307, USA. | |
25 | |
26 ;;; Commentary: | |
27 ;; | |
28 ;; This package provides a simple indentation engine for XML. It is | |
29 ;; intended for use in situations where the full power of the popular PSGML | |
30 ;; package (DTD parsing, syntax checking) is not required. | |
31 ;; | |
32 ;; xml-lite is designed to be used in conjunction with the default GNU | |
33 ;; Emacs sgml-mode, to provide a lightweight XML-editing environment. | |
34 | |
35 ;;; Thanks: | |
36 ;; | |
37 ;; Jens Schmidt <Jens.Schmidt@oracle.com> | |
38 ;; for his feedback and suggestions | |
39 | |
40 ;;; Code: | |
41 | |
42 (eval-when-compile (require 'cl)) | |
43 (require 'sgml-mode) | |
44 | |
45 | |
46 ;; Variables | |
47 | |
48 (defgroup xml-lite nil | |
49 "Customizable variables for XML-Lite mode." | |
50 :group 'languages | |
51 ) | |
52 | |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
53 (defcustom xml-lite-basic-offset 2 |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
54 "*Specifies the basic indentation level for `xml-lite-indent-line'." |
43687 | 55 :type 'integer |
56 :group 'xml-lite | |
57 ) | |
58 | |
59 (defcustom xml-lite-electric-slash 'close | |
60 "*If non-nil, inserting a '/' after a '<' behaves electrically. | |
61 If set to `indent', typing '</' just triggers reindentation. | |
62 If set to `close', typing '</' inserts an end-tag for the | |
63 enclosing XML element." | |
64 :type '(choice (const :tag "Indent" indent) | |
65 | |
66 (const :tag "Close" close) | |
67 (const :tag "No" nil)) | |
68 | |
69 :group 'xml-lite | |
70 ) | |
71 | |
72 (defcustom xml-lite-mode-line-string " XML" | |
73 "*String to display in the modeline when `xml-lite-mode' is active. | |
74 Set this to nil if you don't want a modeline indicator for xml-lite-mode." | |
75 :type 'string | |
76 :group 'xml-lite) | |
77 | |
78 (defcustom xml-lite-mode-hook nil | |
79 "*Hook called by `xml-lite-mode'." | |
80 :type 'hook | |
81 :group 'xml-lite) | |
82 | |
83 ;;;###autoload | |
84 (defvar xml-lite-mode nil | |
85 "Non-nil if `xml-lite-mode' is enabled.") | |
86 (make-variable-buffer-local 'xml-lite-mode) | |
87 | |
88 | |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
89 ;; Syntax analysis |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
90 |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
91 (defsubst xml-lite-at-indentation-p () |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
92 "Return true if point is at the first non-whitespace character on the line." |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
93 (save-excursion |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
94 (skip-chars-backward " \t") |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
95 (bolp))) |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
96 |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
97 (defun xml-lite-in-string-p (&optional limit) |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
98 "Determine whether point is inside a string. If it is, return the |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
99 position of the character starting the string, else return nil. |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
100 |
44189
ee2adfa7e248
(xml-lite-in-string-p): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44187
diff
changeset
|
101 Parse begins from LIMIT, which defaults to the preceding occurence of a tag |
ee2adfa7e248
(xml-lite-in-string-p): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44187
diff
changeset
|
102 at the beginning of a line." |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
103 (let ((context (sgml-lexical-context limit))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
104 (if (eq (car context) 'string) (cdr context)))) |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
105 |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
106 |
43687 | 107 ;; Parsing |
108 (defstruct (xml-lite-tag | |
109 (:constructor xml-lite-make-tag (type start end name name-end))) | |
110 type start end name name-end) | |
111 (defsubst xml-lite-parse-tag-name () | |
112 "Skip past a tag-name, and return the name." | |
44180
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
113 (buffer-substring-no-properties |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
114 (point) (progn (skip-syntax-forward "w_") (point)))) |
43687 | 115 |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
116 (defsubst xml-lite-looking-back-at (s) |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
117 (let ((limit (max (- (point) (length s)) (point-min)))) |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
118 (equal s (buffer-substring-no-properties limit (point))))) |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
119 |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
120 (defsubst xml-lite-looking-at (s) |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
121 (let ((limit (min (+ (point) (length s))))) |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
122 (equal s (buffer-substring-no-properties (point) limit)))) |
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
123 |
43687 | 124 (defun xml-lite-parse-tag-backward () |
125 "Get information about the parent tag." | |
126 (let ((limit (point)) | |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
127 tag-type tag-start tag-end name name-end) |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
128 (with-syntax-table sgml-tag-syntax-table |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
129 (cond |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
130 |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
131 ((null (re-search-backward "[<>]" nil t))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
132 |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
133 ((= ?> (char-after)) ;--- found tag-end --- |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
134 (setq tag-end (1+ (point))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
135 (goto-char tag-end) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
136 (cond |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
137 ((xml-lite-looking-back-at "--") ; comment |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
138 (setq tag-type 'comment |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
139 tag-start (search-backward "<!--" nil t))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
140 ((xml-lite-looking-back-at "]]>") ; cdata |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
141 (setq tag-type 'cdata |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
142 tag-start (search-backward "![CDATA[" nil t))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
143 (t |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
144 (setq tag-start (ignore-errors (backward-sexp) (point)))))) |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
145 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
146 ((= ?< (char-after)) ;--- found tag-start --- |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
147 ;; !!! This should not happen because the caller should be careful |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
148 ;; that we do not start from within a tag !!! |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
149 (setq tag-start (point)) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
150 (goto-char (1+ tag-start)) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
151 (cond |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
152 ((xml-lite-looking-at "!--") ; comment |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
153 (setq tag-type 'comment |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
154 tag-end (search-forward "-->" nil t))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
155 ((xml-lite-looking-at "![CDATA[") ; cdata |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
156 (setq tag-type 'cdata |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
157 tag-end (search-forward "]]>" nil t))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
158 (t |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
159 (goto-char tag-start) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
160 (setq tag-end (ignore-errors (forward-sexp) (point))))))) |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
161 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
162 (cond |
43687 | 163 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
164 ((or tag-type (null tag-start))) |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
165 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
166 ((= ?! (char-after (1+ tag-start))) ; declaration |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
167 (setq tag-type 'decl)) |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
168 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
169 ((= ?? (char-after (1+ tag-start))) ; processing-instruction |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
170 (setq tag-type 'pi)) |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
171 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
172 ((= ?/ (char-after (1+ tag-start))) ; close-tag |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
173 (goto-char (+ 2 tag-start)) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
174 (setq tag-type 'close |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
175 name (xml-lite-parse-tag-name) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
176 name-end (point))) |
43687 | 177 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
178 ((member ; JSP tags etc |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
179 (char-after (1+ tag-start)) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
180 '(?% ?#)) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
181 (setq tag-type 'unknown)) |
43687 | 182 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
183 (t |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
184 (goto-char (1+ tag-start)) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
185 (setq tag-type 'open |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
186 name (xml-lite-parse-tag-name) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
187 name-end (point)) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
188 ;; check whether it's an empty tag |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
189 (if (or (and tag-end (eq ?/ (char-before (- tag-end 1)))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
190 (and (not sgml-xml-mode) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
191 (member-ignore-case name sgml-empty-tags))) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
192 (setq tag-type 'empty)))) |
43687 | 193 |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
194 (cond |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
195 (tag-start |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
196 (goto-char tag-start) |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
197 (xml-lite-make-tag tag-type tag-start tag-end name name-end)))))) |
43687 | 198 |
199 (defsubst xml-lite-inside-tag-p (tag-info &optional point) | |
200 "Return true if TAG-INFO contains the POINT." | |
201 (let ((end (xml-lite-tag-end tag-info)) | |
202 (point (or point (point)))) | |
203 (or (null end) | |
204 (> end point)))) | |
205 | |
206 (defun xml-lite-get-context (&optional full) | |
207 "Determine the context of the current position. | |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
208 If FULL is `empty', return even if the context is empty (i.e. |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
209 we just skipped over some element and got to a beginning of line). |
43687 | 210 If FULL is non-nil, parse back to the beginning of the buffer, otherwise |
211 parse until we find a start-tag as the first thing on a line. | |
212 | |
213 The context is a list of tag-info structures. The last one is the tag | |
214 immediately enclosing the current position." | |
215 (let ((here (point)) | |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
216 (ignore nil) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
217 (context nil) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
218 tag-info) |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
219 ;; CONTEXT keeps track of the tag-stack |
44201
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
220 ;; IGNORE keeps track of the nesting level of point relative to the |
2eeb8d7f1161
(xml-lite-in-string-p): Use sgml-lexical-context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44189
diff
changeset
|
221 ;; first (outermost) tag on the context. This is the list of |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
222 ;; enclosing start-tags we'll have to ignore. |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
223 (skip-chars-backward " \t\n") ; Make sure we're not at indentation. |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
224 (while |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
225 (and (or ignore (not (if full (eq full 'empty) context)) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
226 (not (xml-lite-at-indentation-p))) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
227 (setq tag-info (xml-lite-parse-tag-backward))) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
228 |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
229 ;; This tag may enclose things we thought were tags. If so, |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
230 ;; discard them. |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
231 (while (and context |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
232 (> (xml-lite-tag-end tag-info) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
233 (xml-lite-tag-end (car context)))) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
234 (setq context (cdr context))) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
235 |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
236 (cond |
43687 | 237 |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
238 ;; inside a tag ... |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
239 ((xml-lite-inside-tag-p tag-info here) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
240 (push tag-info context)) |
43687 | 241 |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
242 ;; start-tag |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
243 ((eq (xml-lite-tag-type tag-info) 'open) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
244 (cond |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
245 ((null ignore) (push tag-info context)) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
246 ((eq t (compare-strings (xml-lite-tag-name tag-info) nil nil |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
247 (car ignore) nil nil t)) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
248 (setq ignore (cdr ignore))) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
249 (t |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
250 ;; The open and close tags don't match. |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
251 (if (not sgml-xml-mode) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
252 ;; Assume the open tag is simply not closed. |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
253 (unless (member-ignore-case (xml-lite-tag-name tag-info) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
254 sgml-unclosed-tags) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
255 (message "Unclosed tag <%s>" (xml-lite-tag-name tag-info))) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
256 (message "Unmatched tags <%s> and </%s>" |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
257 (xml-lite-tag-name tag-info) (pop ignore)))))) |
43687 | 258 |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
259 ;; end-tag |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
260 ((eq (xml-lite-tag-type tag-info) 'close) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
261 (if (and (not sgml-xml-mode) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
262 (member-ignore-case (xml-lite-tag-name tag-info) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
263 sgml-empty-tags)) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
264 (message "Spurious </%s>: empty tag" (xml-lite-tag-name tag-info)) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
265 (push (xml-lite-tag-name tag-info) ignore))) |
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
266 )) |
43687 | 267 |
268 ;; return context | |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
269 context)) |
43687 | 270 |
271 (defun xml-lite-show-context (&optional full) | |
272 "Display the current context. | |
273 If FULL is non-nil, parse back to the beginning of the buffer." | |
274 (interactive "P") | |
275 (with-output-to-temp-buffer "*XML Context*" | |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
276 (pp (save-excursion (xml-lite-get-context full))))) |
43687 | 277 |
278 | |
279 ;; Indenting | |
280 | |
281 (defun xml-lite-calculate-indent () | |
282 "Calculate the column to which this line should be indented." | |
283 (let* ((here (point)) | |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
284 (context (save-excursion (xml-lite-get-context))) |
43687 | 285 (ref-tag-info (car context)) |
286 (last-tag-info (car (last context)))) | |
287 | |
288 (save-excursion | |
289 (cond | |
290 | |
291 ;; no context | |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
292 ((null context) 0) |
43687 | 293 |
294 ;; inside a comment | |
295 ((eq 'comment (xml-lite-tag-type last-tag-info)) | |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
296 (let ((mark (looking-at "--"))) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
297 (goto-char (xml-lite-tag-start last-tag-info)) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
298 (forward-char 2) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
299 (if mark (current-column) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
300 (forward-char 2) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
301 (+ (if (zerop (skip-chars-forward " \t")) 1 0) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
302 (current-column))))) |
43687 | 303 |
304 ;; inside a tag | |
305 ((xml-lite-inside-tag-p last-tag-info here) | |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
306 |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
307 (let ((start-of-enclosing-string |
44168
68fd324f9f0f
(xml-lite-at-indentation-p): Move.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
43687
diff
changeset
|
308 (xml-lite-in-string-p (xml-lite-tag-start last-tag-info)))) |
43687 | 309 (cond |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
310 ;; inside an attribute value |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
311 (start-of-enclosing-string |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
312 (goto-char start-of-enclosing-string) |
43687 | 313 (1+ (current-column))) |
314 ;; if we have a tag-name, base indent on that | |
315 ((and (xml-lite-tag-name-end last-tag-info) | |
316 (progn | |
317 (goto-char (xml-lite-tag-name-end last-tag-info)) | |
318 (not (looking-at "[ \t]*$")))) | |
319 (1+ (current-column))) | |
320 ;; otherwise, add indent-offset | |
321 (t | |
322 (goto-char (xml-lite-tag-start last-tag-info)) | |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
323 (+ (current-column) xml-lite-basic-offset))))) |
43687 | 324 |
325 ;; inside an element | |
326 (t | |
327 ;; indent to start of tag | |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
328 (let ((indent-offset xml-lite-basic-offset)) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
329 ;; add xml-lite-basic-offset, unless we're looking at the |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
330 ;; matching end-tag |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
331 (if (and (eq (length context) 1) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
332 (xml-lite-looking-at "</")) |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
333 (setq indent-offset 0)) |
43687 | 334 (goto-char (xml-lite-tag-start ref-tag-info)) |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
335 (+ (current-column) indent-offset))) |
43687 | 336 |
337 )))) | |
338 | |
339 (defun xml-lite-indent-line () | |
340 "Indent the current line as XML." | |
341 (interactive) | |
44180
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
342 (let* ((savep (point)) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
343 (indent-col |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
344 (save-excursion |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
345 (back-to-indentation) |
44180
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
346 (if (>= (point) savep) (setq savep nil)) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
347 (xml-lite-calculate-indent)))) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
348 (if savep |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
349 (save-excursion (indent-line-to indent-col)) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
350 (indent-line-to indent-col)))) |
43687 | 351 |
352 | |
353 ;; Editing shortcuts | |
354 | |
355 (defun xml-lite-insert-end-tag () | |
356 "Insert an end-tag for the current element." | |
357 (interactive) | |
44242
84ff52bf6d2f
(xml-lite-get-context): Allow stopping even with an empty context.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44201
diff
changeset
|
358 (let* ((context (save-excursion (xml-lite-get-context))) |
43687 | 359 (tag-info (car (last context))) |
360 (type (and tag-info (xml-lite-tag-type tag-info)))) | |
361 | |
362 (cond | |
363 | |
364 ((null context) | |
365 (error "Nothing to close")) | |
366 | |
367 ;; inside a tag | |
368 ((xml-lite-inside-tag-p tag-info) | |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
369 (insert (cond |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
370 ((eq type 'open) " />") |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
371 ((eq type 'comment) " -->") |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
372 ((eq type 'cdata) "]]>") |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
373 ((eq type 'jsp) "%>") |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
374 ((eq type 'pi) "?>") |
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
375 (t ">")))) |
43687 | 376 |
377 ;; inside an element | |
378 ((eq type 'open) | |
379 (insert "</" (xml-lite-tag-name tag-info) ">") | |
44180
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
380 (indent-according-to-mode)) |
43687 | 381 |
382 (t | |
383 (error "Nothing to close"))))) | |
384 | |
385 (defun xml-lite-slash (arg) | |
386 "Insert ARG slash characters. | |
387 Behaves electrically if `xml-lite-electric-slash' is non-nil." | |
388 (interactive "p") | |
389 (cond | |
390 ((not (and (eq (char-before) ?<) (= arg 1))) | |
391 (insert-char ?/ arg)) | |
392 ((eq xml-lite-electric-slash 'indent) | |
393 (insert-char ?/ 1) | |
44180
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
394 (indent-according-to-mode)) |
43687 | 395 ((eq xml-lite-electric-slash 'close) |
396 (delete-backward-char 1) | |
397 (xml-lite-insert-end-tag)) | |
398 (t | |
399 (insert-char ?/ arg)))) | |
400 | |
401 | |
402 ;; Keymap | |
403 | |
404 (defvar xml-lite-mode-map | |
405 (let ((map (make-sparse-keymap))) | |
406 (define-key map "\C-c/" 'xml-lite-insert-end-tag) | |
407 (define-key map "\C-c\C-s" 'xml-lite-show-context) | |
408 (define-key map "/" 'xml-lite-slash) | |
409 map) | |
410 "Key bindings for `xml-lite-mode'.") | |
411 | |
412 | |
413 ;; Minor mode | |
414 | |
415 ;;;###autoload | |
416 (define-minor-mode xml-lite-mode | |
417 "Toggle `xml-lite-mode'. | |
418 With ARG, enable xml-lite-mode if and only if ARG is positive. | |
419 | |
420 xml-lite-mode provides indentation for XML tags. The value of | |
44187
65437de0940f
Fix copyright notice.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44180
diff
changeset
|
421 `xml-lite-basic-offset' determines the amount of indentation. |
43687 | 422 |
423 Key bindings: | |
424 \\{xml-lite-mode-map}" | |
425 nil ; initial value | |
426 " XML" ; mode indicator | |
427 'xml-lite-mode-map ; keymap | |
428 (if xml-lite-mode | |
429 (progn | |
44180
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
430 (if (eq major-mode 'fundamental-mode) (sgml-mode)) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
431 (set (make-local-variable 'sgml-xml-mode) t) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
432 (set (make-local-variable 'xml-lite-orig-indent-line-function) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
433 indent-line-function) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
434 (set (make-local-variable 'indent-line-function) 'xml-lite-indent-line)) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
435 (kill-local-variable 'sgml-xml-mode) |
e7a365c909ff
Don't require `custom'.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
44168
diff
changeset
|
436 (setq indent-line-function xml-lite-orig-indent-line-function))) |
43687 | 437 |
438 (provide 'xml-lite) | |
439 | |
440 ;;; xml-lite.el ends here |