summaryrefslogtreecommitdiff
path: root/elpa/evil-20220510.2302/evil-core.el
diff options
context:
space:
mode:
authormattkae <mattkae@protonmail.com>2022-06-07 08:23:47 -0400
committermattkae <mattkae@protonmail.com>2022-06-07 08:23:47 -0400
commitbd18a38c2898548a3664a9ddab9f79c84f2caf4a (patch)
tree95b9933376770381bd8859782ae763be81c2d72b /elpa/evil-20220510.2302/evil-core.el
parentb07628dddf418d4f47b858e6c35fd3520fbaeed2 (diff)
parentef160dea332af4b4fe5e2717b962936c67e5fe9e (diff)
Merge conflict
Diffstat (limited to 'elpa/evil-20220510.2302/evil-core.el')
-rw-r--r--elpa/evil-20220510.2302/evil-core.el1392
1 files changed, 0 insertions, 1392 deletions
diff --git a/elpa/evil-20220510.2302/evil-core.el b/elpa/evil-20220510.2302/evil-core.el
deleted file mode 100644
index cf75497..0000000
--- a/elpa/evil-20220510.2302/evil-core.el
+++ /dev/null
@@ -1,1392 +0,0 @@
-;;; evil-core.el --- Core functionality -*- lexical-binding: t -*-
-;; Author: Vegard Øye <vegard_oye at hotmail.com>
-;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
-
-;; Version: 1.15.0
-
-;;
-;; This file is NOT part of GNU Emacs.
-
-;;; License:
-
-;; This file is part of Evil.
-;;
-;; Evil is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-;;
-;; Evil is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with Evil. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Evil is defined as a globalized minor mode, enabled with the toggle
-;; function `evil-mode'. This in turn enables `evil-local-mode' in
-;; every buffer, which sets up the buffer's state.
-;;
-;; Each state has its own keymaps, and these keymaps have status as
-;; "emulation keymaps" with priority over regular keymaps. Emacs
-;; maintains the following keymap hierarchy (highest priority first):
-;;
-;; * Overriding keymaps/overlay keymaps...
-;; * Emulation mode keymaps...
-;; - Evil keymaps...
-;; * Minor mode keymaps...
-;; * Local keymap (`local-set-key')
-;; * Global keymap (`global-set-key')
-;;
-;; Within this hierarchy, Evil arranges the keymaps for the current
-;; state as shown below:
-;;
-;; * Intercept keymaps...
-;; * Local state keymap
-;; * Minor-mode keymaps...
-;; * Auxiliary keymaps...
-;; * Overriding keymaps...
-;; * Global state keymap
-;; * Keymaps for other states...
-;;
-;; These keymaps are listed in `evil-mode-map-alist', which is listed
-;; in `emulation-mode-map-alist'.
-;;
-;; Most of the key bindings for a state are stored in its global
-;; keymap, which has a name such as `evil-normal-state-map'. (See the
-;; file evil-maps.el, which contains all the default key bindings.) A
-;; state also has a local keymap (`evil-normal-state-local-map'),
-;; which may contain user customizations for the current buffer.
-;; Furthermore, any Emacs mode may be assigned state bindings of its
-;; own by passing the mode's keymap to the function `evil-define-key'
-;; or `evil-define-minor-mode-key'. The former uses a specific map to
-;; define the key in while the latter associates the key with a
-;; particular mode. These mode-specific bindings are ultimately stored
-;; in so-called auxiliary and minor-mode keymaps respectively, which
-;; are sandwiched between the local keymap and the global keymap.
-;; Finally, the state may also activate the keymaps of other states
-;; (e.g., Normal state inherits bindings from Motion state).
-;;
-;; For integration purposes, a regular Emacs keymap may be "elevated"
-;; to emulation status by passing it to `evil-make-intercept-map' or
-;; `evil-make-overriding-map'. An "intercept" keymap has priority over
-;; all other Evil keymaps. (Evil uses this facility when debugging and
-;; for handling the "ESC" key in the terminal.) More common is the
-;; "overriding" keymap, which only has priority over the global state
-;; keymap. (This is useful for adapting key-heavy modes such as Dired,
-;; where all but a few keys should be left as-is and should not be
-;; shadowed by Evil's default bindings.)
-;;
-;; States are defined with the macro `evil-define-state', which
-;; creates a command for switching to the state. This command,
-;; for example `evil-normal-state' for Normal state, performs
-;; the following tasks:
-;;
-;; * Setting `evil-state' to the new state.
-;; * Refreshing the keymaps in `evil-mode-map-alist'.
-;; * Updating the mode line.
-;; - Normal state depends on `evil-normal-state-tag'.
-;; * Adjusting the cursor's appearance.
-;; - Normal state depends on `evil-normal-state-cursor'.
-;; * Displaying a message in the echo area.
-;; - Normal state depends on `evil-normal-state-message'.
-;; * Running hooks.
-;; - Normal state runs `evil-normal-state-entry-hook' when
-;; entering, and `evil-normal-state-exit-hook' when exiting.
-;;
-;; The various properties of a state can be accessed through their
-;; respective variables, or by passing a keyword and the state's name
-;; to the `evil-state-property' function. Evil defines the states
-;; Normal state ("normal"), Insert state ("insert"), Visual state
-;; ("visual"), Replace state ("replace"), Operator-Pending state
-;; ("operator"), Motion state ("motion") and Emacs state ("emacs").
-
-(require 'evil-common)
-
-;;; Code:
-
-(declare-function evil-emacs-state-p "evil-states")
-(declare-function evil-ex-p "evil-ex")
-(defvar evil-mode-buffers)
-
-(define-minor-mode evil-local-mode
- "Minor mode for setting up Evil in a single buffer."
- :init-value nil
- (cond
- ((evil-disabled-buffer-p)
- ;; Don't leave the mode variable on in buffers where evil disabled, because
- ;; functions that check this variable will get an incorrect result (e.g.,
- ;; evil-refresh-cursor).
- (setq evil-local-mode nil))
- (evil-local-mode
- (setq emulation-mode-map-alists
- (evil-concat-lists '(evil-mode-map-alist)
- emulation-mode-map-alists))
- (evil-initialize-local-keymaps)
- ;; restore the proper value of `major-mode' in Fundamental buffers
- (when (eq major-mode 'turn-on-evil-mode)
- (setq major-mode 'fundamental-mode))
- (when (minibufferp)
- (setq-local evil-default-state 'insert)
- (setq-local evil-echo-state nil))
- ;; The initial state is usually setup by `evil-initialize' when
- ;; the major-mode in a buffer changes. This preliminary
- ;; initialization is only for the case when `evil-local-mode' is
- ;; called directly for the first time in a buffer.
- (unless evil-state (evil-initialize-state))
- (add-hook 'input-method-activate-hook 'evil-activate-input-method t t)
- (add-hook 'input-method-deactivate-hook 'evil-deactivate-input-method t t)
- (add-hook 'activate-mark-hook 'evil-visual-activate-hook nil t)
- (add-hook 'pre-command-hook 'evil-repeat-pre-hook)
- (add-hook 'post-command-hook 'evil-repeat-post-hook))
- (t
- (evil-refresh-mode-line)
- (remove-hook 'activate-mark-hook 'evil-visual-activate-hook t)
- (remove-hook 'input-method-activate-hook 'evil-activate-input-method t)
- (remove-hook 'input-method-deactivate-hook 'evil-deactivate-input-method t)
- (evil-change-state nil))))
-
-;; Make the variable permanent local. This is particular useful in
-;; conjunction with nXhtml/mumamo because mumamo does not touch these
-;; variables.
-(put 'evil-local-mode 'permanent-local t)
-
-(defun turn-on-evil-mode (&optional arg)
- "Turn on Evil in the current buffer."
- (interactive)
- (evil-local-mode (or arg 1)))
-
-(defun turn-off-evil-mode (&optional arg)
- "Turn off Evil in the current buffer."
- (interactive)
- (evil-local-mode (or arg -1)))
-
-;; The function `evil-initialize' should only be used to initialize
-;; `evil-local-mode' from the globalized minor-mode `evil-mode'. It is
-;; called whenever evil is enabled in a buffer for the first time or
-;; when evil is active and the major-mode of the buffer changes. In
-;; addition to enabling `evil-local-mode' it also sets the initial
-;; evil-state according to the major-mode.
-(defun evil-initialize ()
- "Enable Evil in the current buffer, if appropriate.
-To enable Evil globally, do (evil-mode 1)."
- (unless (and (minibufferp) (not evil-want-minibuffer))
- (evil-local-mode 1)
- (evil-initialize-state)))
-
-;;;###autoload (autoload 'evil-mode "evil" nil t)
-(define-globalized-minor-mode evil-mode
- evil-local-mode evil-initialize)
-
-;; No hooks are run in Fundamental buffers, so other measures are
-;; necessary to initialize Evil in these buffers. When Evil is
-;; enabled globally, the default value of `major-mode' is set to
-;; `turn-on-evil-mode', so that Evil is enabled in Fundamental
-;; buffers as well. Then, the buffer-local value of `major-mode' is
-;; changed back to `fundamental-mode'. (Since the `evil-mode' function
-;; is created by a macro, we use `defadvice' to augment it.)
-(defadvice evil-mode (after start-evil activate)
- "Enable Evil in Fundamental mode."
- (if evil-mode
- (progn
- (when (eq (default-value 'major-mode) 'fundamental-mode)
- ;; changed back by `evil-local-mode'
- (setq-default major-mode 'turn-on-evil-mode))
- (ad-enable-regexp "^evil")
- (ad-activate-regexp "^evil")
- (with-no-warnings (evil-esc-mode 1)))
- (when (eq (default-value 'major-mode) 'turn-on-evil-mode)
- (setq-default major-mode 'fundamental-mode))
- (ad-disable-regexp "^evil")
- (ad-update-regexp "^evil")
- (with-no-warnings (evil-esc-mode -1))))
-
-(defun evil-change-state (state &optional message)
- "Change the state to STATE.
-If STATE is nil, disable all states."
- (let ((func (evil-state-property (or state evil-state) :toggle)))
- (when (and (functionp func)
- (or message (not (eq state evil-state))))
- (funcall func (if state (and message 1) -1)))))
-
-(defmacro evil-save-state (&rest body)
- "Save the current state; execute BODY; restore the state."
- (declare (indent defun)
- (debug t))
- `(let* ((evil-state evil-state)
- (evil-previous-state evil-previous-state)
- (evil-previous-state-alist (copy-tree evil-previous-state-alist))
- (evil-next-state evil-next-state)
- (old-state evil-state)
- (inhibit-quit t)
- (buf (current-buffer)))
- (unwind-protect
- (progn ,@body)
- (when (buffer-live-p buf)
- (with-current-buffer buf
- (evil-change-state old-state))))))
-
-(defmacro evil-with-state (state &rest body)
- "Change to STATE and execute BODY without refreshing the display.
-Restore the previous state afterwards."
- (declare (indent defun)
- (debug t))
- `(evil-without-display
- (evil-save-state
- (evil-change-state ',state)
- ,@body)))
-
-(defun evil-initializing-p (&optional buffer)
- "Whether Evil is in the process of being initialized."
- (memq (or buffer (current-buffer)) evil-mode-buffers))
-
-(defun evil-initialize-state (&optional state buffer)
- "Set up the initial state for BUFFER.
-BUFFER defaults to the current buffer.
-Uses STATE if specified, or calls `evil-initial-state-for-buffer'.
-See also `evil-set-initial-state'."
- (with-current-buffer (or buffer (current-buffer))
- (if state (evil-change-state state)
- (evil-change-to-initial-state buffer))))
-(put 'evil-initialize-state 'permanent-local-hook t)
-
-(defun evil-initial-state-for-buffer-name (&optional name default)
- "Return the initial Evil state to use for a buffer with name NAME.
-Matches the name against the regular expressions in
-`evil-buffer-regexps'. If none matches, returns DEFAULT."
- (let ((name (if (stringp name) name (buffer-name name)))
- regexp state)
- (when (stringp name)
- (catch 'done
- (dolist (entry evil-buffer-regexps default)
- (setq regexp (car entry)
- state (cdr entry))
- (when (string-match regexp name)
- (throw 'done state)))))))
-
-(defun evil-disabled-buffer-p (&optional buffer)
- "Whether Evil should be disabled in BUFFER."
- (null (evil-initial-state-for-buffer-name buffer 'undefined)))
-
-(defun evil-initial-state-for-buffer (&optional buffer default)
- "Return the initial Evil state to use for BUFFER.
-BUFFER defaults to the current buffer. Returns DEFAULT
-if no initial state is associated with BUFFER.
-See also `evil-initial-state'."
- (with-current-buffer (or buffer (current-buffer))
- (or (evil-initial-state-for-buffer-name (buffer-name))
- (catch 'done
- (dolist (mode minor-mode-map-alist)
- (setq mode (car-safe mode))
- (when (and (boundp mode) (symbol-value mode))
- (when (setq mode (evil-initial-state mode))
- (throw 'done mode)))))
- (evil-initial-state major-mode nil t)
- default)))
-
-(defun evil-initial-state (mode &optional default follow-parent checked-modes)
- "Return the Evil state to use for MODE or its alias.
-Returns DEFAULT if no initial state is associated with MODE.
-The initial state for a mode can be set with
-`evil-set-initial-state'.
-
-If FOLLOW-PARENT is non-nil, also check parent modes of MODE and
-its alias. CHECKED-MODES is used internally and should not be set
-initially."
- (cond
- ((and mode (symbolp mode) (memq mode checked-modes))
- (error "Circular reference detected in ancestors of %s\n%s"
- major-mode checked-modes))
- ((and mode (symbolp mode))
- (let ((mode-alias (let ((func (symbol-function mode)))
- (when (symbolp func)
- func)))
- state modes)
- (or
- (catch 'done
- (dolist (entry (evil-state-property t :modes) default)
- (setq state (car entry)
- modes (symbol-value (cdr entry)))
- (when (or (memq mode modes)
- (and mode-alias
- (memq mode-alias modes)))
- (throw 'done state))))
- (when follow-parent
- (evil-initial-state (get mode 'derived-mode-parent)
- nil t (cons mode checked-modes)))
- (when follow-parent
- (evil-initial-state (get mode-alias 'derived-mode-parent)
- nil t (cons mode-alias checked-modes))))))))
-
-(defun evil-set-initial-state (mode state)
- "Set the initial state for major mode MODE to STATE.
-This is the state the buffer comes up in."
- (dolist (modes (evil-state-property t :modes))
- (setq modes (cdr-safe modes))
- (set modes (delq mode (symbol-value modes))))
- (when state
- (add-to-list (evil-state-property state :modes) mode)))
-
-(evil-define-command evil-change-to-initial-state
- (&optional buffer message)
- "Change the state of BUFFER to its initial state.
-This is the state the buffer came up in. If Evil is not activated
-then this function does nothing."
- :keep-visual t
- :suppress-operator t
- (with-current-buffer (or buffer (current-buffer))
- (when evil-local-mode
- (evil-change-state (evil-initial-state-for-buffer
- buffer (or evil-default-state 'normal))
- message))))
-
-(evil-define-command evil-change-to-previous-state
- (&optional buffer message)
- "Change the state of BUFFER to its previous state."
- :keep-visual t
- :repeat abort
- :suppress-operator t
- (with-current-buffer (or buffer (current-buffer))
- (let ((prev-state evil-previous-state)
- (prev-prev-state (cdr-safe (assoc evil-previous-state
- evil-previous-state-alist))))
- (evil-change-state nil)
- (when prev-prev-state
- (setq evil-previous-state prev-prev-state))
- (evil-change-state (or prev-state evil-default-state 'normal)
- message))))
-
-;; When a buffer is created in a low-level way, it is invisible to
-;; Evil (as well as other globalized minor modes) because no hooks are
-;; run. This is appropriate since many buffers are used for throwaway
-;; purposes. Passing the buffer to `set-window-buffer' indicates
-;; otherwise, though, so advise this function to initialize Evil.
-(defadvice set-window-buffer (before evil)
- "Initialize Evil in the displayed buffer."
- (when evil-mode
- (when (get-buffer (ad-get-arg 1))
- (with-current-buffer (ad-get-arg 1)
- (unless evil-local-mode
- (evil-local-mode 1))))))
-
-;; Refresh cursor color.
-;; Cursor color can only be set for each frame but not for each buffer.
-(add-hook 'window-configuration-change-hook 'evil-refresh-cursor)
-(defadvice select-window (after evil activate)
- (evil-refresh-cursor))
-
-(defun evil-generate-mode-line-tag (&optional state)
- "Generate the evil mode-line tag for STATE."
- (let ((tag (evil-state-property state :tag t)))
- (when (functionp tag)
- (setq tag (funcall tag)))
- ;; prepare mode-line: add tooltip
- (if (stringp tag)
- (propertize tag
- 'help-echo (evil-state-property state :name)
- 'mouse-face 'mode-line-highlight)
- tag)))
-
-(defun evil-refresh-mode-line (&optional state)
- "Refresh mode line tag."
- (when (listp mode-line-format)
- (setq evil-mode-line-tag (evil-generate-mode-line-tag state))
- ;; refresh mode line data structure
- ;; first remove evil from mode-line
- (setq mode-line-format (delq 'evil-mode-line-tag mode-line-format))
- (let ((mlpos mode-line-format)
- pred which where)
- ;; determine before/after which symbol the tag should be placed
- (cond
- ((eq evil-mode-line-format 'before)
- (setq where 'after which 'mode-line-position))
- ((eq evil-mode-line-format 'after)
- (setq where 'after which 'mode-line-modes))
- ((consp evil-mode-line-format)
- (setq where (car evil-mode-line-format)
- which (cdr evil-mode-line-format))))
- ;; find the cons-cell of the symbol before/after which the tag
- ;; should be placed
- (while (and mlpos
- (let ((sym (or (car-safe (car mlpos)) (car mlpos))))
- (not (eq which sym))))
- (setq pred mlpos
- mlpos (cdr mlpos)))
- ;; put evil tag at the right position in the mode line
- (cond
- ((not mlpos)) ;; position not found, so do not add the tag
- ((eq where 'before)
- (if pred
- (setcdr pred (cons 'evil-mode-line-tag mlpos))
- (setq mode-line-format
- (cons 'evil-mode-line-tag mode-line-format))))
- ((eq where 'after)
- (setcdr mlpos (cons 'evil-mode-line-tag (cdr mlpos)))))
- (force-mode-line-update))))
-
-;; input methods should be disabled in non-insertion states
-(defun evil-activate-input-method ()
- "Enable input method in states with :input-method non-nil."
- (let (input-method-activate-hook
- input-method-deactivate-hook)
- (when (and evil-local-mode evil-state)
- (setq evil-input-method current-input-method)
- (unless (evil-state-property evil-state :input-method)
- (deactivate-input-method)))))
-(put 'evil-activate-input-method 'permanent-local-hook t)
-
-(defun evil-deactivate-input-method ()
- "Disable input method in all states."
- (let (input-method-activate-hook
- input-method-deactivate-hook)
- (when (and evil-local-mode evil-state)
- (setq evil-input-method nil))))
-(put 'evil-deactivate-input-method 'permanent-local-hook t)
-
-(defmacro evil-without-input-method-hooks (&rest body)
- "Execute body with evil's activate/deactivate-input-method hooks deactivated.
-
-This allows input methods to be used in normal-state."
- `(unwind-protect
- (progn
- (remove-hook 'input-method-activate-hook 'evil-activate-input-method t)
- (remove-hook 'input-method-deactivate-hook
- 'evil-deactivate-input-method t)
- ,@body)
- (progn
- (add-hook 'input-method-activate-hook 'evil-activate-input-method nil t)
- (add-hook 'input-method-deactivate-hook
- 'evil-deactivate-input-method nil t))))
-
-(defadvice toggle-input-method (around evil)
- "Refresh `evil-input-method'."
- (cond
- ((not evil-local-mode)
- ad-do-it)
- ((evil-state-property evil-state :input-method)
- ad-do-it)
- (t
- (let ((current-input-method evil-input-method))
- ad-do-it))))
-
-;; Local keymaps are implemented using buffer-local variables.
-;; However, unless a buffer-local value already exists,
-;; `define-key' acts on the variable's default (global) value.
-;; So we need to initialize the variable whenever we enter a
-;; new buffer or when the buffer-local values are reset.
-(defun evil-initialize-local-keymaps ()
- "Initialize a buffer-local value for local keymaps as necessary.
-The initial value is that of `make-sparse-keymap'."
- (dolist (entry evil-local-keymaps-alist)
- (let ((map (cdr entry)))
- (unless (and (keymapp (symbol-value map))
- (local-variable-p map))
- (set map (make-sparse-keymap))))))
-
-(defun evil-make-overriding-map (keymap &optional state copy)
- "Give KEYMAP precedence over the global keymap of STATE.
-The keymap will have lower precedence than custom STATE bindings.
-If STATE is nil, give it precedence over all states.
-If COPY is t, create a copy of KEYMAP and give that
-higher precedence. See also `evil-make-intercept-map'."
- (let ((key [override-state]))
- (if (not copy)
- (define-key keymap key (or state 'all))
- (unless (keymapp copy)
- (setq copy (assq-delete-all 'menu-bar (copy-keymap keymap))))
- (define-key copy key (or state 'all))
- (define-key keymap key copy))))
-
-(defun evil-make-intercept-map (keymap &optional state aux)
- "Give KEYMAP precedence over all Evil keymaps in STATE.
-If STATE is nil, give it precedence over all states. If AUX is non-nil, make the
-auxiliary keymap corresponding to KEYMAP in STATE an intercept keymap instead of
-KEYMAP itself. See also `evil-make-overriding-map'."
- (let ((key [intercept-state])
- (keymap (if aux
- (evil-get-auxiliary-keymap keymap state t t)
- keymap)))
- (define-key keymap key (or state 'all))))
-
-(defmacro evil-define-keymap (keymap doc &rest body)
- "Define a keymap KEYMAP listed in `evil-mode-map-alist'.
-That means it will have precedence over regular keymaps.
-
-DOC is the documentation for the variable. BODY, if specified,
-is executed after toggling the mode. Optional keyword arguments
-may be specified before the body code:
-
-:mode VAR Mode variable. If unspecified, the variable
- is based on the keymap name.
-:local BOOLEAN Whether the keymap should be buffer-local, that is,
- reinitialized for each buffer.
-:func BOOLEAN Create a toggle function even if BODY is empty.
-
-\(fn KEYMAP DOC [[KEY VAL]...] BODY...)"
- (declare (indent defun)
- (doc-string 2)
- (debug (&define name
- [&optional stringp]
- [&rest [keywordp sexp]]
- def-body)))
- (let ((func t)
- arg intercept key local mode overriding)
- (while (keywordp (car-safe body))
- (setq key (pop body)
- arg (pop body))
- (cond
- ((eq key :mode)
- (setq mode arg))
- ((eq key :local)
- (setq local arg))
- ((eq key :func)
- (setq func arg))
- ((eq key :intercept)
- (setq intercept arg))
- ((eq key :overriding)
- (setq overriding arg))))
- (setq mode (or mode
- (intern (replace-regexp-in-string
- "\\(?:-\\(?:mode-\\)?\\(?:key\\)?map\\)?$"
- "-mode"
- (symbol-name keymap)))))
- `(progn
- (defvar ,keymap ,(unless local '(make-sparse-keymap)))
- (unless (get ',keymap 'variable-documentation)
- (put ',keymap 'variable-documentation ,doc))
- (defvar ,mode nil)
- (unless (get ',mode 'variable-documentation)
- (put ',mode 'variable-documentation ,doc))
- (make-variable-buffer-local ',mode)
- (put ',mode 'permanent-local t)
- (when ,intercept
- (evil-make-intercept-map ,keymap))
- (when ,overriding
- (evil-make-overriding-map ,keymap))
- ,@(if local
- `((make-variable-buffer-local ',keymap)
- (put ',keymap 'permanent-local t)
- (evil--add-to-alist 'evil-local-keymaps-alist
- ',mode ',keymap))
- `((evil--add-to-alist 'evil-global-keymaps-alist
- ',mode ',keymap)
- (evil--add-to-alist 'evil-mode-map-alist
- ',mode ,keymap)))
- ,(when (or body func)
- `(defun ,mode (&optional arg)
- ,@(when doc `(,doc))
- (interactive)
- (cond
- ((numberp arg)
- (setq ,mode (> arg 0)))
- (t
- (setq ,mode (not ,mode))))
- ,@body))
- ',keymap)))
-
-;; 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-mode t)
- (add-hook 'after-make-frame-functions #'evil-init-esc)
- (mapc #'evil-init-esc (frame-list))))
- ((< arg 0)
- (when evil-esc-mode
- (remove-hook 'after-make-frame-functions #'evil-init-esc)
- (mapc #'evil-deinit-esc (frame-list))
- (setq evil-esc-mode nil)))))
-
-(defun evil-init-esc (frame)
- "Update `input-decode-map' in terminal."
- (with-selected-frame frame
- (let ((term (frame-terminal frame)))
- (when (and
- (or (eq evil-intercept-esc 'always)
- (and evil-intercept-esc
- (eq (terminal-live-p term) t))) ; only patch tty
- (not (terminal-parameter term 'evil-esc-map)))
- (let ((evil-esc-map (lookup-key input-decode-map [?\e])))
- (set-terminal-parameter term 'evil-esc-map evil-esc-map)
- (define-key input-decode-map [?\e]
- `(menu-item "" ,evil-esc-map :filter ,#'evil-esc)))))))
-
-(defun evil-deinit-esc (frame)
- "Restore `input-decode-map' in terminal."
- (with-selected-frame frame
- (let ((term (frame-terminal frame)))
- (when (terminal-live-p term)
- (let ((evil-esc-map (terminal-parameter term 'evil-esc-map)))
- (when evil-esc-map
- (define-key input-decode-map [?\e] evil-esc-map)
- (set-terminal-parameter term 'evil-esc-map nil)))))))
-
-(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)
- (or evil-local-mode (evil-ex-p)
- (active-minibuffer-window))
- (not (evil-emacs-state-p))
- (let ((keys (this-single-command-keys)))
- (and (> (length keys) 0)
- (= (aref keys (1- (length keys))) ?\e)))
- (sit-for evil-esc-delay))
- (prog1 [escape]
- (when defining-kbd-macro
- (end-kbd-macro)
- (setq last-kbd-macro (vconcat last-kbd-macro [escape]))
- (start-kbd-macro t t)))
- map))
-
-(defun evil-state-p (sym)
- "Whether SYM is the name of a state."
- (assq sym evil-state-properties))
-
-(defun evil-state-keymaps (state &rest excluded)
- "Return a keymap alist of keymaps activated by STATE.
-If STATE references other states in its :enable property,
-these states are recursively processed and added to the list.
-\(The EXCLUDED argument is an internal safeguard against
-infinite recursion, keeping track of processed states.)"
- (let* ((state (or state evil-state))
- (enable (evil-state-property state :enable))
- (map (cons
- (evil-state-property state :mode)
- (evil-state-property state :keymap t)))
- (local-map (cons
- (evil-state-property state :local)
- (evil-state-property state :local-keymap t)))
- (minor-mode-maps (evil-state-minor-mode-keymaps state))
- (aux-maps (evil-state-auxiliary-keymaps state))
- (overriding-maps
- (evil-state-overriding-keymaps state))
- (intercept-maps
- (evil-state-intercept-keymaps state))
- (result `(,intercept-maps))
- (remove-duplicates (null excluded)))
- (unless (memq state enable)
- (setq enable (cons state enable)))
- ;; process STATE's :enable property
- (dolist (entry enable)
- (cond
- ((memq entry excluded))
- ;; the keymaps for STATE
- ((eq entry state)
- (setq result `(,@result
- (,local-map)
- ,minor-mode-maps
- ,aux-maps
- ,overriding-maps
- (,map)))
- (push state excluded))
- ;; the keymaps for another state: call `evil-state-keymaps'
- ;; recursively, but keep track of processed states
- ((evil-state-p entry)
- (setq result `(,@result
- ,(apply #'evil-state-keymaps entry excluded))))
- ;; a single keymap
- ((or (keymapp entry)
- (and (keymapp (symbol-value entry))
- (setq entry (symbol-value entry)))
- (setq entry (evil-keymap-for-mode entry)))
- (setq result `(,@result
- ((,(evil-mode-for-keymap entry t) .
- ,entry)))))))
- ;; postpone the expensive filtering of duplicates to the top level
- (if remove-duplicates
- (apply #'evil-concat-keymap-alists result)
- (apply #'append result))))
-
-(defun evil-normalize-keymaps (&optional state)
- "Create a buffer-local value for `evil-mode-map-alist'.
-This is a keymap alist, determined by the current state
-\(or by STATE if specified)."
- (let ((state (or state evil-state))
- (excluded '(nil t))
- map mode temp)
- ;; initialize buffer-local keymaps as necessary
- (evil-initialize-local-keymaps)
- ;; deactivate keymaps of previous state
- (dolist (entry evil-mode-map-alist)
- (setq mode (car-safe entry)
- map (cdr-safe entry))
- ;; don't deactivate overriding keymaps;
- ;; they are toggled by their associated mode
- (if (or (memq mode excluded)
- (evil-intercept-keymap-p map)
- (evil-overriding-keymap-p map)
- (evil-auxiliary-keymap-p map)
- (evil-minor-mode-keymap-p map))
- (push mode excluded)
- (when (and (fboundp mode) (symbol-value mode))
- (funcall mode -1))
- (set mode nil)))
- (setq evil-mode-map-alist nil)
- ;; activate keymaps of current state
- (when state
- (setq temp (evil-state-keymaps state))
- (dolist (entry temp)
- (setq mode (car entry)
- map (cdr entry))
- (unless (or (and (boundp mode) (symbol-value mode))
- ;; the minor-mode keymaps include modes that are not
- ;; necessarily active
- (evil-minor-mode-keymap-p map))
- (when (fboundp mode)
- (funcall mode 1))
- (set mode t))
- ;; refresh the keymap in case it has changed
- ;; (e.g., `evil-operator-shortcut-map' is
- ;; reset on toggling)
- (if (or (memq mode excluded)
- (evil-intercept-keymap-p map)
- (evil-overriding-keymap-p map)
- (evil-auxiliary-keymap-p map)
- (evil-minor-mode-keymap-p map))
- (push mode excluded)
- (setcdr entry (or (evil-keymap-for-mode mode) map))))
- ;; update `evil-mode-map-alist'
- (setq evil-mode-map-alist temp))))
-
-(defun evil-mode-for-keymap (keymap &optional default)
- "Return the minor mode associated with KEYMAP.
-Returns DEFAULT if no mode is found.
-See also `evil-keymap-for-mode'."
- (let ((map (if (keymapp keymap) keymap (symbol-value keymap)))
- (var (when (symbolp keymap) keymap)))
- ;; Check Evil variables first for speed purposes.
- ;; If all else fails, check `minor-mode-map-alist'.
- (or (when var
- (or (car (rassq var evil-global-keymaps-alist))
- (car (rassq var evil-local-keymaps-alist))))
- (car (rassq map (mapcar #'(lambda (e)
- ;; from (MODE-VAR . MAP-VAR)
- ;; to (MODE-VAR . MAP)
- (cons (car-safe e)
- (symbol-value (cdr-safe e))))
- (append evil-global-keymaps-alist
- evil-local-keymaps-alist))))
- (car (rassq map minor-mode-map-alist))
- default)))
-
-(defun evil-keymap-for-mode (mode &optional variable)
- "Return the keymap associated with MODE.
-Return the keymap variable if VARIABLE is non-nil.
-See also `evil-mode-for-keymap'."
- (let* ((var (or (cdr (assq mode evil-global-keymaps-alist))
- (cdr (assq mode evil-local-keymaps-alist))))
- (map (or (symbol-value var)
- (cdr (assq mode minor-mode-map-alist)))))
- (if variable var map)))
-
-(defun evil-state-auxiliary-keymaps (state)
- "Return a keymap alist of auxiliary keymaps for STATE."
- (let ((state (or state evil-state))
- aux result)
- (dolist (map (current-active-maps) result)
- (when (setq aux (evil-get-auxiliary-keymap map state))
- (push (cons (evil-mode-for-keymap map t) aux) result)))
- (nreverse result)))
-
-(defun evil-state-minor-mode-keymaps (state)
- "Return a keymap alist of minor-mode keymaps for STATE."
- (let* ((state (or state evil-state))
- (state-entry (assq state evil-minor-mode-keymaps-alist)))
- (when state-entry
- (cdr state-entry))))
-
-(defun evil-state-overriding-keymaps (&optional state)
- "Return a keymap alist of overriding keymaps for STATE."
- (let* ((state (or state evil-state))
- result)
- (dolist (map (current-active-maps))
- (when (setq map (evil-overriding-keymap-p map state))
- (push (cons (evil-mode-for-keymap map t) map) result)))
- (nreverse result)))
-
-(defun evil-state-intercept-keymaps (&optional state)
- "Return a keymap alist of intercept keymaps for STATE."
- (let* ((state (or state evil-state))
- result)
- (dolist (map (current-active-maps))
- (when (setq map (or (evil-intercept-keymap-p map state)
- (evil-intercept-keymap-p
- (evil-get-auxiliary-keymap map state) state)))
- (push (cons (evil-mode-for-keymap map t) map) result)))
- (setq result (nreverse result))
- result))
-
-(defun evil-set-auxiliary-keymap (map state &optional aux)
- "Set the auxiliary keymap for MAP in STATE to AUX.
-If AUX is nil, create a new auxiliary keymap."
- (unless (keymapp aux)
- (setq aux (make-sparse-keymap)))
- (unless (evil-auxiliary-keymap-p aux)
- (evil-set-keymap-prompt
- aux (format "Auxiliary keymap for %s"
- (or (evil-state-property state :name)
- (format "%s state" state)))))
- (define-key map
- (vconcat (list (intern (format "%s-state" state)))) aux)
- aux)
-(put 'evil-set-auxiliary-keymap 'lisp-indent-function 'defun)
-
-(defun evil-get-auxiliary-keymap (map state &optional create ignore-parent)
- "Get the auxiliary keymap for MAP in STATE.
-If CREATE is non-nil, create an auxiliary keymap
-if MAP does not have one. If CREATE and
-IGNORE-PARENT are non-nil then a new auxiliary
-keymap is created even if the parent of MAP has
-one already."
- (when state
- (let* ((key (vconcat (list (intern (format "%s-state" state)))))
- (parent-aux (when (and ignore-parent
- (keymap-parent map))
- (lookup-key (keymap-parent map) key)))
- (aux (lookup-key map key)))
- (cond
- ((and ignore-parent
- (equal parent-aux aux)
- create)
- (evil-set-auxiliary-keymap map state))
- ((evil-auxiliary-keymap-p aux)
- aux)
- (create
- (evil-set-auxiliary-keymap map state))))))
-
-(defun evil-get-minor-mode-keymap (state mode)
- "Get the auxiliary keymap for MODE in STATE, creating one if it
-does not already exist."
- (let ((state-entry (assq state evil-minor-mode-keymaps-alist)))
- (if (and state-entry
- (assq mode state-entry))
- (cdr (assq mode state-entry))
- (let ((map (make-sparse-keymap)))
- (evil-set-keymap-prompt
- map (format "Minor-mode keymap for %s in %s"
- (symbol-name mode)
- (or (evil-state-property state :name)
- (format "%s state" state))))
- (if state-entry
- (setcdr state-entry
- (append (list (cons mode map)) (cdr state-entry)))
- (push (cons state (list (cons mode map)))
- evil-minor-mode-keymaps-alist))
- map))))
-
-(defun evil-auxiliary-keymap-p (map)
- "Whether MAP is an auxiliary keymap."
- (and (keymapp map)
- (string-match-p "Auxiliary keymap"
- (or (keymap-prompt map) "")) t))
-
-(defun evil-minor-mode-keymap-p (map)
- "Whether MAP is a minor-mode keymap."
- (and (keymapp map)
- (string-match-p "Minor-mode keymap"
- (or (keymap-prompt map) "")) t))
-
-(defun evil-intercept-keymap-p (map &optional state)
- "Whether MAP is an intercept keymap for STATE.
-If STATE is nil, it means any state."
- (let ((entry (and (keymapp map)
- (lookup-key map [intercept-state]))))
- (cond
- ((null entry)
- nil)
- ((null state)
- map)
- ((eq entry state)
- map)
- ((eq entry 'all)
- map))))
-
-(defun evil-overriding-keymap-p (map &optional state)
- "Whether MAP is an overriding keymap for STATE.
-If STATE is nil, it means any state."
- (let ((entry (and (keymapp map)
- (lookup-key map [override-state]))))
- (cond
- ((null entry)
- nil)
- ((keymapp entry)
- (evil-overriding-keymap-p entry state))
- ((null state)
- map)
- ((eq entry state)
- map)
- ((eq entry 'all)
- map))))
-
-(defun evil-intercept-keymap-state (map)
- "Return the state for the intercept keymap MAP.
-A return value of t means all states."
- (let ((state (lookup-key map [intercept-state] map)))
- (cond
- ((keymapp state)
- (evil-intercept-keymap-state state))
- ((eq state 'all)
- t)
- (t
- state))))
-
-(defun evil-overriding-keymap-state (map)
- "Return the state for the overriding keymap MAP.
-A return value of t means all states."
- (let ((state (lookup-key map [override-state] map)))
- (cond
- ((keymapp state)
- (evil-overriding-keymap-state state))
- ((eq state 'all)
- t)
- (t
- state))))
-
-(defun evil-send-leader ()
- "Put symbol leader in `unread-command-events' to trigger any
-<leader> bindings."
- (interactive)
- (setq prefix-arg current-prefix-arg)
- (push '(t . leader) unread-command-events))
-
-(defun evil-send-localleader ()
- "Put symbol localleader in `unread-command-events' to trigger any
-<localleader> bindings."
- (interactive)
- (setq prefix-arg current-prefix-arg)
- (push '(t . localleader) unread-command-events))
-
-(defun evil-set-leader (state key &optional localleader)
- "Set KEY to trigger leader bindings in STATE.
-KEY should be in the form produced by `kbd'. STATE is one of
-`normal', `insert', `visual', `replace', `operator', `motion',
-`emacs', a list of one or more of these, or `nil', which means
-all of the above. If LOCALLEADER is non-nil, set the local leader
-instead."
- (let* ((all-states '(normal insert visual replace operator motion emacs))
- (states (cond ((listp state) state)
- ((member state all-states) (list state))
- ((null state) all-states)
- ;; Maybe throw error here
- (t (list state))))
- (binding (if localleader 'evil-send-localleader 'evil-send-leader)))
- (dolist (state states)
- (evil-global-set-key state key binding))))
-
-(defmacro evil-define-key (state keymap key def &rest bindings)
- "Create a STATE binding from KEY to DEF for KEYMAP.
-STATE is one of `normal', `insert', `visual', `replace',
-`operator', `motion', `emacs', or a list of one or more of
-these. Omitting a state by using `nil' corresponds to a standard
-Emacs binding using `define-key'. The remaining arguments are
-like those of `define-key'. For example:
-
- (evil-define-key 'normal foo-map \"a\" 'bar)
-
-This creates a binding from `a' to `bar' in normal state, which
-is active whenever `foo-map' is active. Using nil for the state,
-the following lead to identical bindings:
-
- (evil-define-key nil foo-map \"a\" 'bar)
- (define-key foo-map \"a\" 'bar)
-
-It is possible to specify multiple states and/or bindings at
-once:
-
- (evil-define-key '(normal visual) foo-map
- \"a\" 'bar
- \"b\" 'foo)
-
-If `foo-map' has not been initialized yet, this macro adds an
-entry to `after-load-functions', delaying execution as necessary.
-
-KEYMAP may also be a quoted symbol. If the symbol is `global', the
-global evil keymap corresponding to the state(s) is used, meaning
-the following lead to identical bindings:
-
- (evil-define-key 'normal 'global \"a\" 'bar)
- (evil-global-set-key 'normal \"a\" 'bar)
-
-The symbol `local' may also be used, which corresponds to using
-`evil-local-set-key'. If a quoted symbol is used that is not
-`global' or `local', it is assumed to be the name of a minor
-mode, in which case `evil-define-minor-mode-key' is used."
- (declare (indent defun))
- (cond ((member keymap '('global 'local))
- `(evil-define-key* ,state ,keymap ,key ,def ,@bindings))
- ((and (consp keymap) (eq (car keymap) 'quote))
- `(evil-define-minor-mode-key ,state ,keymap ,key ,def ,@bindings))
- (t
- `(evil-delay ',(if (symbolp keymap)
- `(and (boundp ',keymap) (keymapp ,keymap))
- `(keymapp ,keymap))
- '(condition-case-unless-debug err
- (evil-define-key* ,state ,keymap ,key ,def ,@bindings)
- (error
- (message "error in evil-define-key: %s"
- (error-message-string err))))
- 'after-load-functions t nil
- (format "evil-define-key-in-%s"
- ',(if (symbolp keymap) keymap 'keymap))))))
-(defalias 'evil-declare-key 'evil-define-key)
-
-(defun evil-define-key* (state keymap key def &rest bindings)
- "Create a STATE binding from KEY to DEF for KEYMAP.
-STATE is one of normal, insert, visual, replace, operator,
-motion, emacs, or a list of one or more of these. Omitting a
-state by using nil corresponds to a standard Emacs binding using
-`define-key' The remaining arguments are like those of
-`define-key'. For example:
-
- (evil-define-key* 'normal foo-map \"a\" 'bar)
-
-This creates a binding from \"a\" to bar in Normal state, which
-is active whenever foo-map is active. Using nil for the state,
-the following are equivalent:
-
- (evil-define-key* nil foo-map \"a\" 'bar)
-
- (define-key foo-map \"a\" 'bar)
-
- It is possible to specify multiple states and/or bindings at
- once:
-
- (evil-define-key* '(normal visual) foo-map
- \"a\" 'bar
- \"b\" 'foo)
-
-KEYMAP may also be a quoted symbol. If the symbol is global, the
-global evil keymap corresponding to the state(s) is used, meaning
-the following are equivalent:
-
- (evil-define-key* 'normal 'global \"a\" 'bar)
-
- (evil-global-set-key 'normal \"a\" 'bar)
-
-The symbol local may also be used, which corresponds to using
-`evil-local-set-key'.
-
-The use is nearly identical to `evil-define-key' with the
-exception that this is a function and not a macro (and so will
-not be expanded when compiled which can have unintended
-consequences). `evil-define-key*' also does not defer any
-bindings like `evil-define-key' does using `evil-delay'. This
-allows errors in the bindings to be caught immediately, and makes
-its behavior more predictable."
- (declare (indent defun))
- (let ((maps
- (if state
- (mapcar
- (lambda (st)
- (cond ((eq keymap 'global)
- (evil-state-property st :keymap t))
- ((eq keymap 'local)
- (evil-state-property st :local-keymap t))
- (t
- (evil-get-auxiliary-keymap keymap st t t))))
- (if (listp state) state (list state)))
- (list
- (cond ((eq keymap 'global)
- global-map)
- ((eq keymap 'local)
- ;; see `local-set-key'
- (or (current-local-map)
- (let ((map (make-sparse-keymap)))
- (use-local-map map)
- map)))
- (t
- keymap))))))
- (while key
- (dolist (map maps)
- (define-key map key def))
- (setq key (pop bindings)
- def (pop bindings)))
- ;; ensure the prompt string comes first
- (dolist (map maps)
- (evil-set-keymap-prompt map (keymap-prompt map)))))
-
-(defun evil-define-minor-mode-key (state mode key def &rest bindings)
- "Similar to `evil-define-key' but the bindings are associated
-with the minor-mode symbol MODE instead of a particular map.
-Associating bindings with a mode symbol instead of a map allows
-evil to use Emacs' built-in mechanisms to enable the bindings
-automatically when MODE is active without relying on calling
-`evil-normalize-keymaps'. Another less significant difference is
-that the bindings can be created immediately, because this
-function only uses the symbol MODE and does not rely on its
-value.
-
-See `evil-define-key' for the usage of STATE, KEY, DEF and
-BINDINGS."
- (declare (indent defun))
- (let ((maps (mapcar
- (lambda (st)
- (evil-get-minor-mode-keymap st mode))
- (if (listp state) state (list state)))))
- (while key
- (dolist (map maps)
- (define-key map key def))
- (setq key (pop bindings)
- def (pop bindings)))))
-
-(defmacro evil-add-hjkl-bindings (keymap &optional state &rest bindings)
- "Add \"h\", \"j\", \"k\", \"l\" bindings to KEYMAP in STATE.
-Add additional BINDINGS if specified."
- (declare (indent defun))
- `(evil-define-key ,state ,keymap
- "h" (lookup-key evil-motion-state-map "h")
- "j" (lookup-key evil-motion-state-map "j")
- "k" (lookup-key evil-motion-state-map "k")
- "l" (lookup-key evil-motion-state-map "l")
- ":" (lookup-key evil-motion-state-map ":")
- ,@bindings))
-
-;; may be useful for programmatic purposes
-(defun evil-global-set-key (state key def)
- "Bind KEY to DEF in STATE."
- (define-key (evil-state-property state :keymap t) key def))
-
-(defun evil-local-set-key (state key def)
- "Bind KEY to DEF in STATE in the current buffer."
- (define-key (evil-state-property state :local-keymap t) key def))
-
-;; Advise these functions as they may activate an overriding keymap or
-;; a keymap with state bindings; if so, refresh `evil-mode-map-alist'.
-(defadvice use-global-map (after evil activate)
- "Refresh Evil keymaps."
- (evil-normalize-keymaps))
-
-(defadvice use-local-map (after evil activate)
- "Refresh Evil keymaps."
- (evil-normalize-keymaps))
-
-(defmacro evil-define-state (state doc &rest body)
- "Define an Evil state STATE.
-DOC is a general description and shows up in all docstrings;
-the first line of the string should be the full name of the state.
-
-BODY is executed each time the state is enabled or disabled.
-
-Optional keyword arguments:
-- `:tag' - the mode line indicator, e.g. \"<T>\".
-- `:message' - string shown in the echo area when the state is
- activated.
-- `:cursor' - default cursor specification.
-- `:enable' - list of other state keymaps to enable when in this
- state.
-- `:entry-hook' - list of functions to run when entering this state.
-- `:exit-hook' - list of functions to run when exiting this state.
-- `:suppress-keymap' - if non-nil, effectively disables bindings to
- `self-insert-command' by making `evil-suppress-map' the parent of
- the global state keymap.
-
-The global keymap of this state will be `evil-test-state-map',
-the local keymap will be `evil-test-state-local-map', and so on.
-
-\(fn STATE DOC [[KEY VAL]...] BODY...)"
- (declare (indent defun)
- (doc-string 2)
- (debug (&define name
- [&optional stringp]
- [&rest [keywordp sexp]]
- def-body)))
- (let* ((name (and (string-match "^\\(.+\\)\\(\\(?:.\\|\n\\)*\\)" doc)
- (match-string 1 doc)))
- (doc (match-string 2 doc))
- (name (and (string-match "^\\(.+?\\)\\.?$" name)
- (match-string 1 name)))
- (doc (if (or (null doc) (string= doc "")) ""
- (format "\n%s" doc)))
- (toggle (intern (format "evil-%s-state" state)))
- (mode (intern (format "%s-minor-mode" toggle)))
- (keymap (intern (format "%s-map" toggle)))
- (local (intern (format "%s-local-minor-mode" toggle)))
- (local-keymap (intern (format "%s-local-map" toggle)))
- (tag (intern (format "%s-tag" toggle)))
- (message (intern (format "%s-message" toggle)))
- (cursor (intern (format "%s-cursor" toggle)))
- (entry-hook (intern (format "%s-entry-hook" toggle)))
- (exit-hook (intern (format "%s-exit-hook" toggle)))
- (modes (intern (format "%s-modes" toggle)))
- (predicate (intern (format "%s-p" toggle)))
- arg cursor-value enable entry-hook-value exit-hook-value
- input-method key message-value suppress-keymap tag-value)
- ;; collect keywords
- (while (keywordp (car-safe body))
- (setq key (pop body)
- arg (pop body))
- (cond
- ((eq key :tag)
- (setq tag-value arg))
- ((eq key :message)
- (setq message-value arg))
- ((eq key :cursor)
- (setq cursor-value arg))
- ((eq key :entry-hook)
- (setq entry-hook-value arg)
- (unless (listp entry-hook-value)
- (setq entry-hook-value (list entry-hook-value))))
- ((eq key :exit-hook)
- (setq exit-hook-value arg)
- (unless (listp exit-hook-value)
- (setq exit-hook-value (list exit-hook-value))))
- ((eq key :enable)
- (setq enable arg))
- ((eq key :input-method)
- (setq input-method arg))
- ((eq key :suppress-keymap)
- (setq suppress-keymap arg))))
-
- ;; macro expansion
- `(progn
- ;; Save the state's properties in `evil-state-properties' for
- ;; runtime lookup. Among other things, this information is used
- ;; to determine what keymaps should be activated by the state
- ;; (and, when processing :enable, what keymaps are activated by
- ;; other states). We cannot know this at compile time because
- ;; it depends on the current buffer and its active keymaps
- ;; (to which we may have assigned state bindings), as well as
- ;; states whose definitions may not have been processed yet.
- (evil-put-property
- 'evil-state-properties ',state
- :name ',name
- :toggle ',toggle
- :mode (defvar ,mode nil
- ,(format "Non-nil if %s is enabled.
-Use the command `%s' to change this variable." name toggle))
- :keymap (defvar ,keymap (make-sparse-keymap)
- ,(format "Keymap for %s." name))
- :local (defvar ,local nil
- ,(format "Non-nil if %s is enabled.
-Use the command `%s' to change this variable." name toggle))
- :local-keymap (defvar ,local-keymap nil
- ,(format "Buffer-local keymap for %s." name))
- :tag (defvar ,tag ,tag-value
- ,(format "Mode line tag for %s." name))
- :message (defvar ,message ,message-value
- ,(format "Echo area message for %s." name))
- :cursor (defvar ,cursor ',cursor-value
- ,(format "Cursor for %s.
-May be a cursor type as per `cursor-type', a color string as passed
-to `set-cursor-color', a zero-argument function for changing the
-cursor, or a list of the above." name))
- :entry-hook (defvar ,entry-hook nil
- ,(format "Hooks to run when entering %s." name))
- :exit-hook (defvar ,exit-hook nil
- ,(format "Hooks to run when exiting %s." name))
- :modes (defvar ,modes nil
- ,(format "Modes that should come up in %s." name))
- :input-method ',input-method
- :predicate ',predicate
- :enable ',enable)
-
- ,@(when suppress-keymap
- `((set-keymap-parent ,keymap evil-suppress-map)))
-
- (dolist (func ',entry-hook-value)
- (add-hook ',entry-hook func))
-
- (dolist (func ',exit-hook-value)
- (add-hook ',exit-hook func))
-
- (defun ,predicate (&optional state)
- ,(format "Whether the current state is %s.
-\(That is, whether `evil-state' is `%s'.)" name state)
- (and evil-local-mode
- (eq (or state evil-state) ',state)))
-
- ;; define state function
- (defun ,toggle (&optional arg)
- ,(format "Enable %s. Disable with negative ARG.
-If ARG is nil, don't display a message in the echo area.%s" name doc)
- (interactive)
- (cond
- ((and (numberp arg) (< arg 1))
- (setq evil-previous-state evil-state
- evil-state nil)
- (let ((evil-state ',state))
- (run-hooks ',exit-hook)
- (setq evil-state nil)
- (evil-normalize-keymaps)
- ,@body))
- (t
- (unless evil-local-mode
- (evil-local-mode 1))
- (let ((evil-next-state ',state)
- input-method-activate-hook
- input-method-deactivate-hook)
- (evil-change-state nil)
- (setq evil-state ',state)
- (evil--add-to-alist 'evil-previous-state-alist
- ',state evil-previous-state)
- (let ((evil-state ',state))
- (evil-normalize-keymaps)
- (if ',input-method
- (activate-input-method evil-input-method)
- ;; BUG #475: Deactivate the current input method only
- ;; if there is a function to deactivate it, otherwise
- ;; an error would be raised. This strange situation
- ;; should not arise in general and there should
- ;; probably be a better way to handle this situation.
- (if deactivate-current-input-method-function
- (deactivate-input-method)))
- (unless evil-no-display
- (evil-refresh-cursor ',state)
- (evil-refresh-mode-line ',state)
- (when (called-interactively-p 'any)
- (redisplay)))
- ,@body
- (run-hooks ',entry-hook)
- (when (and evil-echo-state
- arg (not evil-no-display) ,message)
- (if (functionp ,message)
- (funcall ,message)
- (evil-echo "%s" ,message))))))))
-
- (evil-set-command-property ',toggle :keep-visual t)
- (evil-set-command-property ',toggle :suppress-operator t)
-
- (evil-define-keymap ,keymap nil
- :mode ,mode
- :func nil)
-
- (evil-define-keymap ,local-keymap nil
- :mode ,local
- :local t
- :func nil)
-
- ',state)))
-
-(provide 'evil-core)
-
-;;; evil-core.el ends here