emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Valentin Lab <valentin.lab@kalysto.org>
To: emacs-orgmode@gnu.org
Subject: [feature] Consistent fixed indentation of headline data
Date: Tue, 5 Jul 2022 16:59:57 +0200	[thread overview]
Message-ID: <2fcae365-97cf-ccc4-23f0-2fc5c110dd69@kalysto.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 1623 bytes --]

Hi everybody,

I'm using org-mode for a long time, and I never understood quite well 
how headline data were supposed to be indented, however I was happy with 
what emerged to me as the default of 2 spaces (with my emacs and 
org-mode version at the time). I recently updated my old emacs to 
=9.5.3=, and what I thought was a default indentation was removed.

Suddenly, I had no indentation at all for these headline-data and this 
bugged me.

I went through documentation, and code, and (re-)discovered 
`org-adapt-indentation' that was nil in my case and is intended to stay 
this way as far as I am concerned : I'm looking for a fixed indentation 
whatever the depth of my outlines.

I'm far from sure it was a default one day, but sure it was at least 
suggested/enforced in my workflow with my emacs at some time. And even 
if it didn't feel like it was clad in iron, it seems I'm not the only 
one who was using that as I can find some examples remaining in the 
current 'testing/examples' org files.

This indentation concerns only what is called "headline data" in the 
documentation of `org-adapt-indentation'. To be precise: schedules 
("SCHEDULE:", "DEADLINE:"...), clock drawer (":LOGBOOK:..."), property 
drawer (":PROPERTY:..."). These are "data" appearing after the headline 
as I understand them.

If I'm a user of org-mode, I'm fairly new in the emacs lisp and hacking 
community and I need to know:
- if my proposal is useful and has any chance to be accepted,
- if there are any pitfalls I delved into in matter of coding, 
conventions, ...
- if it make sense for others to include this,

Many thanks !

[-- Attachment #2: 0001-org-el-Add-fixed-indentation-of-headline-data.patch --]
[-- Type: text/x-patch, Size: 10245 bytes --]

From 54ee0ce45c4a0c31a8a701047d4d56c1592fb5bb Mon Sep 17 00:00:00 2001
From: Valentin Lab <valentin.lab@kalysto.org>
Date: Fri, 1 Jul 2022 14:03:41 +0200
Subject: [PATCH] org-el: Add fixed indentation of headline data

* lisp/org.el (org-headline-data-fixed-indent-level): Definition of
new customizable variable and doc.
(org-add-planning-info): When creating planning line, force a
`org-indent-line' to indent it correctly.
(org--get-expected-indentation): If variable
`org-headline-data-fixed-indent-level' is set and line is header,
inform `org-indent-line' to indent from specified amount.
(org-adapt-indentation): Update documentation to mention new
`org-headline-data-fixed-indent-level'.

TINYCHANGE

Signed-off-by: Valentin Lab <valentin.lab@kalysto.org>
---
 lisp/org.el              |  22 ++++++-
 testing/lisp/test-org.el | 139 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 159 insertions(+), 2 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 38a50d231..377a54edd 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -1428,7 +1428,8 @@ The following issues are influenced by this variable:
   indentation is not changed at all.
 
 - Property drawers and planning information is inserted indented
-  when this variable is set.  When nil, they will not be indented.
+  when this variable is set.  When nil, they will be indented
+  following `org-headline-data-fixed-indent-level'.
 
 - TAB indents a line relative to current level.  The lines below
   a headline will be indented when this variable is set to t.
@@ -1445,6 +1446,19 @@ time in Emacs."
 	  (const :tag "Do not adapt indentation at all" nil))
   :safe (lambda (x) (memq x '(t nil headline-data))))
 
+(defcustom org-headline-data-fixed-indent-level nil
+  "Indentation level for org property drawer.
+
+`org-adapt-indentation' need to be set to nil for this value
+to be considered.
+
+Note that this is all about true indentation, by adding and
+removing space characters.  See also \"org-indent.el\" which does
+level-dependent indentation in a virtual way, i.e. at display
+time in Emacs."
+  :group 'org-edit-structure
+  :type 'integer)
+
 (defvaralias 'org-special-ctrl-a 'org-special-ctrl-a/e)
 
 (defcustom org-special-ctrl-a/e nil
@@ -10060,7 +10074,8 @@ WHAT entry will also be removed."
 		    (eq what 'closed)
 		    nil nil (list org-end-time-was-given))))
 	   (unless (eolp) (insert " "))
-	   ts))))))
+	   ts))
+        (org-indent-line)))))
 
 (defvar org-log-note-marker (make-marker)
   "Marker pointing at the entry where the note is to be inserted.")
@@ -18371,6 +18386,9 @@ ELEMENT."
 			    ;; a footnote definition.
 			    (org--get-expected-indentation
 			     (org-element-property :parent previous) t))))))))))
+      ((and (not (eq org-headline-data-fixed-indent-level nil))
+         (memq type '(drawer property-drawer planning node-property clock)))
+         org-headline-data-fixed-indent-level)
       ;; Otherwise, move to the first non-blank line above.
       (t
        (beginning-of-line)
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index fcf2d0b5f..600d647e4 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -1069,6 +1069,49 @@
 	 " #+BEGIN_CENTER\n<point>  Contents\n#+END_CENTER"
 	 (org-indent-line)
 	 (org-get-indentation)))))
+  (let ((org-adapt-indentation nil)
+         (org-headline-data-fixed-indent-level 3))
+    (should
+     ;; First line should be indented using
+     ;; `org-headline-data-fixed-indent-level'.
+     (= 3
+        (org-test-with-temp-text "* H\n<point>:PROPERTY:\n:END:"
+	  (org-indent-line)
+	  (org-get-indentation))))
+    (should
+     (= 3
+        (org-test-with-temp-text "* H\n<point>SCHEDULED:\n"
+	  (org-indent-line)
+	  (org-get-indentation))))
+    (should
+     (= 3
+        (org-test-with-temp-text "* H\n<point>:LOGBOOK:\n:END:\n"
+	  (org-indent-line)
+	  (org-get-indentation))))
+    ;; same for old format on CLOCKing (no LOGBOOK drawer).
+    (should
+     (= 3
+        (org-test-with-temp-text "* H\n<point>CLOCK:\n"
+	  (org-indent-line)
+	  (org-get-indentation))))
+    ;; Lines that are not the first should not use `org-headline-data-fixed-indent-level'
+    (should
+     (= 0
+        (org-test-with-temp-text "* H\n:PROPERTY:\n<point>:foo: 1\n:END:"
+	  (org-indent-line)
+	  (org-get-indentation))))
+    (should
+     (= 0
+        (org-test-with-temp-text "* H\n<point> foo"
+	  (org-indent-line)
+	  (org-get-indentation))))
+    ;; First lines that are not planning/drawers/clocking should not be incremented
+    (should
+     (= 0
+        (org-test-with-temp-text "* H\n:LOGBOOK:\n<point>:foo: 1\n:END:"
+	  (org-indent-line)
+	  (org-get-indentation))))
+    )
   ;; Within code part of a source block, use language major mode if
   ;; `org-src-tab-acts-natively' is non-nil.  Otherwise, indent
   ;; according to line above.
@@ -1216,6 +1259,13 @@
             (org-test-with-temp-text "* H\n:PROPERTIES:\n:key:\n:END:"
               (org-indent-region (point-min) (point-max))
               (buffer-string)))))
+  ;; ;; Indent property drawers according to `org-adapt-indentation'.
+  ;; (let ((org-adapt-indentation 'headline-data))
+  ;;   (should
+  ;;    (equal "* H\n  :PROPERTIES:\n  :key:\n  :END:\n\ncontent2"
+  ;;           (org-test-with-temp-text "* H\n:PROPERTIES:\n:key:\n:END:\n\ncontent"
+  ;;             (org-indent-region (point-min) (point-max))
+  ;;             (buffer-string)))))
   ;; Indent plain lists.
   (let ((org-adapt-indentation t))
     (should
@@ -1228,6 +1278,33 @@
 	    (org-test-with-temp-text " - A\n\n - B"
 	      (org-indent-region (point-min) (point-max))
 	      (buffer-string)))))
+  ;; Increment list's indent level freely without following
+  ;; `org-headline-data-fixed-indent-level' if `org-adapt-indentation'
+  ;; is nil.
+  (let ((org-adapt-indentation nil)
+        (org-headline-data-fixed-indent-level nil))
+    (should
+     (equal "  - A\n    B\n    - C\n\n      X"
+	    (org-test-with-temp-text "- A\n   B\n  - C\n\n     X"
+	      (org-indent-region (point-min) (point-max))
+	      (buffer-string))))
+    (should
+     (equal "   - A\n\n   - B"
+	    (org-test-with-temp-text " - A\n\n - B"
+	      (org-indent-region (point-min) (point-max))
+	      (buffer-string)))))
+  (let ((org-adapt-indentation nil)
+        (org-headline-data-fixed-indent-level 3))
+    (should
+     (equal "  - A\n    B\n    - C\n\n      Y"
+	    (org-test-with-temp-text "- A\n   B\n  - C\n\n     Y"
+	      (org-indent-region (point-min) (point-max))
+	      (buffer-string))))
+    (should
+     (equal "     - A\n\n     - B"
+	    (org-test-with-temp-text "   - A\n\n   - B"
+	      (org-indent-region (point-min) (point-max))
+	      (buffer-string)))))
   ;; Indent footnote definitions.
   (should
    (equal "[fn:1] Definition\n\nDefinition"
@@ -5291,6 +5368,17 @@ Text.
 	    (replace-regexp-in-string
 	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
 	     nil nil 1))))
+  ;; Create deadline when `org-adapt-indentation' is nil and
+  ;; `org-headline-data-fixed-indent-level' is non-nil
+  (should
+   (equal "* H\n   DEADLINE: <2015-06-25>\nParagraph"
+	  (org-test-with-temp-text "* H\nParagraph<point>"
+	    (let ((org-adapt-indentation nil)
+                   (org-headline-data-fixed-indent-level 3))
+	      (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
+	    (replace-regexp-in-string
+	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+	     nil nil 1))))
   ;; Update deadline when `org-adapt-indentation' is non-nil.
   (should
    (equal "* H\n  DEADLINE: <2015-06-25>\nParagraph"
@@ -5315,6 +5403,20 @@ Paragraph<point>"
 	    (replace-regexp-in-string
 	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
 	     nil nil 1))))
+  ;; Update deadline when `org-adapt-indentation' is nil and
+  ;; `org-headline-data-fixed-indent-level' is non-nil
+  (should
+   (equal "* H\n   DEADLINE: <2015-06-25>\nParagraph"
+	  (org-test-with-temp-text "\
+* H
+DEADLINE: <2015-06-24 Wed>
+Paragraph<point>"
+	    (let ((org-adapt-indentation nil)
+                  (org-headline-data-fixed-indent-level 3))
+	      (org-add-planning-info 'deadline "<2015-06-25 Thu>"))
+	    (replace-regexp-in-string
+	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+	     nil nil 1))))
   ;; Schedule when `org-adapt-indentation' is non-nil.
   (should
    (equal "* H\n  SCHEDULED: <2015-06-25>\nParagraph"
@@ -5333,6 +5435,17 @@ Paragraph<point>"
 	    (replace-regexp-in-string
 	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
 	     nil nil 1))))
+  ;; Schedule when `org-adapt-indentation' is nil and
+  ;; `org-headline-data-fixed-indent-level' is non-nil
+  (should
+   (equal "* H\n   SCHEDULED: <2015-06-25>\nParagraph"
+	  (org-test-with-temp-text "* H\nParagraph<point>"
+	    (let ((org-adapt-indentation nil)
+                   (org-headline-data-fixed-indent-level 3))
+	      (org-add-planning-info 'scheduled "<2015-06-25 Thu>"))
+	    (replace-regexp-in-string
+	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+	     nil nil 1))))
   ;; Add deadline when scheduled.
   (should
    (equal "\
@@ -5425,6 +5538,32 @@ Paragraph<point>"
 	    (replace-regexp-in-string
 	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
 	     nil nil 1))))
+  ;; Remove closed when `org-adapt-indentation' is nil and
+  ;; `org-headline-data-fixed-indent-level' is non-nil
+  (should
+   (equal "* H\n   DEADLINE: <2015-06-25>\nParagraph"
+	  (org-test-with-temp-text "\
+* H
+CLOSED: [2015-06-25 Thu] DEADLINE: <2015-06-25 Thu>
+Paragraph<point>"
+	    (let ((org-adapt-indentation nil)
+                   (org-headline-data-fixed-indent-level 3))
+	      (org-add-planning-info nil nil 'closed))
+	    (replace-regexp-in-string
+	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+	     nil nil 1))))
+  (should
+   (equal "* H\nParagraph"
+	  (org-test-with-temp-text "\
+* H
+  CLOSED: [2015-06-25 Thu]
+Paragraph<point>"
+	    (let ((org-adapt-indentation nil)
+                   (org-headline-data-fixed-indent-level 3))
+	      (org-add-planning-info nil nil 'closed))
+	    (replace-regexp-in-string
+	     "\\( [.A-Za-z]+\\)>" "" (buffer-string)
+	     nil nil 1))))
   ;; Remove closed entry and delete empty line.
   (should
    (equal "\
-- 
2.25.1


             reply	other threads:[~2022-07-05 15:06 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-05 14:59 Valentin Lab [this message]
2022-07-07 10:41 ` [feature] Consistent fixed indentation of headline data Ihor Radchenko
2022-07-11 19:02   ` Valentin Lab
2022-07-18 13:11     ` [PATCH] Fix bug in org-indent-region when org-adapt-indentation is set to headline-data (was: [feature] Consistent fixed indentation of headline data) Ihor Radchenko
2022-07-18 17:28       ` [PATCH] Fix bug in org-indent-region when org-adapt-indentation is set to headline-data Bastien Guerry
2022-07-19 13:59         ` Ihor Radchenko
2022-07-18 13:26     ` [feature] Consistent fixed indentation of headline data Ihor Radchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2fcae365-97cf-ccc4-23f0-2fc5c110dd69@kalysto.org \
    --to=valentin.lab@kalysto.org \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).