From ef6dac812b75f6f421bed7bc84d6f166c0b90f71 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Wed, 4 Oct 2017 12:57:14 +0200 Subject: [PATCH] Fix `org-backward-paragraph' on block opening line * lisp/org.el (org-backward-paragraph): Do not error when called from a block opening line. * testing/lisp/test-org.el (test-org/backward-paragraph): Add tests. Reported-by: Omar Antolin --- lisp/org.el | 23 +++++++------ testing/lisp/test-org.el | 70 +++++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 386ea47d7..35405b4bf 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -24205,16 +24205,25 @@ convenience: - On an affiliated keyword, jump to the first one. - On a table or a property drawer, move to its beginning. - - On a verse or source block, stop before blank lines." + - On comment, example, export, src and verse blocks, stop + before blank lines." (interactive) (unless (bobp) (let* ((deactivate-mark nil) (element (org-element-at-point)) (type (org-element-type element)) - (contents-begin (org-element-property :contents-begin element)) (contents-end (org-element-property :contents-end element)) (post-affiliated (org-element-property :post-affiliated element)) - (begin (org-element-property :begin element))) + (begin (org-element-property :begin element)) + (special? ;blocks handled specially + (memq type '(comment-block example-block export-block src-block + verse-block))) + (contents-begin + (if special? + ;; These types have no proper contents. Fake line + ;; below the block opening line as contents beginning. + (save-excursion (goto-char begin) (line-beginning-position 2)) + (org-element-property :contents-begin element)))) (cond ((not element) (goto-char (point-min))) ((= (point) begin) @@ -24225,11 +24234,8 @@ convenience: (goto-char (org-element-property :post-affiliated (org-element-property :parent element)))) ((memq type '(property-drawer table)) (goto-char begin)) - ((memq type '(src-block verse-block)) - (when (eq type 'src-block) - (setq contents-begin - (save-excursion (goto-char begin) (forward-line) (point)))) - (if (= (point) contents-begin) (goto-char post-affiliated) + (special? + (if (<= (point) contents-begin) (goto-char post-affiliated) ;; Inside a verse block, see blank lines as paragraph ;; separators. (let ((origin (point))) @@ -24238,7 +24244,6 @@ convenience: (skip-chars-forward " \r\t\n" origin) (if (= (point) origin) (goto-char contents-begin) (beginning-of-line)))))) - ((not contents-begin) (goto-char (or post-affiliated begin))) ((eq type 'paragraph) (goto-char contents-begin) ;; When at first paragraph in an item or a footnote definition, diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 304e50381..4023ec454 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -3536,23 +3536,18 @@ SCHEDULED: <2017-05-06 Sat> t)) ;; Regular test. (should - (org-test-with-temp-text "P1\n\nP2\n\nP3" - (goto-char (point-max)) + (org-test-with-temp-text "P1\n\nP2\n\nP3" (org-backward-paragraph) (looking-at "P3"))) (should - (org-test-with-temp-text "P1\n\nP2\n\nP3" - (goto-char (point-max)) - (beginning-of-line) + (org-test-with-temp-text "P1\n\nP2\n\nP3" (org-backward-paragraph) - (looking-at "P2"))) + (looking-at-p "P2"))) ;; Ignore depth. (should - (org-test-with-temp-text "P1\n\n#+BEGIN_CENTER\nP2\n#+END_CENTER\nP3" - (goto-char (point-max)) - (beginning-of-line) + (org-test-with-temp-text "P1\n\n#+BEGIN_CENTER\nP2\n#+END_CENTER\nP3" (org-backward-paragraph) - (looking-at "P2"))) + (looking-at-p "P2"))) ;; Ignore invisible elements. (should (org-test-with-temp-text "* H1\n P1\n* H2" @@ -3563,49 +3558,56 @@ SCHEDULED: <2017-05-06 Sat> (bobp))) ;; On an affiliated keyword, jump to the first one. (should - (org-test-with-temp-text "P1\n#+name: n\n#+caption: c1\n#+caption: c2\nP2" - (search-forward "c2") + (org-test-with-temp-text + "P1\n#+name: n\n#+caption: c1\n#+caption: c2\nP2" (org-backward-paragraph) - (looking-at "#\\+name"))) + (looking-at-p "#\\+name"))) ;; On the second element in an item or a footnote definition, jump ;; to item or the definition. (should - (org-test-with-temp-text "- line1\n\n line2" - (goto-char (point-max)) - (beginning-of-line) + (org-test-with-temp-text "- line1\n\n line2" (org-backward-paragraph) - (looking-at "- line1"))) + (looking-at-p "- line1"))) (should - (org-test-with-temp-text "[fn:1] line1\n\n line2" - (goto-char (point-max)) - (beginning-of-line) + (org-test-with-temp-text "[fn:1] line1\n\n line2" (org-backward-paragraph) - (looking-at "\\[fn:1\\] line1"))) + (looking-at-p "\\[fn:1\\] line1"))) ;; On a table (resp. a property drawer), ignore table rows ;; (resp. node properties). (should - (org-test-with-temp-text "| a | b |\n| c | d |\nP1" - (goto-char (point-max)) - (beginning-of-line) + (org-test-with-temp-text "| a | b |\n| c | d |\nP1" (org-backward-paragraph) (bobp))) (should (org-test-with-temp-text "* H\n:PROPERTIES:\n:prop: value\n:END:\nP1" (org-backward-paragraph) - (looking-at ":PROPERTIES:"))) - ;; On a source or verse block, stop before blank lines. + (looking-at-p ":PROPERTIES:"))) + ;; On a comment, example, src and verse blocks, stop before blank + ;; lines. (should - (org-test-with-temp-text "#+BEGIN_VERSE\nL1\n\nL2\n\nL3\n#+END_VERSE" - (search-forward "L3") - (beginning-of-line) + (org-test-with-temp-text "#+BEGIN_VERSE\nL1\n\nL2\n\nL3\n#+END_VERSE" (org-backward-paragraph) - (looking-at "L2"))) + (looking-at-p "L2"))) (should - (org-test-with-temp-text "#+BEGIN_SRC\nL1\n\nL2\n\nL3#+END_SRC" - (search-forward "L3") - (beginning-of-line) + (org-test-with-temp-text "#+BEGIN_SRC\nL1\n\nL2\n\nL3#+END_SRC" (org-backward-paragraph) - (looking-at "L2")))) + (looking-at-p "L2"))) + ;; In comment, example, export, src and verse blocks, stop below + ;; opening line when called from within the block. + (should + (org-test-with-temp-text "#+BEGIN_VERSE\nL1\nL2\n#+END_VERSE" + (org-backward-paragraph) + (looking-at-p "L1"))) + (should + (org-test-with-temp-text "#+BEGIN_EXAMPLE\nL1\nL2\n#+END_EXAMPLE" + (org-backward-paragraph) + (looking-at-p "L1"))) + ;; When called from the opening line itself, however, move to + ;; beginning of block. + (should + (org-test-with-temp-text "#+BEGIN_EXAMPLE\nL1\n#+END_EXAMPLE" + (org-backward-paragraph) + (bobp)))) (ert-deftest test-org/forward-element () "Test `org-forward-element' specifications."