emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/evil 45a10ff113: Fix CTRL-O at BOL


From: ELPA Syncer
Subject: [nongnu] elpa/evil 45a10ff113: Fix CTRL-O at BOL
Date: Thu, 22 Jun 2023 04:00:27 -0400 (EDT)

branch: elpa/evil
commit 45a10ff11317327d7a3fca56bf05c0bc36291aa8
Author: Axel Forsman <axelsfor@gmail.com>
Commit: Tom Dalziel <33435574+tomdl89@users.noreply.github.com>

    Fix CTRL-O at BOL
    
    The cursor should not be put after EOL if it has moved to a different line.
    
    This commit also changes evil--execute-normal-eol-pos to be a marker,
    since the Normal state command may insert/remove text.
    
    Closes #1804
---
 evil-commands.el |  52 +++++++++++-----------
 evil-tests.el    | 129 ++++++++++++++++++++++++++++---------------------------
 2 files changed, 92 insertions(+), 89 deletions(-)

diff --git a/evil-commands.el b/evil-commands.el
index a132e78ca5..24fcd3390d 100644
--- a/evil-commands.el
+++ b/evil-commands.el
@@ -5180,10 +5180,6 @@ if the previous state was Emacs state."
       (when (evil-emacs-state-p)
         (evil-normal-state (and message 1))))))
 
-(evil-define-local-var evil--execute-normal-eol-pos nil
-  "Vim has special behaviour for executing in normal state at eol.
-This var stores the eol position, so it can be restored when necessary.")
-
 (defun evil--restore-repeat-hooks ()
   "No insert-state repeat info is recorded after executing in normal state.
 Restore the disabled repeat hooks on insert-state exit."
@@ -5195,6 +5191,9 @@ Restore the disabled repeat hooks on insert-state exit."
 (defvar evil--execute-normal-return-state nil
   "The state to return to after executing in normal state.")
 
+(evil-define-local-var evil--execute-normal-eol-pos nil
+  "Point position if it was at EOL before `evil-execute-in-normal-state'.")
+
 (defun evil-execute-in-normal-state ()
   "Execute the next command in Normal state."
   (interactive)
@@ -5209,31 +5208,34 @@ Restore the disabled repeat hooks on insert-state exit."
                             universal-argument-minus
                             universal-argument-more
                             universal-argument-other-key)))
-      `(progn
-         (with-current-buffer ,(current-buffer)
-           (when (and evil--execute-normal-eol-pos
-                      (= (point) (1- evil--execute-normal-eol-pos))
-                      (not (memq this-command '(evil-insert
-                                                evil-goto-mark))))
-             (forward-char))
-           (unless (memq evil-state '(replace insert))
-             (evil-change-state ',evil-state))
-           (when (eq 'insert evil-state)
-             (remove-hook 'pre-command-hook 'evil-repeat-pre-hook)
-             (remove-hook 'post-command-hook 'evil-repeat-post-hook)
-             (add-hook 'evil-insert-state-exit-hook 
'evil--restore-repeat-hooks))
-           (setq evil-move-cursor-back ',evil-move-cursor-back
-                 evil-move-beyond-eol ',evil-move-beyond-eol
-                 evil-execute-normal-keys nil)))
+      `(with-current-buffer ,(current-buffer)
+         ;; If cursor was after EOL before CTRL-O and is now at EOL,
+         ;; put it after EOL.
+         (and (or (when evil--execute-normal-eol-pos
+                    (= (1+ (point)) (save-excursion
+                                      (goto-char evil--execute-normal-eol-pos)
+                                      (set-marker evil--execute-normal-eol-pos 
nil)
+                                      (line-end-position))))
+                  (and (eq (or goal-column temporary-goal-column) 
most-positive-fixnum)
+                       (memq this-command '(next-line previous-line))))
+              (not (eolp))
+              (not (memq this-command
+                         '(evil-insert evil-beginning-of-line 
evil-first-non-blank)))
+              (forward-char))
+         (unless (memq evil-state '(replace insert))
+           (evil-change-state ',evil-state))
+         (when (eq 'insert evil-state)
+           (remove-hook 'pre-command-hook 'evil-repeat-pre-hook)
+           (remove-hook 'post-command-hook 'evil-repeat-post-hook)
+           (add-hook 'evil-insert-state-exit-hook 'evil--restore-repeat-hooks))
+         (setq evil-execute-normal-keys nil))
     'post-command-hook)
   (setq evil-insert-count nil
         evil--execute-normal-return-state evil-state
-        evil--execute-normal-eol-pos (when (eolp) (point))
-        evil-move-cursor-back nil
+        evil--execute-normal-eol-pos (when (eolp) (point-marker))
         evil-execute-normal-keys (this-command-keys))
-  (evil-normal-state)
-  (setq evil-move-beyond-eol t)
-  (evil-echo "Switched to Normal state for the next command ..."))
+  (let (evil-move-cursor-back) (evil-normal-state))
+  (evil-echo "Switched to Normal state for the next command..."))
 
 (defun evil-stop-execute-in-emacs-state ()
   (when (and (not (eq this-command #'evil-execute-in-emacs-state))
diff --git a/evil-tests.el b/evil-tests.el
index f3e928f541..9e8f8589ec 100644
--- a/evil-tests.el
+++ b/evil-tests.el
@@ -295,71 +295,72 @@ with `M-x evil-tests-run'"))
     (evil-test-change-state 'normal)))
 
 (ert-deftest evil-test-execute-in-normal-state ()
-  "Test `evil-execute-in-normal-state'."
+  "Execute Normal state command in Insert state 
(`evil-execute-in-normal-state')."
   :tags '(evil)
-  (ert-info ("Execute normal state command in insert state")
-    (evil-test-buffer
-      "[a]bcdef\n"
-      ("I")
-      (should (evil-insert-state-p))
-      ("\C-ox")
-      (ert-info ("Should return to insert state")
-        (should (evil-insert-state-p)))
-      "[b]cdef\n"
-      ("\C-oA")
-      (ert-info ("Should return to insert state after insert state command")
-        (should (evil-insert-state-p)))
-      ("bcdef[]\n"))
-    (ert-info ("Cursor is placed correctly afterwards")
-      (evil-test-buffer
-        :state insert
-        "abcdefg[]"
-        ("\C-o~")
-        "abcdefG[]")
-      (evil-test-buffer
-        :state insert
-        "abcdefg[]"
-        ("\C-ozz")
-        "abcdefg[]")
-      (evil-test-buffer
-        :state insert
-        "abc[]defg"
-        ("\C-o$")
-        "abcdefg[]")
-      (evil-test-buffer
-        :state insert
-        "abcdefg[]"
-        ("\C-o^")
-        "[]abcdefg")
-      (evil-test-buffer
-        :state insert
-        "abcdefg[]"
-        ("\C-oi")
-        "abcdef[]g")
-      (evil-test-buffer
-        "line1\nli[n]e2"
-        ("ma" "kA" "\C-o`a")
-        "line1\nli[]ne2"))
-    (ert-info ("Can enter replace state and stay in it")
-      (evil-test-buffer
-        :state insert
-        "abc[]defg"
-        ("\C-oRfoo")
-        "abcfoog"))
-    (ert-info ("Insert count is ignored")
-      (evil-test-buffer
-        "[]"
-        ("2i" "abcdef" "\C-o~" "g" [escape])
-        "abcdeF[g]"))
-    (ert-info ("Can execute evil-repeat in normal state")
-      (evil-test-buffer
-        ;; Although this is the same in vim, text inserted after the temporary
-        ;; normal command is not recorded for repetition, which is a subtle
-        ;; (but arguably more useful) difference
-        :state insert
-        "ab[]cfg"
-        ("\C-o~de\C-o.")
-        "abCdeF[]g"))))
+  (evil-test-buffer "[a]bcdef\n"
+    ("I")
+    (should (evil-insert-state-p))
+    ("\C-ox")
+    (ert-info ("Should return to Insert state") (should (evil-insert-state-p)))
+    "[b]cdef\n"
+    ("\C-oA")
+    (ert-info ("Should return to Insert state after Insert state command")
+      (should (evil-insert-state-p)))
+    ("bcdef[]\n"))
+  (ert-info ("Cursor is placed correctly afterwards")
+    (evil-test-buffer
+      :state insert
+      "abcdefg[]"
+      ("\C-o~")
+      "abcdefG[]")
+    (evil-test-buffer
+      :state insert
+      "abcdefg[]"
+      ("\C-ozz")
+      "abcdefg[]")
+    (evil-test-buffer
+      :state insert
+      "abc[]defg"
+      ("\C-o$")
+      "abcdefg[]")
+    (evil-test-buffer
+      :state insert
+      "abcdefg[]"
+      ("\C-o^")
+      "[]abcdefg")
+    (evil-test-buffer
+      :state insert
+      "abcdefg[]"
+      ("\C-oi")
+      "abcdef[]g")
+    (evil-test-buffer
+      :state insert
+      "\n[]"
+      ("\C-ok")
+      "[]\n")
+    (evil-test-buffer
+      "line1\nli[n]e2"
+      ("ma" "kA" "\C-o`a")
+      "line1\nli[]ne2"))
+  (ert-info ("Can enter replace state and stay in it")
+    (evil-test-buffer
+      :state insert
+      "abc[]defg"
+      ("\C-oRfoo")
+      "abcfoog"))
+  (ert-info ("Insert count is ignored")
+    (evil-test-buffer "[]"
+      ("2i" "abcdef" "\C-o~" "g" [escape])
+      "abcdeF[g]"))
+  (ert-info ("Can execute evil-repeat in normal state")
+    (evil-test-buffer
+      ;; Although this is the same in Vim, text inserted after the temporary
+      ;; normal command is not recorded for repetition, which is a subtle
+      ;; (but arguably more useful) difference.
+      :state insert
+      "ab[]cfg"
+      ("\C-o~de\C-o.")
+      "abCdeF[]g")))
 
 (defun evil-test-suppress-keymap (state)
   "Verify that `self-insert-command' is suppressed in STATE"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]