summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2016-10-15 11:24:16 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2016-10-15 12:00:43 +0200
commit8d2f0a441174c703ed0ed570e2f0eaf0da5d6aeb (patch)
treeb78c14135aa552d87ace1ba8e3a69df177e4382e
parent5c85409464f0f06e60fabfbbf3d0958a57e169fd (diff)
downloadorg-mode-8d2f0a441174c703ed0ed570e2f0eaf0da5d6aeb.tar.gz
Fix `C-a' with visual lines and arguments
* lisp/org.el (org-beginning-of-line): Move to beginning of visual line when appropriate. Fix docstring. * testing/lisp/test-org.el (test-org/beginning-of-line): Add tests.
-rw-r--r--lisp/org.el69
-rw-r--r--testing/lisp/test-org.el75
2 files changed, 103 insertions, 41 deletions
diff --git a/lisp/org.el b/lisp/org.el
index 99ffdf9..732f7e0 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -23710,45 +23710,50 @@ package ox-bibtex by Taru Karttunen."
;;;; Functions extending outline functionality
-(defun org-beginning-of-line (&optional arg)
- "Go to the beginning of the current line.
-
-If that is invisible, continue to a visible line beginning.
+(defun org-beginning-of-line (&optional n)
+ "Go to the beginning of the current visible line.
If this is a headline, and `org-special-ctrl-a/e' is set, ignore
tags on the 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))
+the cursor is already beyond the end of the headline.
+
+With argument N not nil or 1, move forward N - 1 lines first."
+ (interactive "^p")
+ (let ((origin (point))
(special (pcase org-special-ctrl-a/e
- (`(,C-a . _) C-a)
- (C-a C-a)))
+ (`(,C-a . _) C-a) (_ org-special-ctrl-a/e)))
deactivate-mark)
+ ;; First move to a visible line.
(if (bound-and-true-p visual-line-mode)
- (call-interactively #'beginning-of-visual-line)
- (call-interactively #'move-beginning-of-line)
+ (beginning-of-visual-line n)
+ (move-beginning-of-line n)
;; `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))
+ ;; No special behavior. Point is already at the beginning of
+ ;; a line, logical or visual.
+ ((not special))
+ ;; `beginning-of-visual-line' left point before logical beginning
+ ;; of line: point is at the beginning of a visual line. Bail
+ ;; out.
+ ((and (bound-and-true-p visual-line-mode) (not (bolp))))
+ ((looking-at org-complex-heading-regexp)
+ ;; At a headline, special position is before the title, but
+ ;; after any TODO keyword or priority cookie.
(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))))))
+ (line-end-position)))
+ (bol (point)))
+ (if (eq special 'reversed)
+ (when (and (= origin bol) (eq last-command this-command))
+ (goto-char refpos))
+ (when (or (> origin refpos) (= origin bol))
+ (goto-char refpos)))))
((and (looking-at org-list-full-item-re)
- (save-match-data (memq (org-element-type (org-element-at-point))
- '(item plain-list))))
+ (memq (org-element-type (save-match-data (org-element-at-point)))
+ '(item plain-list)))
;; Set special position at first white space character after
;; bullet, and check-box, if any.
(let ((after-bullet
@@ -23756,15 +23761,13 @@ the cursor is already beyond the end of the headline."
(cond ((not box) (match-end 1))
((eq (char-after box) ?\s) (1+ box))
(t box)))))
- ;; Special case: Move point to special position when currently
- ;; after it or at beginning of line.
- (if (eq special t)
- (when (or (> pos after-bullet) (= (point) pos))
+ (if (eq special 'reversed)
+ (when (and (= (point) origin) (eq last-command this-command))
(goto-char after-bullet))
- ;; Reversed case: Move point to special position when point
- ;; was already at beginning of line and command is repeated.
- (when (and (= (point) pos) (eq last-command this-command))
- (goto-char after-bullet))))))))
+ (when (or (> origin after-bullet) (= (point) origin))
+ (goto-char after-bullet)))))
+ ;; No special context. Point is already at beginning of line.
+ (t nil))))
(defun org-end-of-line (&optional n)
"Go to the end of the line, but before ellipsis, if any.
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 08ce4d8..915d229 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -2467,24 +2467,78 @@ http://article.gmane.org/gmane.emacs.orgmode/21459/"
(ert-deftest test-org/beginning-of-line ()
"Test `org-beginning-of-line' specifications."
- ;; Standard test.
+ ;; Move to beginning of line. If current line in invisible, move to
+ ;; beginning of visible line instead.
(should
(org-test-with-temp-text "Some text\nSome other text<point>"
- (progn (org-beginning-of-line) (bolp))))
- ;; Standard test with `visual-line-mode'.
+ (org-beginning-of-line)
+ (bolp)))
+ (should
+ (org-test-with-temp-text "* H1\n** H2<point>"
+ (org-overview)
+ (org-beginning-of-line)
+ (= (line-beginning-position) 1)))
+ ;; With `visual-line-mode' active, move to beginning of visual line.
(should-not
(org-test-with-temp-text "A <point>long line of text\nSome other text"
- (progn (visual-line-mode)
- (dotimes (i 1000) (insert "very "))
- (org-beginning-of-line)
- (bolp))))
- ;; At an headline with special movement.
+ (visual-line-mode)
+ (dotimes (i 1000) (insert "very "))
+ (org-beginning-of-line)
+ (bolp)))
+ ;; In a wide headline, with `visual-line-mode', prefer going to the
+ ;; beginning of a visual line than to the logical beginning of line,
+ ;; even if special movement is active.
+ (should-not
+ (org-test-with-temp-text "* A <point>long headline"
+ (visual-line-mode)
+ (dotimes (i 1000) (insert "very "))
+ (goto-char (point-max))
+ (org-beginning-of-line)
+ (bobp)))
+ (should-not
+ (org-test-with-temp-text "* A <point>long headline"
+ (visual-line-mode)
+ (dotimes (i 1000) (insert "very "))
+ (goto-char (point-max))
+ (let ((org-special-ctrl-a/e t)) (org-beginning-of-line))
+ (bobp)))
+ ;; At an headline with special movement, first move at beginning of
+ ;; title, then at the beginning of line, rinse, repeat.
(should
(org-test-with-temp-text "* TODO Headline<point>"
(let ((org-special-ctrl-a/e t))
(and (progn (org-beginning-of-line) (looking-at "Headline"))
(progn (org-beginning-of-line) (bolp))
(progn (org-beginning-of-line) (looking-at "Headline"))))))
+ (should
+ (org-test-with-temp-text "* TODO [#A] Headline<point>"
+ (let ((org-special-ctrl-a/e t))
+ (org-beginning-of-line)
+ (looking-at "Headline"))))
+ ;; At an headline with reversed movement, first move to beginning of
+ ;; line, then to the beginning of title.
+ (should
+ (org-test-with-temp-text "* TODO Headline<point>"
+ (let ((org-special-ctrl-a/e 'reversed)
+ (this-command last-command))
+ (and (progn (org-beginning-of-line) (bolp))
+ (progn (org-beginning-of-line) (looking-at "Headline"))))))
+ ;; At an item with special movement, first move after to beginning
+ ;; of title, then to the beginning of line, rinse, repeat.
+ (should
+ (org-test-with-temp-text "- [ ] Item<point>"
+ (let ((org-special-ctrl-a/e t))
+ (and (progn (org-beginning-of-line) (looking-at "Item"))
+ (progn (org-beginning-of-line) (bolp))
+ (progn (org-beginning-of-line) (looking-at "Item"))))))
+ ;; At an item with reversed movement, first move to beginning of
+ ;; line, then to the beginning of title.
+ (should
+ (org-test-with-temp-text "- [X] Item<point>"
+ (let ((org-special-ctrl-a/e 'reversed)
+ (this-command last-command))
+ (and (progn (org-beginning-of-line) (bolp))
+ (progn (org-beginning-of-line) (looking-at "Item"))))))
;; Leave point before invisible characters at column 0.
(should
(org-test-with-temp-text "[[http://orgmode.org]]<point>"
@@ -2496,6 +2550,11 @@ http://article.gmane.org/gmane.emacs.orgmode/21459/"
(let ((org-special-ctrl-a/e t))
(org-beginning-of-line)
(bolp))))
+ (should
+ (org-test-with-temp-text "[[http<point>://orgmode.org]]"
+ (visual-line-mode)
+ (org-beginning-of-line)
+ (bolp)))
;; Special case: Do not error when the buffer contains only a single
;; asterisk.
(should