43 |
(require 'sgml-mode) |
(require 'sgml-mode) |
44 |
|
|
45 |
|
|
|
;; Variables |
|
|
|
|
|
(defgroup xml-lite nil |
|
|
"Customizable variables for XML-Lite mode." |
|
|
:group 'languages |
|
|
) |
|
|
|
|
|
(defcustom xml-lite-basic-offset 2 |
|
|
"*Specifies the basic indentation level for `xml-lite-indent-line'." |
|
|
:type 'integer |
|
|
:group 'xml-lite |
|
|
) |
|
|
|
|
|
(defcustom xml-lite-electric-slash 'close |
|
|
"*If non-nil, inserting a '/' after a '<' behaves electrically. |
|
|
If set to `indent', typing '</' just triggers reindentation. |
|
|
If set to `close', typing '</' inserts an end-tag for the |
|
|
enclosing XML element." |
|
|
:type '(choice (const :tag "Indent" indent) |
|
|
|
|
|
(const :tag "Close" close) |
|
|
(const :tag "No" nil)) |
|
|
|
|
|
:group 'xml-lite |
|
|
) |
|
|
|
|
|
(defcustom xml-lite-mode-line-string " XML" |
|
|
"*String to display in the modeline when `xml-lite-mode' is active. |
|
|
Set this to nil if you don't want a modeline indicator for xml-lite-mode." |
|
|
:type 'string |
|
|
:group 'xml-lite) |
|
|
|
|
|
(defcustom xml-lite-mode-hook nil |
|
|
"*Hook called by `xml-lite-mode'." |
|
|
:type 'hook |
|
|
:group 'xml-lite) |
|
|
|
|
|
;;;###autoload |
|
|
(defvar xml-lite-mode nil |
|
|
"Non-nil if `xml-lite-mode' is enabled.") |
|
|
(make-variable-buffer-local 'xml-lite-mode) |
|
|
|
|
|
|
|
46 |
;; Syntax analysis |
;; Syntax analysis |
47 |
|
|
48 |
(defsubst xml-lite-at-indentation-p () |
(defsubst xml-lite-at-indentation-p () |
51 |
(skip-chars-backward " \t") |
(skip-chars-backward " \t") |
52 |
(bolp))) |
(bolp))) |
53 |
|
|
|
(defun xml-lite-in-string-p (&optional limit) |
|
|
"Determine whether point is inside a string. If it is, return the |
|
|
position of the character starting the string, else return nil. |
|
|
|
|
|
Parse begins from LIMIT, which defaults to the preceding occurence of a tag |
|
|
at the beginning of a line." |
|
|
(let ((context (sgml-lexical-context limit))) |
|
|
(if (eq (car context) 'string) (cdr context)))) |
|
|
|
|
54 |
|
|
55 |
;; Parsing |
;; Parsing |
56 |
(defstruct (xml-lite-tag |
(defstruct (xml-lite-tag |
170 |
;; enclosing start-tags we'll have to ignore. |
;; enclosing start-tags we'll have to ignore. |
171 |
(skip-chars-backward " \t\n") ; Make sure we're not at indentation. |
(skip-chars-backward " \t\n") ; Make sure we're not at indentation. |
172 |
(while |
(while |
173 |
(and (or ignore (not (if full (eq full 'empty) context)) |
(and (or ignore |
174 |
|
(not (if full (eq full 'empty) context)) |
175 |
(not (xml-lite-at-indentation-p)) |
(not (xml-lite-at-indentation-p)) |
176 |
(and (not sgml-xml-mode) context |
(and (not sgml-xml-mode) context |
177 |
(/= (point) (xml-lite-tag-start (car context))) |
(/= (point) (xml-lite-tag-start (car context))) |
182 |
;; This tag may enclose things we thought were tags. If so, |
;; This tag may enclose things we thought were tags. If so, |
183 |
;; discard them. |
;; discard them. |
184 |
(while (and context |
(while (and context |
185 |
(> (xml-lite-tag-end tag-info) |
(> (xml-lite-tag-end tag-info) |
186 |
(xml-lite-tag-end (car context)))) |
(xml-lite-tag-end (car context)))) |
187 |
(setq context (cdr context))) |
(setq context (cdr context))) |
188 |
|
|
189 |
(cond |
(cond |
190 |
|
|
238 |
(pp (save-excursion (xml-lite-get-context full))))) |
(pp (save-excursion (xml-lite-get-context full))))) |
239 |
|
|
240 |
|
|
|
;; Indenting |
|
|
|
|
|
|
|
241 |
;; Editing shortcuts |
;; Editing shortcuts |
242 |
|
|
243 |
(defun xml-lite-insert-end-tag () |
(defun xml-lite-insert-end-tag () |
286 |
(t |
(t |
287 |
(insert-char ?/ arg)))) |
(insert-char ?/ arg)))) |
288 |
|
|
|
|
|
|
;; Keymap |
|
|
|
|
|
(defvar xml-lite-mode-map |
|
|
(let ((map (make-sparse-keymap))) |
|
|
(define-key map "\C-c/" 'xml-lite-insert-end-tag) |
|
|
(define-key map "\C-c\C-s" 'xml-lite-show-context) |
|
|
(define-key map "/" 'xml-lite-slash) |
|
|
map) |
|
|
"Key bindings for `xml-lite-mode'.") |
|
|
|
|
|
|
|
|
;; Minor mode |
|
|
|
|
|
;;;###autoload |
|
|
(define-minor-mode xml-lite-mode |
|
|
"Toggle `xml-lite-mode'. |
|
|
With ARG, enable xml-lite-mode if and only if ARG is positive. |
|
|
|
|
|
xml-lite-mode provides indentation for XML tags. The value of |
|
|
`xml-lite-basic-offset' determines the amount of indentation. |
|
|
|
|
|
Key bindings: |
|
|
\\{xml-lite-mode-map}" |
|
|
nil ; initial value |
|
|
" XML" ; mode indicator |
|
|
'xml-lite-mode-map ; keymap |
|
|
(if xml-lite-mode |
|
|
(progn |
|
|
(if (eq major-mode 'fundamental-mode) (sgml-mode)) |
|
|
(set (make-local-variable 'sgml-xml-mode) t) |
|
|
(set (make-local-variable 'xml-lite-orig-indent-line-function) |
|
|
indent-line-function) |
|
|
(set (make-local-variable 'indent-line-function) 'sgml-indent-line)) |
|
|
(kill-local-variable 'sgml-xml-mode) |
|
|
(setq indent-line-function xml-lite-orig-indent-line-function))) |
|
|
|
|
289 |
(provide 'xml-lite) |
(provide 'xml-lite) |
290 |
|
|
291 |
;;; xml-lite.el ends here |
;;; xml-lite.el ends here |