Browse Source

Fix indentation of some elements

* lisp/org.el (org--get-expected-indentation): Tiny refactoring.
(org-indent-line): Ignore LaTex environments.
(org-indent-region): Better handling for export blocks, LaTeX
environments and example blocks.

* testing/lisp/test-org.el (test-org/indent-line):
(test-org/indent-region): Add tests.
Nicolas Goaziou 3 years ago
parent
commit
6da9d0a416
2 changed files with 85 additions and 26 deletions
  1. 35 13
      lisp/org.el
  2. 50 13
      testing/lisp/test-org.el

+ 35 - 13
lisp/org.el

@@ -22799,7 +22799,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)
@@ -22951,6 +22951,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)
@@ -23002,22 +23009,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
@@ -23027,8 +23050,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
@@ -23062,7 +23084,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

+ 50 - 13
testing/lisp/test-org.el

@@ -720,36 +720,36 @@
   ;; `org-adapt-indentation' is nil.
   (should
    (= 2
-      (org-test-with-temp-text "* H\nA"
-	(forward-line)
+      (org-test-with-temp-text "* H\n<point>A"
 	(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<point>\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\n<point>A"
       (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\nA<point>B"
      (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<point> - A"
 	(let ((org-adapt-indentation t)) (org-indent-line))
 	(org-get-indentation))))
+  (should
+   (= 1
+      (org-test-with-temp-text
+	  "\\begin{equation}\n <point>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
@@ -889,17 +889,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