diff --git a/evil-common.el b/evil-common.el
index bc76653d..b991b869 100644
--- a/evil-common.el
+++ b/evil-common.el
@@ -714,12 +714,12 @@ recursively."
(beg 0)
(end 1)
(found-prefix nil))
- (while (and (<= end len))
+ (while (<= end len)
(let* ((seq (substring keys beg end))
(cmd (key-binding seq)))
(cond
((memq cmd '(undefined nil))
- (user-error "No command bound to %s" seq))
+ (user-error "No command bound to `%s'" seq))
((arrayp cmd) ; keyboard macro, replace command with macro
(setq keys (vconcat (substring keys 0 beg)
cmd
diff --git a/evil-macros.el b/evil-macros.el
index f70a4148..5e57f617 100644
--- a/evil-macros.el
+++ b/evil-macros.el
@@ -25,13 +25,14 @@
;; You should have received a copy of the GNU General Public License
;; along with Evil. If not, see .
+;;; Code:
+
(require 'evil-common)
(require 'evil-states)
(require 'evil-repeat)
-;;; Code:
-
(declare-function evil-ex-p "evil-ex")
+(declare-function evil-line-or-visual-line "evil-commands")
;; set some error codes
(put 'beginning-of-line 'error-conditions '(beginning-of-line error))
@@ -562,16 +563,13 @@ Optional keyword arguments are:
(setq evil-inhibit-operator-value nil)))))
;; this is used in the `interactive' specification of an operator command
-(defun evil-operator-range (&optional return-type)
- "Read a motion from the keyboard and return its buffer positions.
-The return value is a list (BEG END), or (BEG END TYPE) if
-RETURN-TYPE is non-nil."
+(defun evil-operator-range ()
+ "Read a motion from the keyboard and return its buffer positions."
(let* ((evil-ex-p (and (not (minibufferp)) (evil-ex-p)))
(motion (or evil-operator-range-motion
(when evil-ex-p 'evil-line)))
(type evil-operator-range-type)
- (range (evil-range (point) (point)))
- command count)
+ range count)
(setq evil-this-type-modified nil)
(evil-save-echo-area
(cond
@@ -586,67 +584,59 @@ RETURN-TYPE is non-nil."
(setq range (evil-range (region-beginning)
(region-end)
(or evil-this-type 'exclusive))))
+ ;; motion
(t
- ;; motion
- (evil-save-state
- (unless motion
- (evil-change-state 'operator)
+ (unless motion
+ (evil-save-state
;; Make linewise operator shortcuts. E.g., "d" yields the
;; shortcut "dd", and "g?" yields shortcuts "g??" and "g?g?".
(let ((keys (nth 2 (evil-extract-count (this-command-keys)))))
- (setq keys (listify-key-sequence keys))
- (dotimes (var (length keys))
- (define-key evil-operator-shortcut-map
- (vconcat (nthcdr var keys)) 'evil-line-or-visual-line)))
+ (evil-change-state 'operator)
+ (cl-loop for keys on (listify-key-sequence keys) do
+ (define-key evil-operator-shortcut-map
+ (vconcat keys) #'evil-line-or-visual-line)))
;; read motion from keyboard
- (setq command (evil-read-motion motion)
- motion (nth 0 command)
- count (nth 1 command)
- type (or type (nth 2 command))))
- (cond
- ((eq motion #'undefined)
- (setq range (if return-type '(nil nil nil) '(nil nil))
- motion nil))
- ((or (null motion) ; keyboard-quit
- (evil-get-command-property motion :suppress-operator))
- (when (fboundp 'evil-repeat-abort)
- (evil-repeat-abort))
- (setq quit-flag t
- motion nil))
- (evil-repeat-count
- (setq count evil-repeat-count
- ;; only the first operator's count is overwritten
- evil-repeat-count nil))
- ((or count current-prefix-arg)
- ;; multiply operator count and motion count together
- (setq count
- (* (prefix-numeric-value count)
- (prefix-numeric-value current-prefix-arg)))))
- (when motion
- (let ((evil-state 'operator)
- mark-active)
- ;; calculate motion range
- (setq range (evil-motion-range
- motion
- count
- type))))
- ;; update global variables
- (setq evil-this-motion motion
- evil-this-motion-count count
- type (evil-type range type)
- evil-this-type type))))
- (when (evil-range-p range)
- (unless (or (null type) (eq (evil-type range) type))
- (evil-contract-range range)
- (evil-set-type range type)
- (evil-expand-range range))
- (evil-set-range-properties range nil)
- (unless return-type
- (evil-set-type range nil))
- (setq evil-operator-range-beginning (evil-range-beginning range)
- evil-operator-range-end (evil-range-end range)
- evil-operator-range-type (evil-type range)))
- range)))
+ (let ((command (evil-read-motion motion)))
+ (setq motion (car command)
+ count (cadr command)
+ type (or type (nth 2 command))))))
+ (cond
+ ((eq motion #'undefined)
+ (setq range (list nil nil)
+ motion nil))
+ ((or (null motion) ; keyboard-quit
+ (evil-get-command-property motion :suppress-operator))
+ (evil-repeat-abort)
+ (setq quit-flag t
+ range (evil-range (point) (point)) ; zero-len range
+ motion nil))
+ (evil-repeat-count
+ (setq count evil-repeat-count
+ ;; only the first operator's count is overwritten
+ evil-repeat-count nil))
+ ((or count current-prefix-arg)
+ ;; multiply operator count and motion count together
+ (setq count
+ (* (prefix-numeric-value count)
+ (prefix-numeric-value current-prefix-arg)))))
+ (when motion
+ (let ((evil-state 'operator)
+ mark-active)
+ ;; calculate motion range
+ (setq range (evil-motion-range motion count type))))
+ ;; update global variables
+ (setq evil-this-motion motion
+ evil-this-motion-count count
+ type (evil-type range type)
+ evil-this-type type))))
+ (unless (or (null type) (eq (evil-type range) type))
+ (evil-contract-range range)
+ (evil-set-range-type range type)
+ (evil-expand-range range))
+ (setq evil-operator-range-beginning (evil-range-beginning range)
+ evil-operator-range-end (evil-range-end range)
+ evil-operator-range-type (evil-type range))
+ range))
(defmacro evil-define-type (type doc &rest body)
"Define type TYPE.
diff --git a/evil-tests.el b/evil-tests.el
index 4e8aaf4d..edf728d1 100644
--- a/evil-tests.el
+++ b/evil-tests.el
@@ -429,7 +429,14 @@ when exiting Operator-Pending state")
'bar))
(evil-test-change-state 'emacs)
(should-not (eq (lookup-key evil-operator-shortcut-map "b")
- 'bar)))))
+ 'bar))))
+ (ert-info ("Compute shortcuts with original keymaps")
+ (evil-test-buffer "foo"
+ (define-key evil-normal-state-local-map (kbd "SPC x") #'evil-delete)
+ ;; evil-forward-char in motion map should not shadow the executed
+ ;; evil-delete binding above when populating shortcut map.
+ ((kbd "SPC x x"))
+ "")))
(ert-deftest evil-test-auxiliary-maps ()
"Test auxiliary keymaps"
diff --git a/evil-types.el b/evil-types.el
index 276cdbbf..47b064e3 100644
--- a/evil-types.el
+++ b/evil-types.el
@@ -305,11 +305,14 @@ directly."
(evil-define-interactive-code ""
"Untyped motion range (BEG END)."
- (evil-operator-range))
+ (let ((range (evil-operator-range)))
+ (setcdr (cdr range) nil)
+ range))
(evil-define-interactive-code ""
"Typed motion range (BEG END TYPE)."
- (evil-operator-range t))
+ (let ((range (evil-operator-range)))
+ (list (car range) (cadr range) (evil-type range))))
(evil-define-interactive-code ""
"Typed motion range of visual range(BEG END TYPE).