Browse Source

Fix regression in `org-beginning-of-line'

* lisp/org.el (org-beginning-of-line): Leave point before any invisible
  character at column 0.  Small refactoring.
* testing/lisp/test-org.el (test-org/beginning-of-line): Add tests.

The regression was introduced in
3baf246f4f73005a4eacd7c368f7222f95d50243.
Nicolas Goaziou 8 years ago
parent
commit
756bb87d81
2 changed files with 36 additions and 22 deletions
  1. 22 17
      lisp/org.el
  2. 14 5
      testing/lisp/test-org.el

+ 22 - 17
lisp/org.el

@@ -23718,27 +23718,32 @@ first attempt, and only move to after the tags when the cursor is already
 beyond the end of the headline."
   (interactive "P")
   (let ((pos (point))
-	(special (if (consp org-special-ctrl-a/e)
-		     (car org-special-ctrl-a/e)
-		   org-special-ctrl-a/e))
-	deactivate-mark	refpos)
-    (call-interactively (if (bound-and-true-p visual-line-mode)
-			    #'beginning-of-visual-line
-			  #'move-beginning-of-line))
+	(special (pcase org-special-ctrl-a/e
+		   (`(,C-a . _) C-a)
+		   (C-a C-a)))
+	deactivate-mark)
+    (if (bound-and-true-p visual-line-mode)
+	(call-interactively #'beginning-of-visual-line)
+      (call-interactively #'move-beginning-of-line)
+      ;; `move-beginning-of-line' may leave point after invisible
+      ;; characters if line starts with such of these (e.g., with
+      ;; a link at column 0).  Really move to the beginning of the
+      ;; current visible line.
+      (beginning-of-line))
     (cond
      ((or arg (not special)))
      ((and (looking-at org-complex-heading-regexp)
 	   (eq (char-after (match-end 1)) ?\s))
-      (setq refpos (min (1+ (or (match-end 3) (match-end 2) (match-end 1)))
-			(point-at-eol)))
-      (goto-char
-       (if (eq special t)
-	   (cond ((> pos refpos) refpos)
-		 ((= pos (point)) refpos)
-		 (t (point)))
-	 (cond ((> pos (point)) (point))
-	       ((not (eq last-command this-command)) (point))
-	       (t refpos)))))
+      (let ((refpos (min (1+ (or (match-end 3) (match-end 2) (match-end 1)))
+			 (line-end-position))))
+	(goto-char
+	 (if (eq special t)
+	     (cond ((> pos refpos) refpos)
+		   ((= pos (point)) refpos)
+		   (t (point)))
+	   (cond ((> pos (point)) (point))
+		 ((not (eq last-command this-command)) (point))
+		 (t refpos))))))
      ((org-at-item-p)
       ;; Being at an item and not looking at an the item means point
       ;; was previously moved to beginning of a visual line, which

+ 14 - 5
testing/lisp/test-org.el

@@ -2469,24 +2469,33 @@ http://article.gmane.org/gmane.emacs.orgmode/21459/"
   "Test `org-beginning-of-line' specifications."
   ;; Standard test.
   (should
-   (org-test-with-temp-text "Some text\nSome other text"
+   (org-test-with-temp-text "Some text\nSome other text<point>"
      (progn (org-beginning-of-line) (bolp))))
   ;; Standard test with `visual-line-mode'.
   (should-not
-   (org-test-with-temp-text "A long line of text\nSome other text"
+   (org-test-with-temp-text "A <point>long line of text\nSome other text"
      (progn (visual-line-mode)
-	    (forward-char 2)
 	    (dotimes (i 1000) (insert "very "))
 	    (org-beginning-of-line)
 	    (bolp))))
   ;; At an headline with special movement.
   (should
-   (org-test-with-temp-text "* TODO Headline"
+   (org-test-with-temp-text "* TODO Headline<point>"
      (let ((org-special-ctrl-a/e t))
-       (org-end-of-line)
        (and (progn (org-beginning-of-line) (looking-at "Headline"))
 	    (progn (org-beginning-of-line) (bolp))
 	    (progn (org-beginning-of-line) (looking-at "Headline"))))))
+  ;; Leave point before invisible characters at column 0.
+  (should
+   (org-test-with-temp-text "[[http://orgmode.org]]<point>"
+     (let ((org-special-ctrl-a/e nil))
+       (org-beginning-of-line)
+       (bolp))))
+  (should
+   (org-test-with-temp-text "[[http://orgmode.org]]<point>"
+     (let ((org-special-ctrl-a/e t))
+       (org-beginning-of-line)
+       (bolp))))
   ;; Special case: Do not error when the buffer contains only a single
   ;; asterisk.
   (should