diff --git a/lisp/org.el b/lisp/org.el index 29b98a3df..e93000418 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -22738,7 +22738,7 @@ ELEMENT." (goto-char start) (org-get-indentation)))) ((memq type '(headline inlinetask nil)) - (if (save-excursion (beginning-of-line) (looking-at "[ \t]*$")) + (if (org-match-line "[ \t]*$") (org--get-expected-indentation element t) 0)) ((memq type '(diary-sexp footnote-definition)) 0) @@ -22890,6 +22890,13 @@ Also align node properties according to `org-property-format'." (= (line-beginning-position) (org-element-property :post-affiliated element))) 'noindent) + ((and (eq type 'latex-environment) + (>= (point) (org-element-property :post-affiliated element)) + (< (point) (org-with-wide-buffer + (goto-char (org-element-property :end element)) + (skip-chars-backward " \r\t\n") + (line-beginning-position 2)))) + 'noindent) ((and (eq type 'src-block) org-src-tab-acts-natively (> (line-beginning-position) @@ -22941,22 +22948,38 @@ assumed to be significant there." (element-end (copy-marker (org-element-property :end element))) (ind (org--get-expected-indentation element nil))) (cond + ;; Element indented as a single block. Example blocks + ;; preserving indentation are a special case since the + ;; "contents" must not be indented whereas the block + ;; boundaries can. + ((or (memq type '(export-block latex-environment)) + (and (eq type 'example-block) + (not + (or org-src-preserve-indentation + (org-element-property :preserve-indent element))))) + (let ((offset (- ind (org-get-indentation)))) + (unless (zerop offset) + (indent-rigidly (org-element-property :begin element) + (org-element-property :end element) + offset))) + (goto-char element-end)) + ;; Elements indented line wise. Be sure to exclude + ;; example blocks (preserving indentation) and source + ;; blocks from this category as they are treated + ;; specially later. ((or (memq type '(paragraph table table-row)) (not (or (org-element-property :contents-begin element) - (memq type - '(example-block export-block src-block))))) - ;; Elements here are indented as a single block. Also - ;; align node properties. + (memq type '(example-block src-block))))) (when (eq type 'node-property) (org--align-node-property) (beginning-of-line)) (funcall indent-to ind (min element-end end))) + ;; Elements consisting of three parts: before the + ;; contents, the contents, and after the contents. The + ;; contents are treated specially, according to the + ;; element type, or not indented at all. Other parts are + ;; indented as a single block. (t - ;; Elements in this category consist of three parts: - ;; before the contents, the contents, and after the - ;; contents. The contents are treated specially, - ;; according to the element type, or not indented at - ;; all. Other parts are indented as a single block. (let* ((post (copy-marker (org-element-property :post-affiliated element))) (cbeg @@ -22966,8 +22989,7 @@ assumed to be significant there." ;; Fake contents for source blocks. (org-with-wide-buffer (goto-char post) - (forward-line) - (point))) + (line-beginning-position 2))) ((memq type '(footnote-definition item plain-list)) ;; Contents in these elements could start on ;; the same line as the beginning of the @@ -23001,7 +23023,7 @@ assumed to be significant there." (t (funcall indent-to ind (min cbeg end)))) (when (< (point) end) (cl-case type - ((example-block export-block verse-block)) + ((example-block verse-block)) (src-block ;; In a source block, indent source code ;; according to language major mode, but only if diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index c7a3579ed..58aefa55f 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -718,36 +718,36 @@ ;; `org-adapt-indentation' is nil. (should (= 2 - (org-test-with-temp-text "* H\nA" - (forward-line) + (org-test-with-temp-text "* H\nA" (let ((org-adapt-indentation t)) (org-indent-line)) (org-get-indentation)))) (should (= 2 - (org-test-with-temp-text "* H\n\nA" - (forward-line) + (org-test-with-temp-text "* H\n\nA" (let ((org-adapt-indentation t)) (org-indent-line)) (org-get-indentation)))) (should (zerop - (org-test-with-temp-text "* H\nA" - (forward-line) + (org-test-with-temp-text "* H\nA" (let ((org-adapt-indentation nil)) (org-indent-line)) (org-get-indentation)))) ;; Indenting preserves point position. (should - (org-test-with-temp-text "* H\nAB" - (forward-line) - (forward-char) + (org-test-with-temp-text "* H\nAB" (let ((org-adapt-indentation t)) (org-indent-line)) (looking-at "B"))) - ;; Do not change indentation at an item. + ;; Do not change indentation at an item or a LaTeX environment. (should (= 1 - (org-test-with-temp-text "* H\n - A" - (forward-line) + (org-test-with-temp-text "* H\n - A" (let ((org-adapt-indentation t)) (org-indent-line)) (org-get-indentation)))) + (should + (= 1 + (org-test-with-temp-text + "\\begin{equation}\n 1+1=2\n\\end{equation}" + (org-indent-line) + (org-get-indentation)))) ;; On blank lines at the end of a list, indent like last element ;; within it if the line is still in the list. If the last element ;; is an item, indent like its contents. Otherwise, indent like the @@ -887,17 +887,54 @@ (org-test-with-temp-text "#+BEGIN_CENTER\n A\n B\n#+END_CENTER" (org-indent-region (point-min) (point-max)) (buffer-string)))) - ;; Ignore contents of verse blocks and example blocks. + ;; Ignore contents of verse blocks. Only indent block delimiters. (should (equal "#+BEGIN_VERSE\n A\n B\n#+END_VERSE" (org-test-with-temp-text "#+BEGIN_VERSE\n A\n B\n#+END_VERSE" (org-indent-region (point-min) (point-max)) (buffer-string)))) + (should + (equal "#+BEGIN_VERSE\n A\n B\n#+END_VERSE" + (org-test-with-temp-text " #+BEGIN_VERSE\n A\n B\n #+END_VERSE" + (org-indent-region (point-min) (point-max)) + (buffer-string)))) + ;; Indent example blocks as a single block, unless indentation + ;; should be preserved. In this case only indent the block markers. (should (equal "#+BEGIN_EXAMPLE\n A\n B\n#+END_EXAMPLE" (org-test-with-temp-text "#+BEGIN_EXAMPLE\n A\n B\n#+END_EXAMPLE" (org-indent-region (point-min) (point-max)) (buffer-string)))) + (should + (equal "#+BEGIN_EXAMPLE\n A\n B\n#+END_EXAMPLE" + (org-test-with-temp-text " #+BEGIN_EXAMPLE\n A\n B\n #+END_EXAMPLE" + (org-indent-region (point-min) (point-max)) + (buffer-string)))) + (should + (equal "#+BEGIN_EXAMPLE -i\n A\n B\n#+END_EXAMPLE" + (org-test-with-temp-text + " #+BEGIN_EXAMPLE -i\n A\n B\n #+END_EXAMPLE" + (org-indent-region (point-min) (point-max)) + (buffer-string)))) + (should + (equal "#+BEGIN_EXAMPLE\n A\n B\n#+END_EXAMPLE" + (org-test-with-temp-text + " #+BEGIN_EXAMPLE\n A\n B\n #+END_EXAMPLE" + (let ((org-src-preserve-indentation t)) + (org-indent-region (point-min) (point-max))) + (buffer-string)))) + ;; Treat export blocks as a whole. + (should + (equal "#+BEGIN_EXPORT latex\n A\n B\n#+END_EXPORT" + (org-test-with-temp-text "#+BEGIN_EXPORT latex\n A\n B\n#+END_EXPORT" + (org-indent-region (point-min) (point-max)) + (buffer-string)))) + (should + (equal "#+BEGIN_EXPORT latex\n A\n B\n#+END_EXPORT" + (org-test-with-temp-text + " #+BEGIN_EXPORT latex\n A\n B\n #+END_EXPORT" + (org-indent-region (point-min) (point-max)) + (buffer-string)))) ;; Indent according to mode if `org-src-tab-acts-natively' is ;; non-nil. Otherwise, do not indent code at all. (should