summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2015-05-01 12:08:57 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2015-05-01 14:03:26 +0200
commit0b7721322a023d99144cfb5bec092165f8e5cb00 (patch)
tree798624cf052fd1f41948e69bf28e41bda70d6b24
parentbce77d0db31cd0f58daf731b0995e3d862541389 (diff)
downloadorg-mode-0b7721322a023d99144cfb5bec092165f8e5cb00.tar.gz
Fix `org-next-block'
* lisp/org.el (org-next-block): Use Element API. * testing/lisp/test-org.el (test-org/next-block): (test-org/previous-block): New tests.
-rwxr-xr-xlisp/org.el45
-rw-r--r--testing/lisp/test-org.el86
2 files changed, 120 insertions, 11 deletions
diff --git a/lisp/org.el b/lisp/org.el
index e2d1724..6139876 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -24344,19 +24344,42 @@ respect customization of `org-odd-levels-only'."
(defun org-next-block (arg &optional backward block-regexp)
"Jump to the next block.
-With a prefix argument ARG, jump forward ARG many source blocks.
+
+With a prefix argument ARG, jump forward ARG many blocks.
+
When BACKWARD is non-nil, jump to the previous block.
-When BLOCK-REGEXP is non-nil, use this regexp to find blocks."
+
+When BLOCK-REGEXP is non-nil, use this regexp to find blocks.
+Match data is set according to this regexp when the function
+returns.
+
+Return point at beginning of the opening line of found block.
+Throw an error if no block is found."
(interactive "p")
- (let ((re (or block-regexp org-block-regexp))
- (re-search-fn (or (and backward 're-search-backward)
- 're-search-forward)))
- (if (looking-at re) (forward-char 1))
- (condition-case nil
- (funcall re-search-fn re nil nil arg)
- (error (user-error "No %s code blocks"
- (if backward "previous" "further" ))))
- (goto-char (match-beginning 0)) (org-show-context)))
+ (let ((re (or block-regexp "^[ \t]*#\\+BEGIN"))
+ (case-fold-search t)
+ (search-fn (if backward #'re-search-backward #'re-search-forward))
+ (count (or arg 1))
+ (origin (point))
+ last-element)
+ (if backward (beginning-of-line) (end-of-line))
+ (while (and (> count 0) (funcall search-fn re nil t))
+ (let ((element (save-excursion
+ (goto-char (match-beginning 0))
+ (save-match-data (org-element-at-point)))))
+ (when (and (memq (org-element-type element)
+ '(center-block comment-block dynamic-block
+ example-block export-block quote-block
+ special-block src-block verse-block))
+ (<= (match-beginning 0)
+ (org-element-property :post-affiliated element)))
+ (setq last-element element)
+ (decf count))))
+ (if (= count 0)
+ (prog1 (goto-char (org-element-property :post-affiliated last-element))
+ (org-show-context))
+ (goto-char origin)
+ (user-error "No %s code blocks" (if backward "previous" "further")))))
(defun org-previous-block (arg &optional block-regexp)
"Jump to the previous block.
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 95cbe37..f490c10 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -2309,6 +2309,92 @@ Text.
(mapcar (lambda (ov) (cons (overlay-start ov) (overlay-end ov)))
(overlays-in (point-min) (point-max)))))))
+(ert-deftest test-org/next-block ()
+ "Test `org-next-block' specifications."
+ ;; Regular test.
+ (should
+ (org-test-with-temp-text "Paragraph\n#+BEGIN_CENTER\ncontents\n#+END_CENTER"
+ (org-next-block 1)
+ (looking-at "#\\+BEGIN_CENTER")))
+ ;; Ignore case.
+ (should
+ (org-test-with-temp-text "Paragraph\n#+begin_center\ncontents\n#+end_center"
+ (let ((case-fold-search nil))
+ (org-next-block 1)
+ (looking-at "#\\+begin_center"))))
+ ;; Ignore current line.
+ (should
+ (org-test-with-temp-text
+ "#+BEGIN_QUOTE\n#+END_QUOTE\n#+BEGIN_CENTER\n#+END_CENTER"
+ (org-next-block 1)
+ (looking-at "#\\+BEGIN_CENTER")))
+ ;; Throw an error when no block is found.
+ (should-error
+ (org-test-with-temp-text "Paragraph"
+ (org-next-block 1)))
+ ;; With an argument, skip many blocks at once.
+ (should
+ (org-test-with-temp-text
+ "Start\n#+BEGIN_CENTER\nA\n#+END_CENTER\n#+BEGIN_QUOTE\nB\n#+END_QUOTE"
+ (org-next-block 2)
+ (looking-at "#\\+BEGIN_QUOTE")))
+ ;; With optional argument BLOCK-REGEXP, filter matched blocks.
+ (should
+ (org-test-with-temp-text
+ "Start\n#+BEGIN_CENTER\nA\n#+END_CENTER\n#+BEGIN_QUOTE\nB\n#+END_QUOTE"
+ (org-next-block 1 nil "^[ \t]*#\\+BEGIN_QUOTE")
+ (looking-at "#\\+BEGIN_QUOTE")))
+ ;; Optional argument is also case-insensitive.
+ (should
+ (org-test-with-temp-text
+ "Start\n#+BEGIN_CENTER\nA\n#+END_CENTER\n#+begin_quote\nB\n#+end_quote"
+ (let ((case-fold-search nil))
+ (org-next-block 1 nil "^[ \t]*#\\+BEGIN_QUOTE")
+ (looking-at "#\\+begin_quote")))))
+
+(ert-deftest test-org/previous-block ()
+ "Test `org-previous-block' specifications."
+ ;; Regular test.
+ (should
+ (org-test-with-temp-text "#+BEGIN_CENTER\ncontents\n#+END_CENTER\n<point>"
+ (org-previous-block 1)
+ (looking-at "#\\+BEGIN_CENTER")))
+ ;; Ignore case.
+ (should
+ (org-test-with-temp-text "#+begin_center\ncontents\n#+end_center\n<point>"
+ (let ((case-fold-search nil))
+ (org-previous-block 1)
+ (looking-at "#\\+begin_center"))))
+ ;; Ignore current line.
+ (should
+ (org-test-with-temp-text
+ "#+BEGIN_QUOTE\n#+END_QUOTE\n#+BEGIN_CENTER<point>\n#+END_CENTER"
+ (org-previous-block 1)
+ (looking-at "#\\+BEGIN_QUOTE")))
+ ;; Throw an error when no block is found.
+ (should-error
+ (org-test-with-temp-text "Paragraph<point>"
+ (org-previous-block 1)))
+ ;; With an argument, skip many blocks at once.
+ (should
+ (org-test-with-temp-text
+ "#+BEGIN_CENTER\nA\n#+END_CENTER\n#+BEGIN_QUOTE\nB\n#+END_QUOTE\n<point>"
+ (org-previous-block 2)
+ (looking-at "#\\+BEGIN_CENTER")))
+ ;; With optional argument BLOCK-REGEXP, filter matched blocks.
+ (should
+ (org-test-with-temp-text
+ "#+BEGIN_CENTER\nA\n#+END_CENTER\n#+BEGIN_QUOTE\nB\n#+END_QUOTE\n<point>"
+ (org-previous-block 1 "^[ \t]*#\\+BEGIN_QUOTE")
+ (looking-at "#\\+BEGIN_QUOTE")))
+ ;; Optional argument is also case-insensitive.
+ (should
+ (org-test-with-temp-text
+ "#+BEGIN_CENTER\nA\n#+END_CENTER\n#+begin_quote\nB\n#+end_quote\n<point>"
+ (let ((case-fold-search nil))
+ (org-next-block 1 "^[ \t]*#\\+BEGIN_QUOTE")
+ (looking-at "#\\+begin_quote")))))
+
;;; Outline structure