# HG changeset patch # User Stefan Monnier # Date 1017703935 0 # Node ID 96c839b7b4c29e80aac355c9c976242e6c269ee3 # Parent f532fa5aeca1b126d770cb26d254b567736a9b65 (sgml-at-indentation-p, sgml-tag) (sgml-parse-tag-name, sgml-looking-back-at, sgml-parse-tag-backward) (sgml-inside-tag-p, sgml-get-context, sgml-show-context) (sgml-insert-end-tag): New funs taken from xml-lite.el. (sgml-calculate-indent): Use them. (sgml-slash-matching): Rename from sgml-slash. (sgml-slash): Copied from xml-lite and changed to use sgml-slash-matching and sgml-quick-keys. diff -r f532fa5aeca1 -r 96c839b7b4c2 lisp/textmodes/sgml-mode.el --- a/lisp/textmodes/sgml-mode.el Mon Apr 01 23:10:26 2002 +0000 +++ b/lisp/textmodes/sgml-mode.el Mon Apr 01 23:32:15 2002 +0000 @@ -80,7 +80,7 @@ with comments, so we normally turn it off.") (defvar sgml-quick-keys nil - "Use <, >, &, SPC and `sgml-specials' keys \"electrically\" when non-nil. + "Use <, >, &, /, SPC and `sgml-specials' keys \"electrically\" when non-nil. This takes effect when first loading the `sgml-mode' library.") @@ -384,7 +384,7 @@ (define-derived-mode sgml-mode text-mode "SGML" "Major mode for editing SGML documents. Makes > match <. -Keys <, &, SPC within <>, \" and ' can be electric depending on +Keys <, &, SPC within <>, \", / and ' can be electric depending on `sgml-quick-keys'. An argument of N to a tag-inserting command means to wrap it around @@ -450,6 +450,22 @@ (defun sgml-slash (arg) + "Insert ARG slash characters. +Behaves electrically if `sgml-quick-keys' is non-nil." + (interactive "p") + (cond + ((not (and (eq (char-before) ?<) (= arg 1))) + (sgml-slash-matching arg)) + ((eq sgml-quick-keys 'indent) + (insert-char ?/ 1) + (indent-according-to-mode)) + ((eq sgml-quick-keys 'close) + (delete-backward-char 1) + (sgml-insert-end-tag)) + (t + (sgml-slash-matching arg)))) + +(defun sgml-slash-matching (arg) "Insert `/' and display any previous matching `/'. Two `/'s are treated as matching if the first `/' ends a net-enabling start tag, and the second `/' is the corresponding null end tag." @@ -925,6 +941,190 @@ (?> . ">")))))))) +(defsubst sgml-at-indentation-p () + "Return true if point is at the first non-whitespace character on the line." + (save-excursion + (skip-chars-backward " \t") + (bolp))) + + +;; Parsing + +(defstruct (sgml-tag + (:constructor sgml-make-tag (type start end name))) + type start end name) + +(defsubst sgml-parse-tag-name () + "Skip past a tag-name, and return the name." + (buffer-substring-no-properties + (point) (progn (skip-syntax-forward "w_") (point)))) + +(defsubst sgml-looking-back-at (s) + (let ((limit (max (- (point) (length s)) (point-min)))) + (equal s (buffer-substring-no-properties limit (point))))) + +(defun sgml-parse-tag-backward () + "Parse an SGML tag backward, and return information about the tag. +Assume that parsing starts from within a textual context. +Leave point at the beginning of the tag." + (let (tag-type tag-start tag-end name) + (search-backward ">") + (setq tag-end (1+ (point))) + (cond + ((sgml-looking-back-at "--") ; comment + (setq tag-type 'comment + tag-start (search-backward "") + ((eq type 'cdata) "]]>") + ((eq type 'jsp) "%>") + ((eq type 'pi) "?>") + (t ">")))) + + ;; inside an element + ((eq type 'open) + (insert "") + (indent-according-to-mode)) + + (t + (error "Nothing to close"))))) + (defun sgml-empty-tag-p (tag-name) "Return non-nil if TAG-NAME is an implicitly empty tag." (and (not sgml-xml-mode) @@ -1003,19 +1203,19 @@ (> (point) (cdr lcon))) nil (goto-char here) - (nreverse (xml-lite-get-context (if unclosed nil 'empty))))) + (nreverse (sgml-get-context (if unclosed nil 'empty))))) (there (point))) ;; Ignore previous unclosed start-tag in context. (while (and context unclosed (eq t (compare-strings - (xml-lite-tag-name (car context)) nil nil + (sgml-tag-name (car context)) nil nil unclosed nil nil t))) (setq context (cdr context))) ;; Indent to reflect nesting. (if (and context - (goto-char (xml-lite-tag-end (car context))) + (goto-char (sgml-tag-end (car context))) (skip-chars-forward " \t\n") - (< (point) here) (xml-lite-at-indentation-p)) + (< (point) here) (sgml-at-indentation-p)) (current-column) (goto-char there) (+ (current-column)