Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

advise read-key as well as read-key-sequence #865

Merged
merged 2 commits into from
Mar 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion evil-commands.el
Original file line number Diff line number Diff line change
Expand Up @@ -3767,7 +3767,7 @@ resp. after executing the command."
;; tag, which bypasses the source of `this-command-keys', we'd be able
;; to capture the key(s) in the post-command of the operator as usual.
;; Fortunately however, `last-input-event' can see the key (by default, `return')
(unless (append (this-command-keys) nil)
(when (= (length (this-command-keys)) 0)
(evil-repeat-record (vector last-input-event))))
(t (evil-repeat-motion flag))))

Expand Down
65 changes: 31 additions & 34 deletions evil-common.el
Original file line number Diff line number Diff line change
Expand Up @@ -580,13 +580,9 @@ Translates it according to the input method."
(setq char (aref cmd 0)
cmd (key-binding cmd)))
(cond
((eq cmd 'self-insert-command)
char)
(cmd
(setq evil-last-read-digraph-char nil)
(call-interactively cmd))
(t
(user-error "No replacement character typed"))))
((eq cmd 'self-insert-command) char)
(cmd (call-interactively cmd))
(t (user-error "No replacement character typed"))))
(quit
(when (fboundp 'evil-repeat-abort)
(evil-repeat-abort))
Expand All @@ -601,41 +597,42 @@ as a command. Its main use is in the `evil-read-key-map'."
(read-quoted-char))

(defun evil-read-digraph-char-with-overlay (overlay)
"Read two chars, displaying the first in OVERLAY, replacing `?'.
"Read two chars, displaying the first in OVERLAY, replacing \"?\".
Return the digraph from `evil-digraph', else return second char."
(interactive)
(let (char1 char2 string)
(unwind-protect
(progn
(overlay-put overlay 'invisible t)
;; create overlay prompt
(setq string (propertize "?"
'face 'minibuffer-prompt
'cursor 1))
(overlay-put overlay 'after-string string)
(setq char1 (read-key))
(setq string (propertize (string char1)
'face 'minibuffer-prompt
'cursor 1))
(overlay-put overlay 'after-string string)
(setq char2 (read-key)))
(delete-overlay overlay))
(or (evil-digraph (list char1 char2))
;; use the last character if undefined
char2)))
(unwind-protect
(let ((read-key-empty-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map read-key-empty-map)
;; Disable read-key-sequence unbound fallbacks, e.g. downcasing
(define-key map [t] 'dummy)
map))
char1 char2)
;; create overlay prompt
(overlay-put overlay 'invisible t)
(overlay-put overlay 'after-string
#("?" 0 1 (face minibuffer-prompt cursor 1)))
(setq char1 (read-key))
(overlay-put overlay 'after-string
(propertize (char-to-string char1)
'face 'minibuffer-prompt
'cursor 1))
(setq char2 (read-key))

(or (evil-digraph (list char1 char2))
;; use the last character if undefined
char2))
(delete-overlay overlay)))

(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)))))
(char (evil-read-digraph-char-with-overlay overlay)))
(setq evil-last-read-digraph-char char)
char))
(let ((overlay (make-overlay
(point) (min (+ (point) (or hide-chars 1))
(point-max)))))
(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.
Expand Down
78 changes: 35 additions & 43 deletions evil-repeat.el
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@
;; `\[evil-repeat-pop]' (`evil-repeat-pop').
;;
;; Repeat information can be stored in almost arbitrary form. How the
;; repeat information for each single command is recored is determined
;; by the :repeat property of the command. This property has the
;; following interpretation:
;; repeat information for each single command is recorded is
;; determined by the :repeat property of the command. This property
;; has the following interpretation:
;;
;; t record commands by storing the key-sequence that invoked it
;; nil ignore this command completely
Expand All @@ -85,13 +85,13 @@
;; insert state, otherwise it is ignored.
;; abort stop recording of repeat information immediately
;; change record commands by storing buffer changes
;; SYMBOL if SYMBOL is contained as key in `evil-repeat-types'
;; call the corresponding (function-)value, otherwise
;; call the function associated with SYMBOL. In both
;; cases the function should take exactly one argument
;; which is either 'pre or 'post depending on whether
;; the function is called before or after the execution
;; of the command.
;; SYMBOL if SYMBOL is contained as key in `evil-repeat-types' call
;; the corresponding (function-)value, otherwise call the
;; function associated with SYMBOL. In both cases the
;; function should take exactly one argument which is either
;; `pre', `pre-read-key-sequence' or `post' specifying on
;; whether the function is called before or after the
;; execution of the command.
;;
;; Therefore, using a certain SYMBOL one can write specific repeation
;; functions for each command.
Expand All @@ -107,13 +107,6 @@
;; `evil-record-repeat' to append further repeat-information of the
;; form described above to `evil-repeat-info'. See the implementation
;; of `evil-repeat-keystrokes' and `evil-repeat-changes' for examples.
;; Those functions are called in different situations before and after
;; the execution of a command. Each function should take one argument
;; which can be either 'pre, 'post, 'pre-operator or 'post-operator
;; specifying when the repeat function has been called. If the command
;; is a usual command the function is called with 'pre before the
;; command is executed and with 'post after the command has been
;; executed.
;;
;; The repeat information is executed with `evil-execute-repeat-info',
;; which passes key-sequence elements to `execute-kbd-macro' and
Expand All @@ -125,10 +118,10 @@
;; prepending the count as a string to the vector of the remaining
;; key-sequence.

(require 'evil-states)

;;; Code:

(require 'evil-states)

(declare-function evil-visual-state-p "evil-visual")
(declare-function evil-visual-range "evil-visual")
(declare-function evil-visual-char "evil-visual")
Expand Down Expand Up @@ -323,15 +316,13 @@ invoked the current command"

(defun evil-this-command-keys (&optional post-cmd)
"Version of `this-command-keys' with finer control over prefix args."
(let ((arg (if post-cmd current-prefix-arg prefix-arg)))
(vconcat
(when (and (numberp arg)
;; Only add prefix if no repeat info recorded yet
(null evil-repeat-info))
(string-to-vector (number-to-string arg)))
(or (when evil-last-read-digraph-char
(vector evil-last-read-digraph-char))
(this-single-command-keys)))))
(vconcat
(let ((arg (if post-cmd current-prefix-arg prefix-arg)))
(and (numberp arg)
;; Only add prefix if no repeat info recorded yet
(null evil-repeat-info)
(number-to-string arg)))
(this-single-command-keys)))

(defun evil-repeat-keystrokes (flag)
"Repeation recording function for commands that are repeated by keystrokes."
Expand All @@ -341,11 +332,10 @@ invoked the current command"
(evil-repeat-record
`(set evil-this-register ,evil-this-register)))
(setq evil-repeat-keys (evil-this-command-keys)))
((eq flag 'post)
((memq flag '(post pre-read-key-sequence))
(evil-repeat-record (if (zerop (length (evil-this-command-keys t)))
evil-repeat-keys
(evil-this-command-keys t)))
(setq evil-last-read-digraph-char nil)
;; erase commands keys to prevent double recording
(evil-clear-command-keys))))

Expand Down Expand Up @@ -436,14 +426,13 @@ Return a single array."
(cur
(setcdr cur-last (cons rep nil))
(setq cur-last (cdr cur-last)))
(t
(setq cur (cons rep nil))
(setq cur-last cur))))
(t (setq cur (cons rep nil)
cur-last cur))))
(t
(when cur
(setcdr result-last (cons (apply #'vconcat cur) nil))
(setq result-last (cdr result-last))
(setq cur nil))
(setq result-last (cdr result-last)
cur nil))
(setcdr result-last (cons rep nil))
(setq result-last (cdr result-last)))))
(when cur
Expand Down Expand Up @@ -523,8 +512,7 @@ where point should be placed after all changes."
(< (nth 2 rep) ?9))
(setcar (nthcdr 2 rep) (1+ (nth 2 rep))))
(apply (car rep) (cdr rep)))
(t
(error "Unexpected repeat-info: %S" rep))))))
(t (error "Unexpected repeat-info: %S" rep))))))

;; TODO: currently we prepend the replacing count before the
;; key-sequence that calls the command. Can we use direct
Expand Down Expand Up @@ -553,8 +541,7 @@ and only if COUNT is non-nil."
(setq done t)))
(evil-execute-repeat-info repeat-info)))
;; repeat with original count
(t
(evil-execute-repeat-info repeat-info)))))
(t (evil-execute-repeat-info repeat-info)))))

;; Keep the compiler happy - this is a buffer local var
(defvar evil--execute-normal-return-state)
Expand Down Expand Up @@ -636,13 +623,18 @@ If COUNT is negative, this is a more recent kill."
(not evil-repeat-move-cursor)))
(evil-repeat-pop (- count) save-point))

(defadvice read-key-sequence (before evil activate)
"Record `this-command-keys' before it is reset."
(defun evil--read-key-sequence-advice ()
"Record `this-command-keys' before it is overwritten."
(when (and (evil-repeat-recording-p)
evil-recording-current-command)
(let ((repeat-type (evil-repeat-type this-command t)))
(if (functionp repeat-type)
(funcall repeat-type 'post)))))
(when (functionp repeat-type)
(funcall repeat-type 'pre-read-key-sequence)))))

(defadvice read-key-sequence (before evil activate)
(evil--read-key-sequence-advice))
(defadvice read-key-sequence-vector (before evil activate)
(evil--read-key-sequence-advice))

(provide 'evil-repeat)

Expand Down
3 changes: 0 additions & 3 deletions evil-vars.el
Original file line number Diff line number Diff line change
Expand Up @@ -1559,9 +1559,6 @@ This keymap can be used to bind some commands during the
execution of `evil-read-key' which is usually used to read a
character argument for some commands, e.g. `evil-replace'.")

(defvar evil-last-read-digraph-char nil
"The last digraph character read. Used for repeats.")

;; TODO: customize size of ring
(defvar evil-repeat-ring (make-ring 10)
"A ring of repeat-informations to repeat the last command.")
Expand Down