diff --git a/lisp/nxml/nxml-mode.el b/lisp/nxml/nxml-mode.el index 3869d0327fd..7317f7186ff 100644 --- a/lisp/nxml/nxml-mode.el +++ b/lisp/nxml/nxml-mode.el @@ -1378,60 +1378,35 @@ nxml-compute-indent-from-previous-line (not (or (= xmltok-start (point)) (eq xmltok-type 'data)))))) (setq ref (point)) - ;; Now scan over tokens until the end of the line to be indented. - ;; Determine the context before and after the beginning of the - ;; line. - (while (< (point) eol) - (nxml-tokenize-forward) - (cond ((<= bol xmltok-start) - (setq after-context - (nxml-merge-indent-context-type after-context))) - ((and (<= (point) bol) - (not (and (eq xmltok-type 'partial-start-tag) - (= (point) bol)))) - (setq before-context - (nxml-merge-indent-context-type before-context))) - ((eq xmltok-type 'data) - (setq before-context - (nxml-merge-indent-context-type before-context)) - (setq after-context - (nxml-merge-indent-context-type after-context))) - ;; If in the middle of a token that looks inline, - ;; then indent relative to the previous non-blank line - ((eq (nxml-merge-indent-context-type before-context) - 'mixed) - (goto-char prev-bol) - (throw 'indent (current-column))) - (t - (throw 'indent - (nxml-compute-indent-in-token bol)))) - (skip-chars-forward " \t\r\n")) - (goto-char ref) - (+ (current-column) - (* nxml-child-indent - (+ (if (eq before-context 'start-tag) 1 0) - (if (eq after-context 'end-tag) -1 0)))))))) - -(defun nxml-merge-indent-context-type (context) - "Merge the indent context type CONTEXT with the token in `xmltok-type'. -Return the merged indent context type. An indent context type is -either nil or one of the symbols `start-tag', `end-tag', `markup', -`comment', `mixed'." - (cond ((memq xmltok-type '(start-tag partial-start-tag)) - (if (memq context '(nil start-tag comment)) - 'start-tag - 'mixed)) - ((memq xmltok-type '(end-tag partial-end-tag)) - (if (memq context '(nil end-tag comment)) - 'end-tag - 'mixed)) - ((eq xmltok-type 'comment) - (cond ((memq context '(start-tag end-tag comment)) - context) - (context 'mixed) - (t 'comment))) - (context 'mixed) - (t 'markup))) + ;; scan over the prevous line to determine the additional + ;; depth of element nesting. Also collect the depth change at + ;; the beginning of the line. + (let ((depth-before 0) + (depth-bol 0)) + (nxml-tokenize-forward) + (when (> (point) bol) ; one token spans this and the line before + (throw 'indent (nxml-compute-indent-in-token bol))) + (while (< (point) bol) + (cond ((eq xmltok-type 'partial-start-tag) + (throw 'indent (nxml-compute-indent-in-token bol))) + ((memq xmltok-type '(start-tag)) + (cl-incf depth-before)) + ((memq xmltok-type '(end-tag partial-end-tag)) + (cl-incf depth-before -1))) + (skip-chars-forward " \t\r\n") + (nxml-tokenize-forward)) + (when (<= xmltok-start eol) + (cond ((memq xmltok-type '(start-tag partial-start-tag data)) + (setq depth-bol 1)) + ((memq xmltok-type '(end-tag partial-end-tag)) + (setq depth-bol -1)))) + (goto-char ref) + (+ (current-column) + (* nxml-child-indent + ;; never change more than one indent level + (cl-signum (if (eq depth-before 0) + (min 0 depth-bol) + (+ (cl-signum depth-before) depth-bol)))))))))) (defun nxml-compute-indent-in-token (pos) "Return the indent for a line that starts inside a token. diff --git a/test/lisp/nxml/nxml-mode-tests.el b/test/lisp/nxml/nxml-mode-tests.el index 973f2ebb67e..f5a691ee181 100644 --- a/test/lisp/nxml/nxml-mode-tests.el +++ b/test/lisp/nxml/nxml-mode-tests.el @@ -31,6 +31,17 @@ nxml-mode-tests-correctly-indented-string (ert-deftest nxml-indent-line-after-attribute () (should (nxml-mode-tests-correctly-indented-string " + + + ... + + +")) + (should (nxml-mode-tests-correctly-indented-string " + + abc + 123 + + + +")) + (should (nxml-mode-tests-correctly-indented-string " + + abc + + + +")) + (should (nxml-mode-tests-correctly-indented-string " + + + + abckde + + e + + + + + + + x + + abc + abc + + abc + +")))) +x + (provide 'nxml-mode-tests) ;;; nxml-mode-tests.el ends here