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 <omar.antolin@gmail.com>
<http://lists.gnu.org/archive/html/emacs-orgmode/2017-10/msg00051.html>
This commit is contained in:
Nicolas Goaziou 2017-10-04 12:57:14 +02:00
parent 8ed303fdfe
commit ef6dac812b
2 changed files with 50 additions and 43 deletions

View File

@ -24205,16 +24205,25 @@ convenience:
- On an affiliated keyword, jump to the first one. - On an affiliated keyword, jump to the first one.
- On a table or a property drawer, move to its beginning. - 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) (interactive)
(unless (bobp) (unless (bobp)
(let* ((deactivate-mark nil) (let* ((deactivate-mark nil)
(element (org-element-at-point)) (element (org-element-at-point))
(type (org-element-type element)) (type (org-element-type element))
(contents-begin (org-element-property :contents-begin element))
(contents-end (org-element-property :contents-end element)) (contents-end (org-element-property :contents-end element))
(post-affiliated (org-element-property :post-affiliated 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 (cond
((not element) (goto-char (point-min))) ((not element) (goto-char (point-min)))
((= (point) begin) ((= (point) begin)
@ -24225,11 +24234,8 @@ convenience:
(goto-char (org-element-property (goto-char (org-element-property
:post-affiliated (org-element-property :parent element)))) :post-affiliated (org-element-property :parent element))))
((memq type '(property-drawer table)) (goto-char begin)) ((memq type '(property-drawer table)) (goto-char begin))
((memq type '(src-block verse-block)) (special?
(when (eq type 'src-block) (if (<= (point) contents-begin) (goto-char post-affiliated)
(setq contents-begin
(save-excursion (goto-char begin) (forward-line) (point))))
(if (= (point) contents-begin) (goto-char post-affiliated)
;; Inside a verse block, see blank lines as paragraph ;; Inside a verse block, see blank lines as paragraph
;; separators. ;; separators.
(let ((origin (point))) (let ((origin (point)))
@ -24238,7 +24244,6 @@ convenience:
(skip-chars-forward " \r\t\n" origin) (skip-chars-forward " \r\t\n" origin)
(if (= (point) origin) (goto-char contents-begin) (if (= (point) origin) (goto-char contents-begin)
(beginning-of-line)))))) (beginning-of-line))))))
((not contents-begin) (goto-char (or post-affiliated begin)))
((eq type 'paragraph) ((eq type 'paragraph)
(goto-char contents-begin) (goto-char contents-begin)
;; When at first paragraph in an item or a footnote definition, ;; When at first paragraph in an item or a footnote definition,

View File

@ -3536,23 +3536,18 @@ SCHEDULED: <2017-05-06 Sat>
t)) t))
;; Regular test. ;; Regular test.
(should (should
(org-test-with-temp-text "P1\n\nP2\n\nP3" (org-test-with-temp-text "P1\n\nP2\n\nP3<point>"
(goto-char (point-max))
(org-backward-paragraph) (org-backward-paragraph)
(looking-at "P3"))) (looking-at "P3")))
(should (should
(org-test-with-temp-text "P1\n\nP2\n\nP3" (org-test-with-temp-text "P1\n\nP2\n\n<point>P3"
(goto-char (point-max))
(beginning-of-line)
(org-backward-paragraph) (org-backward-paragraph)
(looking-at "P2"))) (looking-at-p "P2")))
;; Ignore depth. ;; Ignore depth.
(should (should
(org-test-with-temp-text "P1\n\n#+BEGIN_CENTER\nP2\n#+END_CENTER\nP3" (org-test-with-temp-text "P1\n\n#+BEGIN_CENTER\nP2\n#+END_CENTER\n<point>P3"
(goto-char (point-max))
(beginning-of-line)
(org-backward-paragraph) (org-backward-paragraph)
(looking-at "P2"))) (looking-at-p "P2")))
;; Ignore invisible elements. ;; Ignore invisible elements.
(should (should
(org-test-with-temp-text "* H1\n P1\n* H2" (org-test-with-temp-text "* H1\n P1\n* H2"
@ -3563,49 +3558,56 @@ SCHEDULED: <2017-05-06 Sat>
(bobp))) (bobp)))
;; On an affiliated keyword, jump to the first one. ;; On an affiliated keyword, jump to the first one.
(should (should
(org-test-with-temp-text "P1\n#+name: n\n#+caption: c1\n#+caption: c2\nP2" (org-test-with-temp-text
(search-forward "c2") "P1\n#+name: n\n#+caption: c1\n#+caption: <point>c2\nP2"
(org-backward-paragraph) (org-backward-paragraph)
(looking-at "#\\+name"))) (looking-at-p "#\\+name")))
;; On the second element in an item or a footnote definition, jump ;; On the second element in an item or a footnote definition, jump
;; to item or the definition. ;; to item or the definition.
(should (should
(org-test-with-temp-text "- line1\n\n line2" (org-test-with-temp-text "- line1\n\n<point> line2"
(goto-char (point-max))
(beginning-of-line)
(org-backward-paragraph) (org-backward-paragraph)
(looking-at "- line1"))) (looking-at-p "- line1")))
(should (should
(org-test-with-temp-text "[fn:1] line1\n\n line2" (org-test-with-temp-text "[fn:1] line1\n\n<point> line2"
(goto-char (point-max))
(beginning-of-line)
(org-backward-paragraph) (org-backward-paragraph)
(looking-at "\\[fn:1\\] line1"))) (looking-at-p "\\[fn:1\\] line1")))
;; On a table (resp. a property drawer), ignore table rows ;; On a table (resp. a property drawer), ignore table rows
;; (resp. node properties). ;; (resp. node properties).
(should (should
(org-test-with-temp-text "| a | b |\n| c | d |\nP1" (org-test-with-temp-text "| a | b |\n| c | d |\n<point>P1"
(goto-char (point-max))
(beginning-of-line)
(org-backward-paragraph) (org-backward-paragraph)
(bobp))) (bobp)))
(should (should
(org-test-with-temp-text "* H\n:PROPERTIES:\n:prop: value\n:END:\n<point>P1" (org-test-with-temp-text "* H\n:PROPERTIES:\n:prop: value\n:END:\n<point>P1"
(org-backward-paragraph) (org-backward-paragraph)
(looking-at ":PROPERTIES:"))) (looking-at-p ":PROPERTIES:")))
;; On a source or verse block, stop before blank lines. ;; On a comment, example, src and verse blocks, stop before blank
;; lines.
(should (should
(org-test-with-temp-text "#+BEGIN_VERSE\nL1\n\nL2\n\nL3\n#+END_VERSE" (org-test-with-temp-text "#+BEGIN_VERSE\nL1\n\nL2\n\n<point>L3\n#+END_VERSE"
(search-forward "L3")
(beginning-of-line)
(org-backward-paragraph) (org-backward-paragraph)
(looking-at "L2"))) (looking-at-p "L2")))
(should (should
(org-test-with-temp-text "#+BEGIN_SRC\nL1\n\nL2\n\nL3#+END_SRC" (org-test-with-temp-text "#+BEGIN_SRC\nL1\n\nL2\n\n<point>L3#+END_SRC"
(search-forward "L3")
(beginning-of-line)
(org-backward-paragraph) (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<point>\n#+END_VERSE"
(org-backward-paragraph)
(looking-at-p "L1")))
(should
(org-test-with-temp-text "#+BEGIN_EXAMPLE\nL1\nL2<point>\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_<point>EXAMPLE\nL1\n#+END_EXAMPLE"
(org-backward-paragraph)
(bobp))))
(ert-deftest test-org/forward-element () (ert-deftest test-org/forward-element ()
"Test `org-forward-element' specifications." "Test `org-forward-element' specifications."