Ver código fonte

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.
Ihor Radchenko 2 anos atrás
pai
commit
0a6a56c804
2 arquivos alterados com 109 adições e 21 exclusões
  1. 42 21
      lisp/org.el
  2. 67 0
      testing/lisp/test-org.el

+ 42 - 21
lisp/org.el

@@ -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)))

+ 67 - 0
testing/lisp/test-org.el

@@ -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