From: Stefan Monnier Date: Mon, 1 Apr 2002 23:32:15 +0000 (+0000) Subject: (sgml-at-indentation-p, sgml-tag) X-Git-Tag: ttn-vms-21-2-B4~15834 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2394187c2c96f22b59e785311187165f97b22755;p=emacs.git (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 --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el index 5b7034f8a80..8f3ba9c6a78 100644 --- a/lisp/textmodes/sgml-mode.el +++ b/lisp/textmodes/sgml-mode.el @@ -80,7 +80,7 @@ Including ?- has the problem of affecting dashes that have nothing to do 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 @@ Otherwise, it is set to be buffer-local when the file has (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 @@ Do \\[describe-key] on the following bindings to discover what they do. (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 @@ With prefix argument, unquote the region." (?> . ">")))))))) +(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 @@ With prefix argument, unquote the region." (> (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)