Browse Source

Another fix to `org-next-visible-heading'

* lisp/org.el (org-next-visible-heading): There is no guarantee that
a `outline' overlay begins on the same line as a headline.
* testing/lisp/test-org.el (test-org/previous-visible-heading): New
test.

Reported-by: Kevin Liu <kevin@nivekuil.com>
<http://lists.gnu.org/r/emacs-orgmode/2020-06/msg00092.html>
Nicolas Goaziou 4 years ago
parent
commit
b68090e0be
2 changed files with 65 additions and 16 deletions
  1. 12 12
      lisp/org.el
  2. 53 4
      testing/lisp/test-org.el

+ 12 - 12
lisp/org.el

@@ -20477,20 +20477,20 @@ With ARG, repeats or can move backward if negative."
       (end-of-line))
       (end-of-line))
     (while (and (< arg 0) (re-search-backward regexp nil :move))
     (while (and (< arg 0) (re-search-backward regexp nil :move))
       (unless (bobp)
       (unless (bobp)
-	(pcase (get-char-property-and-overlay (point) 'invisible)
-	  (`(outline . ,o)
-	   (goto-char (overlay-start o))
-	   (beginning-of-line))
-	  (_ nil)))
+	(while (pcase (get-char-property-and-overlay (point) 'invisible)
+		 (`(outline . ,o)
+		  (goto-char (overlay-start o))
+		  (re-search-backward regexp nil :move))
+		 (_ nil))))
       (cl-incf arg))
       (cl-incf arg))
     (while (and (> arg 0) (re-search-forward regexp nil t))
     (while (and (> arg 0) (re-search-forward regexp nil t))
-      (pcase (get-char-property-and-overlay (point) 'invisible)
-	(`(outline . ,o)
-	 (goto-char (overlay-end o))
-	 (skip-chars-forward " \t\n")
-	 (end-of-line))
-	(_
-	 (end-of-line)))
+      (while (pcase (get-char-property-and-overlay (point) 'invisible)
+	       (`(outline . ,o)
+		(goto-char (overlay-end o))
+		(re-search-forward regexp nil :move))
+	       (_
+		(end-of-line)
+		nil)))			;leave the loop
       (cl-decf arg))
       (cl-decf arg))
     (if (> arg 0) (goto-char (point-max)) (beginning-of-line))))
     (if (> arg 0) (goto-char (point-max)) (beginning-of-line))))
 
 

+ 53 - 4
testing/lisp/test-org.el

@@ -3153,10 +3153,6 @@ SCHEDULED: <2017-05-06 Sat>
      (org-cycle)
      (org-cycle)
      (org-next-visible-heading 1)
      (org-next-visible-heading 1)
      (looking-at "\\* H3")))
      (looking-at "\\* H3")))
-  (should
-   (org-test-with-temp-text "* H1\n* H2\n* H3"
-     (org-next-visible-heading 1)
-     (looking-at "\\* H2")))
   ;; Move point between headlines, not on blank lines between.
   ;; Move point between headlines, not on blank lines between.
   (should
   (should
    (org-test-with-temp-text "* H1\n** H2\n\n\n\n* H3"
    (org-test-with-temp-text "* H1\n** H2\n\n\n\n* H3"
@@ -3183,6 +3179,59 @@ SCHEDULED: <2017-05-06 Sat>
      (org-next-visible-heading -2)
      (org-next-visible-heading -2)
      (looking-at "\\* H1"))))
      (looking-at "\\* H1"))))
 
 
+(ert-deftest test-org/previous-visible-heading ()
+  "Test `org-previous-visible-heading' specifications."
+  ;; Move to the beginning of the next headline, taking into
+  ;; consideration ARG.
+  (should
+   (org-test-with-temp-text "* H1\n<point>* H2"
+     (org-previous-visible-heading 1)
+     (looking-at "\\* H1")))
+  (should
+   (org-test-with-temp-text "* H1\n* H2\n<point>* H3"
+     (org-previous-visible-heading 2)
+     (looking-at "\\* H1")))
+  ;; Ignore invisible headlines.
+  (should
+   (org-test-with-temp-text "* H1\n** H2\n<point>* H3"
+     (org-overview)
+     (org-previous-visible-heading 1)
+     (looking-at "\\* H1")))
+  ;; Move point between headlines, not on blank lines between.
+  (should
+   (org-test-with-temp-text "* H1\n\n\n\n** H2\n<point>* H3"
+     (let ((org-cycle-separator-lines 1))
+       (org-overview)
+       (org-previous-visible-heading 1))
+     (looking-at "\\* H1")))
+  ;; Move at end of buffer when there is no more headline.
+  (should
+   (org-test-with-temp-text "* H1"
+     (org-previous-visible-heading 1)
+     (bobp)))
+  (should
+   (org-test-with-temp-text "* H1\n* <point>H2"
+     (org-previous-visible-heading 2)
+     (bobp)))
+  ;; Invisible parts may not start at a headline, i.e., when revealing
+  ;; parts of the buffer.  Handle this.
+  (should
+   (org-test-with-temp-text "* Main\n** H1\nFoo\n** H2\nBar\n** H3\nBaz"
+     (org-overview)
+     (search-forward "H1")
+     (org-show-context 'minimal)
+     (org-cycle)
+     (search-forward "H3")
+     (org-show-context 'minimal)
+     ;; At this point, buffer displays, with point at "|",
+     ;;
+     ;; * Main
+     ;; ** H1
+     ;;    Foo
+     ;; ** H3|
+     (org-previous-visible-heading 1)
+     (looking-at "\\*+ H1"))))
+
 (ert-deftest test-org/forward-heading-same-level ()
 (ert-deftest test-org/forward-heading-same-level ()
   "Test `org-forward-heading-same-level' specifications."
   "Test `org-forward-heading-same-level' specifications."
   ;; Test navigation at top level, forward and backward.
   ;; Test navigation at top level, forward and backward.