Browse Source

Fix `org-backward-sentence' and `org-forward-sentence'

* lisp/org.el (org-backward-sentence):
(org-forward-sentence): Properly move at the boundaries of an element.

* testing/lisp/test-org.el (test-org/forward-sentence):
(test-org/backward-sentence): New tests.

Reported-by: Rasmus <rasmus@gmx.us>
<http://permalink.gmane.org/gmane.emacs.orgmode/96377>
Nicolas Goaziou 6 years ago
parent
commit
98ec17e204
2 changed files with 90 additions and 6 deletions
  1. 31 6
      lisp/org.el
  2. 59 0
      testing/lisp/test-org.el

+ 31 - 6
lisp/org.el

@@ -23838,18 +23838,43 @@ the cursor is already beyond the end of the headline."
 This will call `backward-sentence' or `org-table-beginning-of-field',
 depending on context."
   (interactive "P")
-  (cond
-   ((org-at-table-p) (call-interactively 'org-table-beginning-of-field))
-   (t (call-interactively 'backward-sentence))))
+  (let* ((element (org-element-at-point))
+	 (contents-begin (org-element-property :contents-begin element))
+	 (table (org-element-lineage element '(table) t)))
+    (if (and table
+	     (> (point) contents-begin)
+	     (<= (point) (org-element-property :contents-end table)))
+	(call-interactively #'org-table-beginning-of-field)
+      (save-restriction
+	(when (and contents-begin
+		   (< (point-min) contents-begin)
+		   (> (point) contents-begin))
+	  (narrow-to-region contents-begin
+			    (org-element-property :contents-end element)))
+	(call-interactively #'backward-sentence)))))
 
 (defun org-forward-sentence (&optional arg)
   "Go to end of sentence, or end of table field.
 This will call `forward-sentence' or `org-table-end-of-field',
 depending on context."
   (interactive "P")
-  (cond
-   ((org-at-table-p) (call-interactively 'org-table-end-of-field))
-   (t (call-interactively 'forward-sentence))))
+  (let* ((element (org-element-at-point))
+	 (contents-end (org-element-property :contents-end element))
+	 (table (org-element-lineage element '(table) t)))
+    (if (and table
+	     (>= (point) (org-element-property :contents-begin table))
+	     (< (point) contents-end))
+	(call-interactively #'org-table-end-of-field)
+      (save-restriction
+	(when (and contents-end
+		   (> (point-max) contents-end)
+		   ;; Skip blank lines between elements.
+		   (< (org-element-property :end element)
+		      (save-excursion (goto-char contents-end)
+				      (skip-chars-forward " \r\t\n"))))
+	  (narrow-to-region (org-element-property :contents-begin element)
+			    contents-end))
+	(call-interactively #'forward-sentence)))))
 
 (define-key org-mode-map "\M-a" 'org-backward-sentence)
 (define-key org-mode-map "\M-e" 'org-forward-sentence)

+ 59 - 0
testing/lisp/test-org.el

@@ -1744,6 +1744,65 @@ drops support for Emacs 24.1 and 24.2."
        (org-end-of-line)
        (eobp)))))
 
+(ert-deftest test-org/forward-sentence ()
+  "Test `org-forward-sentence' specifications."
+  ;; At the end of a table cell, move to the end of the next one.
+  (should
+   (org-test-with-temp-text "| a<point> | b |"
+     (org-forward-sentence)
+     (looking-at " |$")))
+  ;; Elsewhere in a cell, move to its end.
+  (should
+   (org-test-with-temp-text "| a<point>c | b |"
+     (org-forward-sentence)
+     (looking-at " | b |$")))
+  ;; Otherwise, simply call `forward-sentence'.
+  (should
+   (org-test-with-temp-text "Sentence<point> 1.  Sentence 2."
+     (org-forward-sentence)
+     (looking-at "  Sentence 2.")))
+  (should
+   (org-test-with-temp-text "Sentence<point> 1.  Sentence 2."
+     (org-forward-sentence)
+     (org-forward-sentence)
+     (eobp)))
+  ;; At the end of an element, jump to the next one, without stopping
+  ;; on blank lines in-between.
+  (should
+   (org-test-with-temp-text "Paragraph 1.<point>\n\nParagraph 2."
+     (org-forward-sentence)
+     (eobp))))
+
+(ert-deftest test-org/backward-sentence ()
+  "Test `org-backward-sentence' specifications."
+  ;; At the beginning of a table cell, move to the beginning of the
+  ;; previous one.
+  (should
+   (org-test-with-temp-text "| a | <point>b |"
+     (org-backward-sentence)
+     (looking-at "a | b |$")))
+  ;; Elsewhere in a cell, move to its beginning.
+  (should
+   (org-test-with-temp-text "| a | b<point>c |"
+     (org-backward-sentence)
+     (looking-at "bc |$")))
+  ;; Otherwise, simply call `backward-sentence'.
+  (should
+   (org-test-with-temp-text "Sentence 1.  Sentence<point> 2."
+     (org-backward-sentence)
+     (looking-at "Sentence 2.")))
+  (should
+   (org-test-with-temp-text "Sentence 1.  Sentence<point> 2."
+     (org-backward-sentence)
+     (org-backward-sentence)
+     (bobp)))
+  ;; Make sure to hit the beginning of a sentence on the same line as
+  ;; an item.
+  (should
+   (org-test-with-temp-text "- Line 1\n  line <point>2."
+     (org-backward-sentence)
+     (looking-at "Line 1"))))
+
 (ert-deftest test-org/forward-paragraph ()
   "Test `org-forward-paragraph' specifications."
   ;; At end of buffer, return an error.