diff options
Diffstat (limited to 'evil-core.el')
| -rw-r--r-- | evil-core.el | 85 |
1 files changed, 54 insertions, 31 deletions
diff --git a/evil-core.el b/evil-core.el index 506b422..0419212 100644 --- a/evil-core.el +++ b/evil-core.el @@ -105,6 +105,8 @@ ;;; Code: +(declare-function evil-emacs-state-p "evil-states") + (define-minor-mode evil-local-mode "Minor mode for setting up Evil in a single buffer." :init-value nil @@ -180,10 +182,12 @@ To enable Evil globally, do (evil-mode 1)." ;; changed back by `evil-local-mode' (setq-default major-mode 'turn-on-evil-mode) (ad-enable-regexp "^evil") - (ad-activate-regexp "^evil")) + (ad-activate-regexp "^evil") + (with-no-warnings (evil-esc-mode 1))) (setq-default major-mode 'fundamental-mode) (ad-disable-regexp "^evil") - (ad-update-regexp "^evil"))) + (ad-update-regexp "^evil") + (with-no-warnings (evil-esc-mode -1)))) (put 'evil-mode 'function-documentation "Toggle Evil in all buffers. @@ -531,27 +535,54 @@ may be specified before the body code: ,@body)) ',keymap))) -;; Intercept the ESC event when running in the terminal. This allows -;; keys that use "ESC" as a prefix key, such as "M-x". If "ESC" is -;; immediately followed by another key, or another key is pressed -;; within `evil-esc-delay', the prefixed key sequence is sent. -;; Otherwise only [escape] is sent. -(evil-define-keymap evil-esc-map - "Keymap for intercepting ESC." - :intercept t) - -(defun evil-turn-on-esc-mode () - "Enable interception of ESC." - (unless (eq this-command #'evil-esc) - (evil-esc-mode 1) - (remove-hook 'pre-command-hook #'evil-turn-on-esc-mode t))) -(put 'evil-turn-on-esc-mode 'permanent-local-hook t) - -;; `evil-esc' is bound to (kbd "ESC"), while other commands -;; are bound to [escape]. That way `evil-esc' is used only when -;; (kbd "ESC") and [escape] are the same event -- i.e., when -;; running Emacs in the terminal. -(define-key evil-esc-map (kbd "ESC") 'evil-esc) +;; The ESC -> escape translation code has been provided by Stefan +;; Monnier in the discussion of GNU Emacs bug #13793. +(defun evil-esc-mode (&optional arg) + "Toggle interception of \\e (escape). +Enable with positive ARG and disable with negative ARG. + +When enabled, `evil-esc-mode' modifies the entry of \\e in +`input-decode-map'. If such an event arrives, it is translated to +a plain 'escape event if no further event occurs within +`evil-esc-delay' seconds. Otherwise no translation happens and +the ESC prefix map (i.e. the map originally bound to \\e in +`input-decode-map`) is returned." + (cond + ((or (null arg) (eq arg 0)) + (evil-esc-mode (if evil-esc-mode -1 +1))) + + ((> arg 0) + (unless evil-esc-mode + (setq evil-esc-map (lookup-key input-decode-map [?\e])) + (define-key input-decode-map [?\e] + `(menu-item "" ,evil-esc-map :filter ,#'evil-esc)) + (setq evil-esc-mode t))) + ((< arg 0) + (when evil-esc-mode + (define-key input-decode-map [?\e] evil-esc-map))))) + +(defun evil-esc (map) + "Translate \\e to 'escape if no further event arrives. +This function is used to translate a \\e event either to 'escape +or to the standard ESC prefix translation map. If \\e arrives, +this function waits for `evil-esc-delay' seconds for another +event. If no other event arrives, the event is translated to +'escape, otherwise it is translated to the standard ESC prefix +map stored in `input-decode-map'. If `evil-inhibit-esc' is +non-nil or if evil is in emacs state, the event is always +translated to the ESC prefix. + +The translation to 'escape happens only if the current command +has indeed been triggered by \\e. In other words, this will only +happen when the keymap is accessed from `read-key-sequence'. In +particular, if it is access from `define-key' the returned +mapping will always be the ESC prefix map." + (if (and (not evil-inhibit-esc) + evil-local-mode + (not (evil-emacs-state-p)) + (equal (this-single-command-keys) [?\e]) + (sit-for evil-esc-delay)) + [escape] map)) (defun evil-state-p (sym) "Whether SYM is the name of a state." @@ -713,7 +744,6 @@ See also `evil-mode-for-keymap'." (when (setq map (evil-intercept-keymap-p map state)) (push (cons (evil-mode-for-keymap map t) map) result))) (setq result (nreverse result)) - (add-to-list 'result `(evil-esc-mode . ,evil-esc-map)) result)) (defun evil-set-auxiliary-keymap (map state &optional aux) @@ -928,7 +958,6 @@ the local keymap will be `evil-test-state-local-map', and so on. (exit-hook (intern (format "%s-exit-hook" toggle))) (modes (intern (format "%s-modes" toggle))) (predicate (intern (format "%s-p" toggle))) - (intercept-esc t) arg cursor-value enable entry-hook-value exit-hook-value input-method key message-value suppress-keymap tag-value) ;; collect keywords @@ -954,8 +983,6 @@ the local keymap will be `evil-test-state-local-map', and so on. (setq enable arg)) ((eq key :input-method) (setq input-method arg)) - ((eq key :intercept-esc) - (setq intercept-esc arg)) ((eq key :suppress-keymap) (setq suppress-keymap arg)))) @@ -1029,7 +1056,6 @@ If ARG is nil, don't display a message in the echo area.%s" name doc) (let ((evil-state ',state)) (run-hooks ',exit-hook) (setq evil-state nil) - (evil-esc-mode -1) (evil-normalize-keymaps) ,@body)) (t @@ -1044,9 +1070,6 @@ If ARG is nil, don't display a message in the echo area.%s" name doc) ',state evil-previous-state) (let ((evil-state ',state)) (evil-normalize-keymaps) - (if ,intercept-esc - (evil-esc-mode 1) - (evil-esc-mode -1)) (if ',input-method (activate-input-method evil-input-method) (deactivate-input-method)) |
