Hello,
Here is a proposal for new `org-forward-paragraph' and
`org-backward-paragraph' functions, currently bound to and
. Note that functions bound to M-{ and M-} are /not/
paragraph-related functions, but we might want to reconsider it at some
point.
In any case, the purpose of this rewrite is to mimic more closely
expected behaviour from `forward-paragraph' and `backward-paragraph'
functions, as found, e.g., in Text mode. Unlike Text mode, navigation in
Org mode is usually not linear, but both should feel the same, for
example, when the document is indeed linear.
These functions try to stop at interesting places, and skip mundane ones
(e.g., tables are treated as a single block) so navigation is still
fast.
I also added support for repeat argument.
WDYT? Also, what should be done with M-{ and M-}?
Regards,
--
Nicolas Goaziou
>From 4ba83f948f9d8ab26261382b66450d531798f73e Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou
Date: Thu, 30 Apr 2020 16:00:18 +0200
Subject: [PATCH] Rewrite `org-forward-paragraph' and `org-backward-paragraph'
* lisp/org.el (org-forward-paragraph):
(org-backward-paragraph): Rewrite functions. Add repeat argument.
Mimic more closely regular `forward|backward-paragraph' functions.
(org--forward-paragraph-once):
(org--backward-paragraph-once):
(org--paragraph-at-point): New functions.
* testing/lisp/test-org.el (test-org/forward-paragraph):
(test-org/backward-paragraph): Update tests. Add some.
Signed-off-by: Nicolas Goaziou
---
lisp/org.el | 440 ++-
testing/lisp/test-org.el | 255 ---
2 files changed, 471 insertions(+), 224 deletions(-)
diff --git a/lisp/org.el b/lisp/org.el
index b869e12e1..59187fe52 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -20500,156 +20500,300 @@ With ARG, repeats or can move forward if negative."
(interactive "p")
(org-next-visible-heading (- arg)))
-(defun org-forward-paragraph ()
- "Move forward to beginning of next paragraph or equivalent.
-
-The function moves point to the beginning of the next visible
-structural element, which can be a paragraph, a table, a list
-item, etc. It also provides some special moves for convenience:
-
- - On an affiliated keyword, jump to the beginning of the
-relative element.
- - On an item or a footnote definition, move to the second
-element inside, if any.
- - On a table or a property drawer, jump after it.
- - On a verse or source block, stop after blank lines."
+(defun org-forward-paragraph ( arg)
+ "Move forward by a paragraph, or equivalent, unit.
+
+With argument ARG, do it ARG times;
+a negative argument ARG = -N means move backward N paragraphs.
+
+The function moves point between two structural
+elements (paragraphs, tables, lists, etc.).
+
+It also provides the following special moves for convenience:
+
+ - on a table or a property drawer, move to its beginning;
+ - on comment, example, export, source and verse blocks, stop
+at blank lines;
+ - skip consecutive clocks, diary S-exps, and keywords."
+ (interactive "^p")
+ (unless arg (setq arg 1))
+ (if (< arg 0) (org-backward-paragraph (- arg))
+(while (and (> arg 0) (not (eobp)))
+ (org--forward-paragraph-once)
+ (cl-decf arg))
+;; Return moves left.
+arg))
+
+(defun org-backward-paragraph ( arg)
+ "Move backward by a paragraph, or equivalent, unit.
+
+With argument ARG, do it ARG times;
+a negative argument ARG = -N means move forward N paragraphs.
+
+The function moves point between two structural
+elements (paragraphs, tables, lists, etc.).
+
+It also provides the following special moves for convenience:
+
+ - on a table or a property drawer, move to its beginning;
+ - on comment, example, export, source and verse blocks, stop
+at blank lines;
+ - skip consecutive clocks, diary S-exps, and keywords."
+ (interactive "^p")
+ (unless arg (setq arg 1))
+ (if (< arg 0) (org-forward-paragraph (- arg))
+(while (and (> arg 0) (not (bobp)))
+ (org--backward-paragraph-once)
+ (cl-decf arg))
+;; Return moves left.
+arg))
+
+(defun org--paragraph-at-point ()
+ "Return paragraph, or equivalent, element at point.
+
+Paragraph element at point is the element at point, with the
+following special cases:
+
+- treat table rows (resp. node properties) as the table
+ \(resp. property drawer) containing them.
+
+- treat plain lists with an item every line as a whole.
+
+- treat consecutive keywords, clocks, and diary-sexps as a single
+ block.
+
+Function may return a real element, or a pseudo-element with type
+`pseudo-paragraph'."
+ (let* ((e (org-element-at-point))
+ (type (org-element-type e))
+ ;; If we need to fake a new pseudo-element, triplet is
+ ;;
+ ;; (BEG END PARENT)
+ ;;
+ ;; where BEG and END are element boundaries, and PARENT the
+ ;; element containing it, or nil.
+ (triplet
+ (cond
+ ((memq type '(table property-drawer))
+ (list (org-element-property :begin e)
+