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."
 beyond the end of the headline."
   (interactive "P")
   (interactive "P")
   (let ((pos (point))
   (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
     (cond
      ((or arg (not special)))
      ((or arg (not special)))
      ((and (looking-at org-complex-heading-regexp)
      ((and (looking-at org-complex-heading-regexp)
 	   (eq (char-after (match-end 1)) ?\s))
 	   (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)
      ((org-at-item-p)
       ;; Being at an item and not looking at an the item means point
       ;; Being at an item and not looking at an the item means point
       ;; was previously moved to beginning of a visual line, which
       ;; 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."
   "Test `org-beginning-of-line' specifications."
   ;; Standard test.
   ;; Standard test.
   (should
   (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))))
      (progn (org-beginning-of-line) (bolp))))
   ;; Standard test with `visual-line-mode'.
   ;; Standard test with `visual-line-mode'.
   (should-not
   (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)
      (progn (visual-line-mode)
-	    (forward-char 2)
 	    (dotimes (i 1000) (insert "very "))
 	    (dotimes (i 1000) (insert "very "))
 	    (org-beginning-of-line)
 	    (org-beginning-of-line)
 	    (bolp))))
 	    (bolp))))
   ;; At an headline with special movement.
   ;; At an headline with special movement.
   (should
   (should
-   (org-test-with-temp-text "* TODO Headline"
+   (org-test-with-temp-text "* TODO Headline<point>"
      (let ((org-special-ctrl-a/e t))
      (let ((org-special-ctrl-a/e t))
-       (org-end-of-line)
        (and (progn (org-beginning-of-line) (looking-at "Headline"))
        (and (progn (org-beginning-of-line) (looking-at "Headline"))
 	    (progn (org-beginning-of-line) (bolp))
 	    (progn (org-beginning-of-line) (bolp))
 	    (progn (org-beginning-of-line) (looking-at "Headline"))))))
 	    (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
   ;; Special case: Do not error when the buffer contains only a single
   ;; asterisk.
   ;; asterisk.
   (should
   (should