branch: elpa/evil commit a1f623c3eb12ecf42ad4b1665a7fde7e30451320 Author: Tom Dalziel <tom...@hotmail.com> Commit: Tom Dalziel <33435574+tomd...@users.noreply.github.com>
Replace state evil digraphs --- evil-commands.el | 44 +++++++++++++++++++++++++------------------- evil-common.el | 37 +++++++++++++++++++++---------------- evil-states.el | 10 ++++++++++ evil-tests.el | 21 ++++++++++++++++++++- 4 files changed, 76 insertions(+), 36 deletions(-) diff --git a/evil-commands.el b/evil-commands.el index 79f23da..8306854 100644 --- a/evil-commands.el +++ b/evil-commands.el @@ -27,6 +27,7 @@ (require 'evil-common) (require 'evil-digraphs) (require 'evil-search) +(require 'evil-states) (require 'evil-ex) (require 'evil-types) (require 'evil-command-window) @@ -2577,27 +2578,24 @@ switch to insert state." "Like `quoted-insert' but delete COUNT chars forward in replace state. Adds a `^' overlay as an input prompt." (interactive "p") - (let* ((cnt (or count 1)) - (pnt (point)) - (chars-to-delete (min (- (point-at-eol) pnt) cnt)) - (insert-prompt (make-overlay pnt (+ chars-to-delete pnt)))) + (let* ((opoint (point)) + chars-to-delete insert-prompt) (unwind-protect (progn - (when (evil-replace-state-p) - (dotimes (c cnt) - (let ((pos (+ c pnt))) - (add-to-list 'evil-replace-alist - (cons pos (when (< c chars-to-delete) - (char-after pos)))))) - (overlay-put insert-prompt 'invisible t)) - ;; The nature of the insert cursor means it has to be after - ;; the prompt rather than before (unlike vim). - (overlay-put insert-prompt - 'before-string (propertize "^" 'face 'escape-glyph)) + (if (evil-replace-state-p) + (progn + (setq chars-to-delete (min (- (point-at-eol) opoint) count) + insert-prompt (make-overlay opoint (+ chars-to-delete opoint))) + (evil-update-replace-alist opoint count chars-to-delete)) + (setq insert-prompt (make-overlay opoint opoint))) + (overlay-put insert-prompt 'invisible t) + (overlay-put insert-prompt 'after-string (propertize "^" + 'face 'escape-glyph + 'cursor 1)) (let (overwrite-mode) ;; Force `read-quoted-char' - (quoted-insert cnt)) + (quoted-insert count)) (when (evil-replace-state-p) (delete-char chars-to-delete))) - (delete-overlay insert-prompt)))) + (when insert-prompt (delete-overlay insert-prompt))))) (defun evil-open-above (count) "Insert a new line above point and switch to Insert state. @@ -2699,8 +2697,16 @@ next VCOUNT - 1 lines below the current one." "Insert COUNT digraphs." :repeat change (interactive "p") - (let ((digraph (evil-read-digraph-char 0))) - (insert-char digraph count))) + (let ((opoint (point)) + chars-to-delete insert-prompt) + (if (evil-replace-state-p) + (progn + (setq chars-to-delete (min (- (point-at-eol) opoint) count) + insert-prompt (make-overlay opoint (+ chars-to-delete opoint))) + (evil-update-replace-alist opoint count chars-to-delete)) + (setq insert-prompt (make-overlay opoint opoint))) + (insert-char (evil-read-digraph-char-with-overlay insert-prompt) count) + (when chars-to-delete (delete-char chars-to-delete)))) (evil-define-command evil-ex-show-digraphs () "Shows a list of all available digraphs." diff --git a/evil-common.el b/evil-common.el index ddb26e1..8c5b822 100644 --- a/evil-common.el +++ b/evil-common.el @@ -620,29 +620,23 @@ as a command. Its main use is in the `evil-read-key-map'." (interactive) (read-quoted-char)) -(defun evil-read-digraph-char (&optional hide-chars) - "Read two keys from keyboard forming a digraph. -This function creates an overlay at (point), hiding the next -HIDE-CHARS characters. HIDE-CHARS defaults to 1." +(defun evil-read-digraph-char-with-overlay (overlay) + "Read two chars, displaying the first in OVERLAY, replacing `?'. +Return the digraph from `evil-digraph', else return second char." (interactive) - (let (char1 char2 string overlay) + (let (char1 char2 string) (unwind-protect (progn - (setq overlay (make-overlay (point) - (min (point-max) - (+ (or hide-chars 1) - (point))))) (overlay-put overlay 'invisible t) ;; create overlay prompt - (setq string "?") - (put-text-property 0 1 'face 'minibuffer-prompt string) - ;; put cursor at (i.e., right before) the prompt - (put-text-property 0 1 'cursor t string) + (setq string (propertize "?" + 'face 'minibuffer-prompt + 'cursor 1)) (overlay-put overlay 'after-string string) (setq char1 (read-key)) - (setq string (string char1)) - (put-text-property 0 1 'face 'minibuffer-prompt string) - (put-text-property 0 1 'cursor t string) + (setq string (propertize (string char1) + 'face 'minibuffer-prompt + 'cursor 1)) (overlay-put overlay 'after-string string) (setq char2 (read-key))) (delete-overlay overlay)) @@ -650,6 +644,17 @@ HIDE-CHARS characters. HIDE-CHARS defaults to 1." ;; use the last character if undefined char2))) +(defun evil-read-digraph-char (&optional hide-chars) + "Read two keys from keyboard forming a digraph. +This function creates an overlay at (point), hiding the next +HIDE-CHARS characters. HIDE-CHARS defaults to 1." + (interactive) + (let ((overlay (make-overlay (point) + (min (point-max) + (+ (or hide-chars 1) + (point)))))) + (evil-read-digraph-char-with-overlay overlay))) + (defun evil-read-motion (&optional motion count type modifier) "Read a MOTION, motion COUNT and motion TYPE from the keyboard. The type may be overridden with MODIFIER, which may be a type diff --git a/evil-states.el b/evil-states.el index fcec2e3..d9784b5 100644 --- a/evil-states.el +++ b/evil-states.el @@ -905,6 +905,16 @@ CORNER defaults to `upper-left'." (when char (insert char)))))) +(defun evil-update-replace-alist (opoint count chars-to-delete) + "Add CHARS-TO-DELETE chars to evil-replace-alist, starting at OPOINT. +If COUNT is greater than CHARS-TO-DELETE, pad the alist with nils." + (when (evil-replace-state-p) + (dotimes (c count) + (let ((pos (+ c opoint))) + (add-to-list 'evil-replace-alist + (cons pos (when (< c chars-to-delete) + (char-after pos)))))))) + ;;; Motion state (evil-define-state motion diff --git a/evil-tests.el b/evil-tests.el index 03c20c4..a0928ce 100644 --- a/evil-tests.el +++ b/evil-tests.el @@ -765,7 +765,17 @@ de[f] (let ((evil-digraphs-table-user '(((?a ?o) . ?å)))) (evil-test-buffer ("i\C-kao") - "å[]")))) + "å[]"))) + (ert-info ("Digraph in replace state") + (evil-test-buffer + "ab[c]defgh" + ("R\C-kc,") + "abç[d]efgh") + (ert-info ("with count") + (evil-test-buffer + "abc[d]efgh" + ("R\C-u3\C-kd*") + "abcδδδ[g]h")))) ;;; Repeat system @@ -5439,6 +5449,15 @@ This buffer is for notes." ";; [T]his buffer is for notes, ;; and for Lisp evaluation.")))) +(ert-deftest evil-test-find-digraph-char () + "Test evil-read-digraph-char while finding char." + :tags '(evil motion) + (ert-info ("Find digraph char") + (evil-test-buffer + "a[b]cde∀g" + ("f\C-kFA") + "abcde[∀]g"))) + (ert-deftest evil-test-find-char-to () "Test `evil-find-char-to'" :tags '(evil motion)