branch: elpa/evil commit cb39d3dc9f0806366e8a37a61ff967fa329b78a2 Author: Tom Dalziel <33435574+tomd...@users.noreply.github.com> Commit: GitHub <nore...@github.com>
Add evil-start-of-line, evil-ensure-column, and use them (#1524) --- evil-commands.el | 112 ++++++++++---------- evil-common.el | 12 +++ evil-macros.el | 1 + evil-tests.el | 307 ++++++++++++++++++++++++++++++++++++++++--------------- evil-types.el | 6 +- evil-vars.el | 10 ++ 6 files changed, 309 insertions(+), 139 deletions(-) diff --git a/evil-commands.el b/evil-commands.el index c17d533..990cacb 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -293,19 +293,17 @@ of the current screen line." (evil-first-non-blank)) (evil-define-motion evil-goto-line (count) - "Go to the first non-blank character of line COUNT. -By default the last line." + "Go to line COUNT. By default the last line." :jump t :type line - (if (null count) - (with-no-warnings (end-of-buffer)) - (goto-char (point-min)) - (forward-line (1- count))) - (evil-first-non-blank)) + (evil-ensure-column + (if (null count) + (with-no-warnings (end-of-buffer)) + (goto-char (point-min)) + (forward-line (1- count))))) (evil-define-motion evil-goto-first-line (count) - "Go to the first non-blank character of line COUNT. -By default the first line." + "Go to line COUNT. By default the first line." :jump t :type line (evil-goto-line (or count 1))) @@ -492,14 +490,14 @@ and jump to the corresponding one." (cond ;; COUNT% jumps to a line COUNT percentage down the file (count - (goto-char - (evil-normalize-position - (let ((size (- (point-max) (point-min)))) - (+ (point-min) - (if (> size 80000) - (* count (/ size 100)) - (/ (* count size) 100)))))) - (back-to-indentation) + (evil-ensure-column + (goto-char + (evil-normalize-position + (let ((size (- (point-max) (point-min)))) + (+ (point-min) + (if (> size 80000) + (* count (/ size 100)) + (/ (* count size) 100))))))) (setq evil-this-type 'line)) ((and (evil-looking-at-start-comment t) (let ((pnt (point))) @@ -976,32 +974,29 @@ In Insert state, insert a newline and indent." (evil-ret-gen count t)) (evil-define-motion evil-window-top (count) - "Move the cursor to line COUNT from the top of the window -on the first non-blank character." + "Move the cursor to line COUNT from the top of the window." :jump t :type line - (move-to-window-line (max (or count 0) - (if (= (point-min) (window-start)) - 0 - scroll-margin))) - (back-to-indentation)) + (evil-ensure-column + (move-to-window-line (max (or count 0) + (if (= (point-min) (window-start)) + 0 + scroll-margin))))) (evil-define-motion evil-window-middle () - "Move the cursor to the middle line in the window -on the first non-blank character." + "Move the cursor to the middle line in the window." :jump t :type line - (move-to-window-line - (/ (1+ (save-excursion (move-to-window-line -1))) 2)) - (back-to-indentation)) + (evil-ensure-column + (move-to-window-line + (/ (1+ (save-excursion (move-to-window-line -1))) 2)))) (evil-define-motion evil-window-bottom (count) - "Move the cursor to line COUNT from the bottom of the window -on the first non-blank character." + "Move the cursor to line COUNT from the bottom of the window." :jump t :type line - (move-to-window-line (- (max (or count 1) (1+ scroll-margin)))) - (back-to-indentation)) + (evil-ensure-column + (move-to-window-line (- (max (or count 1) (1+ scroll-margin)))))) ;; scrolling (evil-define-command evil-scroll-line-up (count) @@ -1037,7 +1032,7 @@ If the scroll count is zero the command scrolls half the screen." :repeat nil :keep-visual t (interactive "<c>") - (evil-save-column + (evil-ensure-column (setq count (or count (max 0 evil-scroll-count))) (setq evil-scroll-count count) (when (= (point-min) (line-beginning-position)) @@ -1062,7 +1057,7 @@ If the scroll count is zero the command scrolls half the screen." :repeat nil :keep-visual t (interactive "<c>") - (evil-save-column + (evil-ensure-column (setq count (or count (max 0 evil-scroll-count))) (setq evil-scroll-count count) (when (eobp) (signal 'end-of-buffer nil)) @@ -1098,7 +1093,7 @@ If the scroll count is zero the command scrolls half the screen." :repeat nil :keep-visual t (interactive "p") - (evil-save-column + (evil-ensure-column (dotimes (i count) (condition-case err (scroll-down nil) @@ -1112,7 +1107,7 @@ If the scroll count is zero the command scrolls half the screen." :repeat nil :keep-visual t (interactive "p") - (evil-save-column + (evil-ensure-column (dotimes (i count) (condition-case err (scroll-up nil) @@ -1495,10 +1490,15 @@ Save in REGISTER or in the kill-ring with YANK-HANDLER." (delete-region (1- beg) end)) (t (delete-region beg end))) - ;; place cursor on beginning of line (when (and (called-interactively-p 'any) (eq type 'line)) - (evil-first-non-blank))) + (evil-first-non-blank) + (when (and (not evil-start-of-line) + evil-operator-start-col + ;; Special exceptions to ever saving column: + (not (memq evil-this-motion '(evil-forward-word-begin + evil-forward-WORD-begin)))) + (move-to-column evil-operator-start-col)))) (evil-define-operator evil-delete-line (beg end type register yank-handler) "Delete to end of line." @@ -1918,10 +1918,9 @@ but doesn't insert or remove any spaces." The text is shifted to the nearest multiple of `evil-shift-width' \(the rounding can be disabled by setting `evil-shift-round'). If PRESERVE-EMPTY is non-nil, lines that contain only spaces are -indented, too, otherwise they are ignored. The relative column -of point is preserved if this function is not called -interactively. Otherwise, if the function is called as an -operator, point is moved to the first non-blank character. +indented, too, otherwise they are ignored. Location of point +is preserved relative to text when called from insert state. +Otherwise, it is determined by `evil-start-of-line' and/or `evil-track-eol'. See also `evil-shift-right'." :type line (interactive "<r><vc>") @@ -1932,17 +1931,20 @@ See also `evil-shift-right'." The text is shifted to the nearest multiple of `evil-shift-width' \(the rounding can be disabled by setting `evil-shift-round'). If PRESERVE-EMPTY is non-nil, lines that contain only spaces are -indented, too, otherwise they are ignored. The relative column -of point is preserved if this function is not called -interactively. Otherwise, if the function is called as an -operator, point is moved to the first non-blank character. +indented, too, otherwise they are ignored. Location of point +is preserved relative to text when called from insert state. +Otherwise, it is determined by `evil-start-of-line' and/or `evil-track-eol'. See also `evil-shift-left'." :type line + :move-point nil ; point is moved according to `evil-start-of-line' and state (interactive "<r><vc>") (setq count (or count 1)) (let ((beg (set-marker (make-marker) beg)) (end (set-marker (make-marker) end)) - (pnt-indent (current-column)) + (col-for-insert (current-column)) + (goal-col (if (consp temporary-goal-column) + (car temporary-goal-column) + temporary-goal-column)) first-shift) ; shift of first line (save-excursion (goto-char beg) @@ -1975,10 +1977,14 @@ See also `evil-shift-left'." (setq first-shift (* count evil-shift-width)) (indent-to first-shift))) ;; When called from insert state (C-t or C-d) the cursor should shift with the line, - ;; otherwise (normal state) it should end up on the first non-whitespace character - (if (evil-insert-state-p) - (move-to-column (max 0 (+ pnt-indent first-shift))) - (evil-first-non-blank)))) + ;; otherwise (normal state) its position is determined by `evil-start-of-line'. + (cond + ((evil-insert-state-p) (move-to-column (max 0 (+ col-for-insert first-shift)))) + (evil-start-of-line (evil-first-non-blank)) + (t (move-to-column (if (and evil-track-eol (= goal-col most-positive-fixnum)) + goal-col + evil-operator-start-col)))) + (setq temporary-goal-column 0))) (evil-define-command evil-shift-right-line (count) "Shift the current line COUNT times to the right. @@ -3950,7 +3956,7 @@ range. The given argument is passed straight to "Go to POSITION in the buffer. Default position is the beginning of the buffer." :jump t - (interactive "<N>Goto position: ") + (interactive "<N>") (let ((position (evil-normalize-position (or position (point-min))))) (goto-char position))) diff --git a/evil-common.el b/evil-common.el index b68e1ca..3ac0cd5 100644 --- a/evil-common.el +++ b/evil-common.el @@ -986,6 +986,18 @@ See also `evil-save-goal-column'." ,@body (move-to-column col)))) +(defmacro evil-ensure-column (&rest body) + "Ensures appropriate column after exeution of BODY. +Appropriate column is determined by `evil-start-of-line'." + (declare (indent defun) + (debug t)) + `(let ((col (current-column))) + (evil-save-goal-column + ,@body + (if evil-start-of-line + (evil-first-non-blank) + (move-to-column col))))) + (defun evil-narrow (beg end) "Restrict the buffer to BEG and END. BEG or END may be nil, specifying a one-sided restriction including diff --git a/evil-macros.el b/evil-macros.el index 7331ae2..329f54c 100644 --- a/evil-macros.el +++ b/evil-macros.el @@ -538,6 +538,7 @@ Optional keyword arguments are: evil-inhibit-operator) (setq evil-inhibit-operator-value nil evil-this-operator this-command) + (setq evil-operator-start-col (current-column)) (prog1 ,interactive (setq orig (point) evil-inhibit-operator-value evil-inhibit-operator) diff --git a/evil-tests.el b/evil-tests.el index 680acb7..53f968f 100644 --- a/evil-tests.el +++ b/evil-tests.el @@ -645,7 +645,7 @@ Below some empty line")) Below some empty line" ("dV}") - "[B]elow some empty line"))) + "Below [s]ome empty line"))) ;;; Insertion @@ -1723,51 +1723,101 @@ New Tex[t] ("2d2l") ";; [o]tes.")) (ert-info ("Delete current line") - (evil-test-buffer - ";; [T]his buffer is for notes you don't want to save, + (ert-info ("With `evil-start-of-line' `nil'") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." - ("dd") - "[;]; and for Lisp evaluation.") - (evil-test-buffer - ";; [T]his buffer is for notes you don't want to save, + ("dd") + ";; [a]nd for Lisp evaluation.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." - ("d1d") - "[;]; and for Lisp evaluation.") - (evil-test-buffer - ";; [T]his buffer is for notes you don't want to save, + ("d1d") + ";; [a]nd for Lisp evaluation.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." - ("1dd") - "[;]; and for Lisp evaluation.") - (evil-test-buffer - ";; [T]his buffer is for notes you don't want to save, + ("1dd") + ";; [a]nd for Lisp evaluation.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save, +;; and for Lisp evaluation." + ("1d1d") + ";; [a]nd for Lisp evaluation.")) + (ert-info ("With `evil-start-of-line' `t'") + (let ((evil-start-of-line t)) + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save, ;; and for Lisp evaluation." - ("1d1d") - "[;]; and for Lisp evaluation.")) + ("dd") + "[;]; and for Lisp evaluation.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save, +;; and for Lisp evaluation." + ("d1d") + "[;]; and for Lisp evaluation.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save, +;; and for Lisp evaluation." + ("1dd") + "[;]; and for Lisp evaluation.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save, +;; and for Lisp evaluation." + ("1d1d") + "[;]; and for Lisp evaluation.")))) (ert-info ("Delete two lines") - (evil-test-buffer - ";; [T]his buffer is for notes you don't want to save. + (ert-info ("With `evil-start-of-line' `nil'") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." - ("d2d") - "[;]; then enter the text in that file's own buffer.") - (evil-test-buffer - ";; [T]his buffer is for notes you don't want to save. + ("d2d") + ";; [t]hen enter the text in that file's own buffer.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." - ("2dd") - "[;]; then enter the text in that file's own buffer.") - (evil-test-buffer - ";; [T]his buffer is for notes you don't want to save. + ("2dd") + ";; [t]hen enter the text in that file's own buffer.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." - ("dj") - "[;]; then enter the text in that file's own buffer.") - (evil-test-buffer - ";; This buffer is for notes you don't want to save. + ("dj") + ";; [t]hen enter the text in that file's own buffer.") + (evil-test-buffer + ";; This buffer is for notes you don't want to save. +;; [I]f you want to create a file, visit that file with C-x C-f, +;; then enter the text in that file's own buffer." + ("dk") + ";; [t]hen enter the text in that file's own buffer.")) + (ert-info ("With `evil-start-of-line' `t'") + (let ((evil-start-of-line t)) + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save. +;; If you want to create a file, visit that file with C-x C-f, +;; then enter the text in that file's own buffer." + ("d2d") + "[;]; then enter the text in that file's own buffer.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save. +;; If you want to create a file, visit that file with C-x C-f, +;; then enter the text in that file's own buffer." + ("2dd") + "[;]; then enter the text in that file's own buffer.") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save. +;; If you want to create a file, visit that file with C-x C-f, +;; then enter the text in that file's own buffer." + ("dj") + "[;]; then enter the text in that file's own buffer.") + (evil-test-buffer + ";; This buffer is for notes you don't want to save. ;; [I]f you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." - ("dk") - "[;]; then enter the text in that file's own buffer."))) + ("dk") + "[;]; then enter the text in that file's own buffer."))))) (evil-define-motion evil-test-square-motion (count) "Test motion for selecting a square." @@ -1865,23 +1915,36 @@ New Tex[t] ("P") ";; This buffe[r] is for notes you don't want to save")) (ert-info ("Delete lines") - (evil-test-buffer - ";; [T]his buffer is for notes you don't want to save. + (ert-info ("With `evil-start-of-line' `nil'") + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." - ("2dd") - "[;]; then enter the text in that file's own buffer." - ("P") - "[;]; This buffer is for notes you don't want to save. + ("2dd") + ";; [t]hen enter the text in that file's own buffer." + ("P") + "[;]; This buffer is for notes you don't want to save. ;; If you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer.")) + (ert-info ("With `evil-start-of-line' `t'") + (let ((evil-start-of-line t)) + (evil-test-buffer + ";; [T]his buffer is for notes you don't want to save. +;; If you want to create a file, visit that file with C-x C-f, +;; then enter the text in that file's own buffer." + ("2dd") + "[;]; then enter the text in that file's own buffer." + ("P") + "[;]; This buffer is for notes you don't want to save. +;; If you want to create a file, visit that file with C-x C-f, +;; then enter the text in that file's own buffer.")))) (ert-info ("Delete last line") (evil-test-buffer ";; This buffer is for notes you don't want to save. ;; [I]f you want to create a file, visit that file with C-x C-f, ;; then enter the text in that file's own buffer." ("2dd") - "[;]; This buffer is for notes you don't want to save.")) + ";; [T]his buffer is for notes you don't want to save.")) (ert-info ("Delete last empty line") (evil-test-buffer "line 1\nline 2\n\n[]" @@ -2249,22 +2312,45 @@ Below some empty line"))) (let ((evil-shift-width 4) indent-tabs-mode) (ert-info ("Shift linewise") - (evil-test-buffer - "[l]ine 1\nline 2\nline 3\n" - ("Vj>") - " [l]ine 1\n line 2\nline 3\n")) + (ert-info ("With `evil-start-of-line' `nil'") + (evil-test-buffer + "[l]ine 1\nline 2\nline 3\n" + ("Vj>") + "[ ] line 1\n line 2\nline 3\n")) + (ert-info ("With `evil-start-of-line' `t'") + (let ((evil-start-of-line t)) + (evil-test-buffer + "[l]ine 1\nline 2\nline 3\n" + ("Vj>") + " [l]ine 1\n line 2\nline 3\n")))) (ert-info ("Shift char selection on whole line") - (evil-test-buffer - "[l]ine 1\nline 2\nline 3\n" - ("v$>") - " [l]ine 1\nline 2\nline 3\n")) + (ert-info ("With `evil-start-of-line' `nil'") + (evil-test-buffer + "[l]ine 1\nline 2\nline 3\n" + ("v$>") + " line [1]\nline 2\nline 3\n")) + (ert-info ("With `evil-start-of-line' `t'") + (let ((evil-start-of-line t)) + (evil-test-buffer + "[l]ine 1\nline 2\nline 3\n" + ("v$>") + " [l]ine 1\nline 2\nline 3\n")))) (ert-info ("Shift visual with count") - (evil-test-buffer - "[l]ine 1\nline 2\nline 3\n" - ("Vj3>") - " [l]ine 1\n line 2\nline 3\n" - ("Vj2<") - " [l]ine 1\n line 2\nline 3\n")) + (ert-info ("With `evil-start-of-line' `nil'") + (evil-test-buffer + "[l]ine 1\nline 2\nline 3\n" + ("Vj3>") + "[ ] line 1\n line 2\nline 3\n" + ("Vj2<") + "[ ] line 1\n line 2\nline 3\n")) + (ert-info ("With `evil-start-of-line' `t'") + (let ((evil-start-of-line t)) + (evil-test-buffer + "[l]ine 1\nline 2\nline 3\n" + ("Vj3>") + " [l]ine 1\n line 2\nline 3\n" + ("Vj2<") + " [l]ine 1\n line 2\nline 3\n")))) (ert-info ("Shift in insert state") (evil-test-buffer "line 1\nl[i]ne 2\nline 3\n" @@ -2866,7 +2952,7 @@ word3[]")) "[l]ine 1\n" ("GiABC" [escape]) "line 1\nAB[C]" - ("gg\".P") + ("go\".P") "AB[C]line 1\nABC")) (ert-deftest evil-test-zero-register () @@ -3188,58 +3274,112 @@ Below some empty line"))) (ert-deftest evil-test-goto-first-line () "Test `evil-goto-first-line' motion" :tags '(evil motion) - (evil-test-buffer - "[i]nt main(int argc, char** argv) + (ert-info ("With `evil-start-of-line' `nil'") + (evil-test-buffer + "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" - ("3gg") - "int main(int argc, char** argv) + ("3gg") + "int main(int argc, char** argv) { - [p]rintf(\"Hello world\\n\"); +[ ] printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" - ("gg") - "[i]nt main(int argc, char** argv) + ("gg") + "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" - ("100gg") - "int main(int argc, char** argv) + ("100gg") + "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]")) + (ert-info ("With `evil-start-of-line' `nil'") + (let ((evil-start-of-line t)) + (evil-test-buffer + "[i]nt main(int argc, char** argv) +{ + printf(\"Hello world\\n\"); + return EXIT_SUCCESS; +}" + ("3gg") + "int main(int argc, char** argv) +{ + [p]rintf(\"Hello world\\n\"); + return EXIT_SUCCESS; +}" + ("gg") + "[i]nt main(int argc, char** argv) +{ + printf(\"Hello world\\n\"); + return EXIT_SUCCESS; +}" + ("100gg") + "int main(int argc, char** argv) +{ + printf(\"Hello world\\n\"); + return EXIT_SUCCESS; +\[}]")))) (ert-deftest evil-test-goto-line () "Test `evil-goto-line' motion" :tags '(evil motion) - (evil-test-buffer - "[i]nt main(int argc, char** argv) + (ert-info ("With `evil-start-of-line' `t'") + (let ((evil-start-of-line t)) + (evil-test-buffer + "[i]nt main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; }" - ("G") - "int main(int argc, char** argv) + ("G") + "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; \[}]" - ("3G") - "int main(int argc, char** argv) + ("3G") + "int main(int argc, char** argv) { [p]rintf(\"Hello world\\n\"); return EXIT_SUCCESS; }" - ("100G") - "int main(int argc, char** argv) + ("100G") + "int main(int argc, char** argv) { printf(\"Hello world\\n\"); return EXIT_SUCCESS; -\[}]")) +\[}]"))) + (ert-info ("With `evil-start-of-line' `nil'") + (evil-test-buffer + "[i]nt main(int argc, char** argv) +{ + printf(\"Hello world\\n\"); + return EXIT_SUCCESS; +}" + ("G") + "int main(int argc, char** argv) +{ + printf(\"Hello world\\n\"); + return EXIT_SUCCESS; +\[}]" + ("3G") + "int main(int argc, char** argv) +{ +[ ] printf(\"Hello world\\n\"); + return EXIT_SUCCESS; +}" + ("100G") + "int main(int argc, char** argv) +{ + printf(\"Hello world\\n\"); + return EXIT_SUCCESS; +\[}]"))) (ert-deftest evil-test-goto-char () "Test `evil-goto-char' motion and ex command." @@ -3252,8 +3392,8 @@ Below some empty line"))) "[W]e only need a short buffer for this test" ("16go") "We only need a [s]hort buffer for this test" - ("go18") - "We only need a sh[o]rt buffer for this test" + ("go") + "[W]e only need a short buffer for this test" (evil-goto-char 24) "We only need a short bu[f]fer for this test")) @@ -6757,7 +6897,7 @@ test hello <a href=\"/deed.zh\">Creative Commons</a> "<;; [T]his buffer is for notes you don't want to save,\n>\ ;; and for Lisp evaluation." ("d") - "[;]; and for Lisp evaluation.")) + ";; [a]nd for Lisp evaluation.")) (ert-deftest evil-test-visual-block () "Test Visual block selection" @@ -7037,13 +7177,14 @@ if no previous selection") "Test if :number moves point to a certain line" :tags '(evil ex) (ert-info ("Move to line") - (evil-test-buffer - :visual line - "1\n 2\n [ ]3\n 4\n 5\n" - (":4" [return]) - "1\n 2\n 3\n [4]\n 5\n" - (":2" [return]) - "1\n [2]\n 3\n 4\n 5\n"))) + (let ((evil-start-of-line t)) + (evil-test-buffer + :visual line + "1\n 2\n [ ]3\n 4\n 5\n" + (":4" [return]) + "1\n 2\n 3\n [4]\n 5\n" + (":2" [return]) + "1\n [2]\n 3\n 4\n 5\n")))) (ert-deftest evil-test-ex-repeat () "Test :@: command." diff --git a/evil-types.el b/evil-types.el index 22d01e8..c23fd59 100644 --- a/evil-types.el +++ b/evil-types.el @@ -342,13 +342,13 @@ If visual state is inactive then those values are nil." :ex-arg t (list (when (evil-ex-p) evil-ex-argument))) -(evil-define-interactive-code "<N>" (prompt) - "Prefix argument, ex-arg or minibuffer input, converted to number" +(evil-define-interactive-code "<N>" () + "Prefix argument or ex-arg, converted to number" (list (cond (current-prefix-arg (prefix-numeric-value current-prefix-arg)) ((and evil-ex-argument (evil-ex-p)) (string-to-number evil-ex-argument)) ((evil-ex-p) nil) - (t (string-to-number (read-string prompt)))))) + (t 1)))) (evil-define-interactive-code "<f>" "Ex file argument." diff --git a/evil-vars.el b/evil-vars.el index c8add73..d516ef1 100644 --- a/evil-vars.el +++ b/evil-vars.el @@ -204,6 +204,13 @@ cursor, or a list of the above." (defvar evil-force-cursor nil "Overwrite the current states default cursor.") +(defcustom evil-start-of-line nil + "Analogue of vim's `startofline'. +If nil, preserve column when making relevant movements of the cursor. +Otherwise, move the cursor to the start of the line." + :type 'boolean + :group 'evil) + (defcustom evil-repeat-move-cursor t "\\<evil-normal-state-map> Whether repeating commands with \\[evil-repeat] may move the cursor. @@ -1440,6 +1447,9 @@ of `evil-inhibit-operator' from one local scope to another.") (defvar evil-operator-range-motion nil "Motion of `evil-operator-range'.") +(defvar evil-operator-start-col nil + "Used to restore column (where possible) after an operator has moved it.") + (defvar evil-restriction-stack nil "List of previous restrictions. Using `evil-with-restriction' stores the previous values of