> Applied, onto main. Great! > May you elaborate on the edge cases you encountered? > It may be a good idea to add such cases to the tests as well.
I think they all reduced to the case where adding the spaces increased the minimum indent of the block, in which case `org-indent-line' would remove `block-content-ind' spaces from all other lines in the block. I attached a patch with a simple test where I also cleaned up the use of obsolete function `org-get-indentation' in `test-org.el'. As a final thing on this patch in particular, I thought for a second that I might have caused a regression in modes where the indent-function cycles indentation (e.g. python-mode). Seems like python-mode in particular relies on `last-command' and not current indentation so it never worked. Idk if there's a good solution to this issue from our side. Still, I think it makes sense to at least refrain from moving stuff around unnecessarily, just in case some modes do rely on current indentation. LRA Mar 29, 2025, 11:07 by yanta...@posteo.net: > l...@phdk.org writes: > >> Thanks for the comments, I've attached the updated patch. >> >>> 1. Use `insert' rather than `insert-char' that is for interactive use. >>> 2. Use more readable ?\t notation >>> >> >> I realized that just inserting the spaces actually did mess up things >> in some edge-cases so I changed approach. It feels ugly having almost >> the exact same bit of code within a couple lines, but I don't see an >> obvious solution. >> > > Applied, onto main. > Fixed. > https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=4750b37809 > > May you elaborate on the edge cases you encountered? > It may be a good idea to add such cases to the tests as well. > > -- > Ihor Radchenko // yantar92, > Org mode maintainer, > Learn more about Org mode at <https://orgmode.org/>. > Support Org development at <https://liberapay.com/org-mode>, > or support my work at <https://liberapay.com/yantar92> >
>From ac097ddbaed6b504f72760a5ffe0b128533fccdd Mon Sep 17 00:00:00 2001 From: Lukas Rudd Andersen <l...@phdk.org> Date: Mon, 31 Mar 2025 16:20:35 +0200 Subject: [PATCH] org-indent-line: Avoid unnecessary temporary changes to indentation * lisp/org.el (org-indent-line): Add a check to ensure that org doesn't indent when it isn't needed. * testing/lisp/test-org.el (test-org/indent-line): Add additional test and clean up use of obsolete function `org-get-indentation'. Link: https://orgmode.org/list/omp_5ys--...@phdk.org TINYCHANGE --- lisp/org.el | 3 +- testing/lisp/test-org.el | 120 +++++++++++++++++++++------------------ 2 files changed, 67 insertions(+), 56 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index ec6aa7580..ee8f66d04 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -19480,7 +19480,8 @@ Also align node properties according to `org-property-format'." org-edit-src-content-indentation))))) ;; Avoid over-indenting when beginning of a new line is not empty. ;; https://list.orgmode.org/omcpuwz--...@phdk.org/ - (when block-content-ind + (when (and block-content-ind + (< (current-indentation) block-content-ind)) (save-excursion (indent-line-to block-content-ind))) (ignore-errors ; do not err when there is no proper major mode ;; It is important to call `indent-according-to-mode' diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index a55c4162e..9966aae44 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -1079,40 +1079,40 @@ Otherwise, evaluate RESULT as an sexp and return its result." (zerop (org-test-with-temp-text "%%(org-calendar-holiday)" (org-indent-line) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text "[fn:1] fn" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text "* H" (org-indent-line) - (org-get-indentation)))) + (current-indentation)))) ;; Do not indent before first headline. (should (zerop (org-test-with-temp-text "" (org-indent-line) - (org-get-indentation)))) + (current-indentation)))) ;; Indent according to headline level otherwise, unless ;; `org-adapt-indentation' is nil. (should (= 2 (org-test-with-temp-text "* H\n<point>A" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (= 2 (org-test-with-temp-text "* H\n<point>\nA" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text "* H\n<point>A" (let ((org-adapt-indentation nil)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) ;; Indenting preserves point position. (should (org-test-with-temp-text "* H\nA<point>B" @@ -1123,13 +1123,13 @@ Otherwise, evaluate RESULT as an sexp and return its result." (= 1 (org-test-with-temp-text "* H\n<point> - A" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (= 1 (org-test-with-temp-text "\\begin{equation}\n <point>1+1=2\n\\end{equation}" (org-indent-line) - (org-get-indentation)))) + (current-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 @@ -1138,39 +1138,39 @@ Otherwise, evaluate RESULT as an sexp and return its result." (= 4 (org-test-with-temp-text "* H\n- A\n - AA\n<point>" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (= 4 (org-test-with-temp-text "* H\n- A\n -\n\n<point>" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text "* H\n- A\n - AA\n\n\n\n<point>" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (= 4 (org-test-with-temp-text "* H\n- A\n - \n<point>" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (= 4 (org-test-with-temp-text "* H\n - \n #+BEGIN_SRC emacs-lisp\n t\n #+END_SRC\n<point>" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (= 2 (org-test-with-temp-text "- A\n B\n\n<point>" (let ((org-adapt-indentation nil)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (= 2 (org-test-with-temp-text "- A\n \begin{cases} 1 + 1\n \end{cases}\n\n<point>" (let ((org-adapt-indentation nil)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) ;; Likewise, on a blank line at the end of a footnote definition, ;; indent at column 0 if line belongs to the definition. Otherwise, ;; indent like the definition itself. @@ -1178,12 +1178,12 @@ Otherwise, evaluate RESULT as an sexp and return its result." (zerop (org-test-with-temp-text "* H\n[fn:1] Definition\n<point>" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text "* H\n[fn:1] Definition\n\n\n\n<point>" (let ((org-adapt-indentation t)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) ;; After the end of the contents of a greater element, indent like ;; the beginning of the element. (should @@ -1191,14 +1191,14 @@ Otherwise, evaluate RESULT as an sexp and return its result." (org-test-with-temp-text " #+BEGIN_CENTER\n Contents\n<point>#+END_CENTER" (org-indent-line) - (org-get-indentation)))) + (current-indentation)))) ;; On blank lines after a paragraph, indent like its last non-empty ;; line. (should (= 1 (org-test-with-temp-text " Paragraph\n\n<point>" (org-indent-line) - (org-get-indentation)))) + (current-indentation)))) ;; At the first line of an element, indent like previous element's ;; first line, ignoring footnotes definitions and inline tasks, or ;; according to parent. @@ -1207,22 +1207,23 @@ Otherwise, evaluate RESULT as an sexp and return its result." (= 2 (org-test-with-temp-text "A\n\n B\n\nC<point>" (org-indent-line) - (org-get-indentation)))) + (current-indentation)))) (should (= 1 (org-test-with-temp-text " A\n\n[fn:1] B\n\n\nC<point>" (org-indent-line) - (org-get-indentation)))) + (current-indentation)))) (should (= 1 (org-test-with-temp-text " #+BEGIN_CENTER\n<point> Contents\n#+END_CENTER" (org-indent-line) - (org-get-indentation))))) + (current-indentation))))) ;; Within code part of a source block, use language major mode if ;; `org-src-tab-acts-natively' is non-nil, only add ;; `org-edit-src-content-indentation' to lines with indentation that - ;; is lower. Otherwise, indent according to line above. + ;; is lower, do so in a way that does not increase the blocks + ;; minimum indent. Otherwise, indent according to line above. (should (= 6 (org-test-with-temp-text @@ -1230,7 +1231,7 @@ Otherwise, evaluate RESULT as an sexp and return its result." (let ((org-src-tab-acts-natively t) (org-edit-src-content-indentation 0)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) (should (= 2 (org-test-with-temp-text @@ -1239,7 +1240,16 @@ Otherwise, evaluate RESULT as an sexp and return its result." (org-edit-src-content-indentation 2)) (org-indent-line)) (forward-line -1) - (org-get-indentation)))) + (current-indentation)))) + (should + (= 7 + (org-test-with-temp-text + "#+BEGIN_SRC emacs-lisp\n (and A<point>\n B)\n#+END_SRC" + (let ((org-src-tab-acts-natively t) + (org-edit-src-content-indentation 2)) + (org-indent-line)) + (forward-line 1) + (current-indentation)))) (should (= 1 (org-test-with-temp-text @@ -1247,14 +1257,14 @@ Otherwise, evaluate RESULT as an sexp and return its result." (let ((org-src-tab-acts-natively nil) (org-edit-src-content-indentation 0)) (org-indent-line)) - (org-get-indentation)))) + (current-indentation)))) ;; Otherwise, indent like the first non-blank line above. (should (zerop (org-test-with-temp-text "#+BEGIN_CENTER\nline1\n\n<point> line2\n#+END_CENTER" (org-indent-line) - (org-get-indentation)))) + (current-indentation)))) ;; Align node properties according to `org-property-format'. Handle ;; nicely empty values. (should @@ -5875,7 +5885,7 @@ Text. (org-adapt-indentation t)) (org-demote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (= 3 (org-test-with-temp-text "* H\n :PROPERTIES:\n :FOO: Bar\n :END:" @@ -5883,7 +5893,7 @@ Text. (org-adapt-indentation t)) (org-demote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should-not (= 3 (org-test-with-temp-text "* H\n SCHEDULED: <2014-03-04 tue.>" @@ -5891,7 +5901,7 @@ Text. (org-adapt-indentation nil)) (org-demote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) ;; When `org-adapt-indentation' is non-nil, shift all lines in ;; section accordingly. Ignore, however, footnote definitions and ;; inlinetasks boundaries. @@ -5902,7 +5912,7 @@ Text. (org-adapt-indentation t)) (org-demote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (= 2 (org-test-with-temp-text "* H\n Paragraph" @@ -5910,7 +5920,7 @@ Text. (org-adapt-indentation nil)) (org-demote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text "* H\n[fn:1] def line 1\ndef line 2" @@ -5918,7 +5928,7 @@ Text. (org-adapt-indentation t)) (org-demote)) (goto-char (point-max)) - (org-get-indentation)))) + (current-indentation)))) (should (= 3 (org-test-with-temp-text "* H\n[fn:1] Def.\n\n\n After def." @@ -5926,7 +5936,7 @@ Text. (org-adapt-indentation t)) (org-demote)) (goto-char (point-max)) - (org-get-indentation)))) + (current-indentation)))) (when (featurep 'org-inlinetask) (should (zerop @@ -5935,7 +5945,7 @@ Text. (org-test-with-temp-text "* H\n***** I\n***** END" (org-demote) (forward-line) - (org-get-indentation)))))) + (current-indentation)))))) (when (featurep 'org-inlinetask) (should (= 3 @@ -5944,7 +5954,7 @@ Text. (org-test-with-temp-text "* H\n***** I\n Contents\n***** END" (org-demote) (forward-line 2) - (org-get-indentation)))))) + (current-indentation)))))) ;; When `org-adapt-indentation' is non-nil, log drawers are ;; adjusted. (should @@ -5981,7 +5991,7 @@ Text. (org-src-preserve-indentation nil)) (org-demote)) (forward-line 2) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text "* H\n#+BEGIN_EXAMPLE\n(+ 1 1)\n#+END_EXAMPLE" @@ -5989,7 +5999,7 @@ Text. (org-src-preserve-indentation t)) (org-demote)) (forward-line 2) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text "* H\n#+BEGIN_SRC emacs-lisp\n(+ 1 1)\n#+END_SRC" @@ -5997,7 +6007,7 @@ Text. (org-src-preserve-indentation t)) (org-demote)) (forward-line 2) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text @@ -6006,7 +6016,7 @@ Text. (org-src-preserve-indentation nil)) (org-demote)) (forward-line 2) - (org-get-indentation))))) + (current-indentation))))) (ert-deftest test-org/promote () "Test `org-promote' specifications." @@ -6059,7 +6069,7 @@ Text. (org-adapt-indentation t)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (= 2 (org-test-with-temp-text "** H\n :PROPERTIES:\n :FOO: Bar\n :END:" @@ -6067,7 +6077,7 @@ Text. (org-adapt-indentation t)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should-not (= 2 (org-test-with-temp-text "** H\n SCHEDULED: <2014-03-04 tue.>" @@ -6075,7 +6085,7 @@ Text. (org-adapt-indentation nil)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) ;; When `org-adapt-indentation' is non-nil, shift all lines in ;; section accordingly. Ignore, however, footnote definitions and ;; inlinetasks boundaries. @@ -6086,7 +6096,7 @@ Text. (org-adapt-indentation t)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should-not (= 2 (org-test-with-temp-text "** H\n Paragraph" @@ -6094,7 +6104,7 @@ Text. (org-adapt-indentation nil)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (= 2 (org-test-with-temp-text "** H\n Paragraph\n[fn:1] line1\nline2" @@ -6102,7 +6112,7 @@ Text. (org-adapt-indentation t)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (when (featurep 'org-inlinetask) (should (zerop @@ -6111,7 +6121,7 @@ Text. (org-test-with-temp-text "** H\n***** I\n***** END" (org-promote) (forward-line) - (org-get-indentation)))))) + (current-indentation)))))) (when (featurep 'org-inlinetask) (should (= 2 @@ -6120,7 +6130,7 @@ Text. (org-test-with-temp-text "** H\n***** I\n Contents\n***** END" (org-promote) (forward-line 2) - (org-get-indentation)))))) + (current-indentation)))))) ;; Give up shifting if it would break document's structure ;; otherwise. (should @@ -6130,7 +6140,7 @@ Text. (org-adapt-indentation t)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (= 3 (org-test-with-temp-text "** H\n Paragraph\n * list." @@ -6138,7 +6148,7 @@ Text. (org-adapt-indentation t)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) ;; When `org-adapt-indentation' is non-nil, log drawers are ;; adjusted. (should @@ -6186,7 +6196,7 @@ Text. (org-odd-levels-only nil)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text @@ -6196,7 +6206,7 @@ Text. (org-odd-levels-only nil)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text @@ -6206,7 +6216,7 @@ Text. (org-odd-levels-only nil)) (org-promote)) (forward-line) - (org-get-indentation)))) + (current-indentation)))) (should (zerop (org-test-with-temp-text @@ -6216,7 +6226,7 @@ Text. (org-odd-levels-only nil)) (org-promote)) (forward-line) - (org-get-indentation))))) + (current-indentation))))) (ert-deftest test-org/org-get-valid-level () "Test function `org-get-valid-level' specifications." -- 2.47.2