Mercurial > emacs
changeset 44244:31f1fc31fd45
(sgml-lexical-context): Return (text . START)
instead of nil when point is outside of any tag.
(sgml-beginning-of-tag): Adjust to the change.
(sgml-calculate-indent): Use the new info returned by
sgml-lexical-context. Try to handle unclosed tags.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Fri, 29 Mar 2002 22:20:15 +0000 |
parents | c3ee131a3ab1 |
children | 8bff6cc92867 |
files | lisp/textmodes/sgml-mode.el |
diffstat | 1 files changed, 42 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/textmodes/sgml-mode.el Fri Mar 29 22:16:38 2002 +0000 +++ b/lisp/textmodes/sgml-mode.el Fri Mar 29 22:20:15 2002 +0000 @@ -846,8 +846,7 @@ (defun sgml-lexical-context (&optional limit) "Return the lexical context at point as (TYPE . START). START is the location of the start of the lexical element. -TYPE is one of `string', `comment', `tag', `cdata', .... -Return nil if we are inside text (i.e. outside of any kind of tag). +TYPE is one of `string', `comment', `tag', or `text'. If non-nil LIMIT is a nearby position before point outside of any tag." ;; As usual, it's difficult to get a reliable answer without parsing the @@ -855,23 +854,26 @@ ;; any string or tag or comment or ... (save-excursion (let ((pos (point)) - (state nil)) + (state nil) + textstart) (if limit (goto-char limit) ;; Hopefully this regexp will match something that's not inside ;; a tag and also hopefully the match is nearby. (re-search-backward "^[ \t]*<[_:[:alpha:]/%!?#]" nil 'move)) + (setq textstart (point)) (with-syntax-table sgml-tag-syntax-table (while (< (point) pos) ;; When entering this loop we're inside text. + (setq textstart (point)) (skip-chars-forward "^<" pos) ;; We skipped text and reached a tag. Parse it. - ;; FIXME: this does not handle CDATA and funny stuff yet. + ;; FIXME: Handle net-enabling start-tags and <![CDATA[ ...]]>. (setq state (parse-partial-sexp (point) pos 0))) (cond ((nth 3 state) (cons 'string (nth 8 state))) ((nth 4 state) (cons 'comment (nth 8 state))) ((and state (> (nth 0 state) 0)) (cons 'tag (nth 1 state))) - (t nil)))))) + (t (cons 'text textstart))))))) (defun sgml-beginning-of-tag (&optional top-level) "Skip to beginning of tag and return its name. @@ -883,7 +885,7 @@ (when (looking-at sgml-tag-name-re) (match-string-no-properties 1))) (if top-level nil - (when context + (when (not (eq (car context) 'text)) (goto-char (cdr context)) (sgml-beginning-of-tag t)))))) @@ -968,22 +970,43 @@ (goto-char (1+ (cdr lcon))) (+ (current-column) sgml-basic-offset))) - (t + (t ;; text (while (looking-at "</") (forward-sexp 1) (skip-chars-forward " \t")) - (let ((context (xml-lite-get-context))) - (cond - ((null context) 0) ; no context - (t - (let ((here (point))) - (goto-char (xml-lite-tag-end (car context))) - (skip-chars-forward " \t\n") - (if (and (< (point) here) (xml-lite-at-indentation-p)) - (current-column) - (goto-char (xml-lite-tag-start (car context))) - (+ (current-column) - (* sgml-basic-offset (length context)))))))))))) + (let* ((here (point)) + (unclosed (and ;; (not sgml-xml-mode) + (looking-at sgml-tag-name-re) + (member-ignore-case (match-string 1) + sgml-unclosed-tags) + (match-string 1))) + (context + ;; If possible, align on the previous non-empty text line. + ;; Otherwise, do a more serious parsing to find the + ;; tag(s) relative to which we should be indenting. + (if (and (not unclosed) (skip-chars-backward " \t") + (< (skip-chars-backward " \t\n") 0) + (back-to-indentation) + (> (point) (cdr lcon))) + nil + (goto-char here) + (nreverse (xml-lite-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 + unclosed nil nil t))) + (setq context (cdr context))) + ;; Indent to reflect nesting. + (if (and context + (goto-char (xml-lite-tag-end (car context))) + (skip-chars-forward " \t\n") + (< (point) here) (xml-lite-at-indentation-p)) + (current-column) + (goto-char there) + (+ (current-column) + (* sgml-basic-offset (length context))))))))) (defun sgml-indent-line () "Indent the current line as SGML."