org-adapt-indentation: Fix 'headline-data checks

* lisp/org.el (org--at-headline-data-p): New function used to check if
element at point belongs to headline data.
(org--get-expected-indentation):
(org-indent-line): Use `org--at-headline-data-p' instead of
explicit (and inaccurate) condition.
* testing/lisp/test-org.el (test-org/indent-region): Add tests.

Fixes incorrect LOGBOOK drawer indentation when
`org-adapt-indentation' is set to 'headline-data.
This commit is contained in:
Ihor Radchenko 2022-09-24 14:07:31 +08:00
parent 9bd8a99a6e
commit 0a6a56c804
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
2 changed files with 109 additions and 21 deletions

View File

@ -18567,6 +18567,36 @@ hierarchy of headlines by UP levels before marking the subtree."
;;; Indentation
(defun org--at-headline-data-p (&optional beg element)
"Return non-nil when `point' or BEG is inside headline metadata.
Metadata is planning line, properties drawer, logbook drawer right
after property drawer, or clock log line immediately following
properties drawer/planning line/ heading.
Optional argument ELEMENT contains element at BEG."
(org-with-wide-buffer
(when beg (goto-char beg))
(setq element (or element (org-element-at-point)))
(if (not (org-element-lineage element '(headline inlinetask)))
nil ; Not inside heading.
;; Skip to top-level parent in section.
(while (not (eq 'section (org-element-type (org-element-property :parent element))))
(setq element (org-element-property :parent element)))
(pcase (org-element-type element)
((or `planning `property-drawer)
t)
(`drawer
;; LOGBOOK drawer with appropriate name.
(equal
(org-log-into-drawer)
(org-element-property :drawer-name element)))
(`clock
;; Previous element must be headline metadata or headline.
(goto-char (1- (org-element-property :begin element)))
(or (org-at-heading-p)
(org--at-headline-data-p)))))))
(defvar org-element-greater-elements)
(defun org--get-expected-indentation (element contentsp)
"Expected indentation column for current line, according to ELEMENT.
@ -18627,17 +18657,10 @@ ELEMENT."
;; Do not indent like previous when the previous
;; element is headline data and `org-adapt-indentation'
;; is set to `headline-data'.
((save-excursion
(goto-char start)
(and
(eq org-adapt-indentation 'headline-data)
(not (or (org-at-clock-log-p)
(org-at-planning-p)))
(progn
(beginning-of-line 1)
(skip-chars-backward "\n")
((and (eq 'headline-data org-adapt-indentation)
(not (org--at-headline-data-p start element))
(or (org-at-heading-p)
(looking-back ":END:.*" (line-beginning-position))))))
(org--at-headline-data-p (1- start) previous)))
(throw 'exit 0))
(t (goto-char (org-element-property :begin previous))
(throw 'exit
@ -18752,17 +18775,15 @@ list structure. Instead, use \\<org-mode-map>`\\[org-shiftmetaleft]' or \
Also align node properties according to `org-property-format'."
(interactive)
(unless (or (org-at-heading-p)
(and (eq org-adapt-indentation 'headline-data)
(not (or (org-at-clock-log-p)
(org-at-planning-p)))
(save-excursion
(beginning-of-line 1)
(skip-chars-backward "\n")
(or (org-at-heading-p)
(looking-back ":END:.*" (line-beginning-position))))))
(let* ((element (save-excursion (beginning-of-line) (org-element-at-point-no-context)))
(type (org-element-type element)))
(let* ((element (save-excursion (beginning-of-line) (org-element-at-point-no-context)))
(type (org-element-type element)))
(unless (or (org-at-heading-p)
(and (eq org-adapt-indentation 'headline-data)
(not (org--at-headline-data-p nil element))
(save-excursion
(goto-char (1- (org-element-property :begin element)))
(or (org-at-heading-p)
(org--at-headline-data-p)))))
(cond ((and (memq type '(plain-list item))
(= (line-beginning-position)
(org-element-property :post-affiliated element)))

View File

@ -1313,6 +1313,73 @@
(org-test-with-temp-text "* H\n:PROPERTIES:\n:key:\n:END:"
(org-indent-region (point-min) (point-max))
(buffer-string)))))
;; Indent planning according to `org-adapt-indentation'.
(let ((org-adapt-indentation 'headline-data))
(should
(equal "* H\n SCHEDULED: <2022-11-03>"
(org-test-with-temp-text "* H\nSCHEDULED: <2022-11-03>"
(org-indent-region (point-min) (point-max))
(buffer-string)))))
;; Indent LOGBOOK according to `org-adapt-indentation'.
(let ((org-adapt-indentation 'headline-data))
(should
(equal "* H\n :LOGBOOK:
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46
:END:"
(org-test-with-temp-text "* H\n:LOGBOOK:
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46
:END:"
(org-indent-region (point-min) (point-max))
(buffer-string)))))
;; Indent clock lines according to `org-adapt-indentation'.
(let ((org-adapt-indentation 'headline-data))
(should
(equal "* H
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46"
(org-test-with-temp-text "* H
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46"
(org-indent-region (point-min) (point-max))
(buffer-string)))))
;; Do not indent beyond headline data.
(let ((org-adapt-indentation 'headline-data))
(should
(equal "* H\n SCHEDULED: <2022-11-03>\nParagraph"
(org-test-with-temp-text "* H\nSCHEDULED: <2022-11-03>\nParagraph"
(org-indent-region (point-min) (point-max))
(buffer-string)))))
(let ((org-adapt-indentation 'headline-data)
(org-log-into-drawer t))
(should
(equal "* TODO A task
:PROPERTIES:
:CAPTURED: [2022-09-11 dim. 21:25]
:END:
:LOGBOOK:
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46
:END:
Paragraph"
(org-test-with-temp-text "* TODO A task
:PROPERTIES:
:CAPTURED: [2022-09-11 dim. 21:25]
:END:
:LOGBOOK:
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46
:END:
Paragraph"
(org-indent-region (point-min) (point-max))
(buffer-string)))))
(let ((org-adapt-indentation 'headline-data))
(should
(equal "* TODO A task
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46
Paragraph
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46"
(org-test-with-temp-text "* TODO A task
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46
Paragraph
CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46"
(org-indent-region (point-min) (point-max))
(buffer-string)))))
;; Indent plain lists.
(let ((org-adapt-indentation t))
(should