Evil is an extensible vi layer for Emacs. It provides Vim features like Visual selection and text objects, and is the successor to Vimpulse and vim-mode.
Current stable version: 1.0.1
1. ELPA: The latest stable version is available from the Marmalade repository, the current development version from MELPA. Both can be installed by
M-x package-install RET evil RET
2. el-get: Evil can be downloaded and installed with:
M-x el-get-install RET evil RET
Alternatively, Evil lives in a Git repository. To download Evil, do:
git clone git://gitorious.org/evil/evil.gitIf you don’t have Git, just head over to Gitorious and click the “Download master as tar.gz” link (extract with tar -xzf master.tar.gz).
Move Evil to ~/.emacs.d/evil (or somewhere else in your load-path). Then add the following lines to ~/.emacs:
(add-to-list 'load-path "~/.emacs.d/evil") ; only without ELPA/el-get (require 'evil) (evil-mode 1)
If your .emacs file has a custom-set-variables section, you should place it after Evil.
Evil requires undo-tree.el in the load-path for linear undo and undo branches. Otherwise, Evil uses regular Emacs undo.
A brief PDF manual is available in the /doc subdirectory.
If you have bug reports or suggestions, please submit them at the BitBucket bug tracker (open for all).
If you want to use the full power of Emacs in Vim-like ways (ie using short key sequences near home row instead of Control-Shift-Nonsense), this section provides some guidance. This guide assumes you’ve read the Evil manual sections “Modes and states” and “Keymaps”.
There are Emacs modes that provide their own single letter key bindings, independent of Evil. BufferMenu, Ediff, and Edebug are a few examples. By default, Evil allows these modes’ keymaps to override Evil’s. To change this behavior, customize the evil-overriding-maps and evil-intercept-maps variables. If you set these two to nil, then the active Evil keymaps have precedence over other active keymaps. For example, without customization, inputting n in the Buffer Menu will call a Buffer Menu command to move down a line. If Buffer-menu-mode-map is removed from evil-overriding-maps, then n will invoke Evil’s command to go to the next search term.
With these customizations made, there are still some familiar Evil key bindings that are unavailable in Buffer Menu. These pertain to commands that edit raw text – disabled because raw text editing doesn’t make much sense in the Buffer Menu. This is realized by the Buffer-menu-mode entry in the evil-motion-state-maps variable. Because the evil-normal-state-map is inactive in motion state, Buffer Menu commands like x and d are directly available.
You may still wish to use a mode’s key bindings, if you decided to remove its keymap from evil-overriding-maps or evil-intercept-maps. Evil defines the \ command to temporarily interpret the subsequent Key Sequence in the Emacs state. If you wish to use Buffer Menu’s b command, you can do so with two key strokes: \b . This is pretty reasonable in most cases, but if you want to have a one letter key binding you can add it specifically with the evil-define-key function.
While Buffer Menu comes up in motion state, other modes such as Ediff come up in Emacs state where all Evil keymaps are inactive. You may change a mode’s initial state by customizing the evil-*-state-modes variables. The Minibuffer is an exception: it is always in Emacs state regardless of these variables. To move all elements of evil-emacs-state-modes to evil-motion-state-modes:
(setq evil-motion-state-modes (append evil-emacs-state-modes evil-motion-state-modes)) (setq evil-emacs-state-modes nil)
It is common for Emacs modes like these to define key bindings for RET and SPC. Since these are motion commands, Evil places its key bindings for these in evil-motion-state-map. However, these commands are fairly worthless to a seasoned Vim user, since they do the same thing as j and l commands. Thus it is useful to remove them from evil-motion-state-map so as when modes define them, RET and SPC bindings are available directly.
(defun my-move-key (keymap-from keymap-to key) "Moves key binding from one keymap to another, deleting from the old location. " (define-key keymap-to key (lookup-key keymap-from key)) (define-key keymap-from key nil) ) (my-move-key evil-motion-state-map evil-normal-state-map (kbd "RET")) (my-move-key evil-motion-state-map evil-normal-state-map " ")
Key Translations are another useful Emacs feature which allows one Key Sequence to translate to another prior to Emacs’ process of Key Lookup in the active keymaps. One limitation is an Evil bug that prevents Key Translations taking effect in the operator state.
An example of defining a Key Translation: You could translate ch to C-h and cx to C-x . To do this, make c a Prefix Key so as Key Lookup does not end on the c input alone.
(define-key evil-normal-state-map "c" nil) (define-key evil-motion-state-map "cu" 'universal-argument)
The second line automatically made c a Prefix Key, and its binding was somewhat arbitrary. Now we define the Key Translations:
(define-key key-translation-map (kbd "ch") (kbd "C-h")) (define-key key-translation-map (kbd "cx") (kbd "C-x"))
Note that this won’t interfere with insert state because c is bound to self-insert-command, and the evil-motion-state-map defining c as a Prefix Key is inactive.
The approach above to Key Translations has a couple of disadvantages: it won’t allow single letter Key Translations, and if a mode offers its own binding for ch or cx, it is unavailable to you (not even via \). To resolve these issues, you’ll need to use the Emacs pretest 24.2.90 release which will become Emacs 24.3 .
In addition to updating your Emacs version, you’ll have to enable lexical binding. Doing so might render other Elisp in your init file inoperable if it relies on dynamic binding. Put this on the very first line of your init file:
;; -*- lexical-binding: t -*-C-x is a common Prefix Key and it is extremely convenient to bind to a single letter near home row. Let’s translate ch to C-h and g to C-x as follows:
;; Note: lexical-binding must be t in order for this to work correctly. (defun make-conditional-key-translation (key-from key-to translate-keys-p) "Make a Key Translation such that if the translate-keys-p function returns true, key-from translates to key-to, else key-from translates to itself. translate-keys-p takes key-from as an argument. " (define-key key-translation-map key-from (lambda (prompt) (if (funcall translate-keys-p key-from) key-to key-from)))) (defun my-translate-keys-p (key-from) "Returns whether conditional key translations should be active. See make-conditional-key-translation function. " (and ;; Only allow a non identity translation if we're beginning a Key Sequence. (equal key-from (this-command-keys)) (or (evil-motion-state-p) (evil-normal-state-p) (evil-visual-state-p)))) (define-key evil-normal-state-map "c" nil) (define-key evil-motion-state-map "cu" 'universal-argument) (make-conditional-key-translation (kbd "ch") (kbd "C-h") 'my-translate-keys-p) (make-conditional-key-translation (kbd "g") (kbd "C-x") 'my-translate-keys-p)
If another keymap defines a binding for “ch”, you can access it with \ch , because my-translate-keys-p returns false in the Emacs state, resulting in a Key Translation of “ch” to itself.
In non insert state, you can now type “g3” to split-window-right, “go” to move to the other window, etc. This code is written to only translate the key when it is the first of a Key Sequence, so as a binding like “sg” won’t translate into “s C-x”.
If there are Evil g commands you miss, just redefine them for C-x:
(define-key evil-motion-state-map "\C-x\C-]" 'find-tag)See evil-maps.el to find all of the Evil g commands.
To continue the pattern of translating “c<char>” to “C-<char>”:
(when (fboundp 'cl-loop) ;; cl-loop iterates from ASCII '!' to ASCII '~'. (cl-loop for ascii-code-i from 33 to 126 by 1 do (make-conditional-key-translation (kbd (format "c%c" ascii-code-i)) (kbd (format "C-%c" ascii-code-i)) 'my-translate-keys-p)))
You can define any key sequence you like for escaping from Evil insert state back to normal state. C-c is one of the options available in Vim by default, but Evil cannot define C-c this way because Emacs coding standards require packages to reserve C-c for the user.
The following Elisp shows how to define C-c as an escape key, using a Key Translation.
;;; C-c as general purpose escape key sequence. ;;; (defun my-esc (prompt) "Functionality for escaping generally. Includes exiting Evil insert state and C-g binding. " (cond ;; If we're in one of the Evil states that defines [escape] key, return [escape] so as ;; Key Lookup will use it. ((or (evil-insert-state-p) (evil-normal-state-p) (evil-replace-state-p) (evil-visual-state-p)) [escape]) ;; This is the best way I could infer for now to have C-c work during evil-read-key. ;; Note: As long as I return [escape] in normal-state, I don't need this. ;;((eq overriding-terminal-local-map evil-read-key-map) (keyboard-quit) (kbd "")) (t (kbd "C-g")))) (define-key key-translation-map (kbd "C-c") 'my-esc) ;; Works around the fact that Evil uses read-event directly when in operator state, which ;; doesn't use the key-translation-map. (define-key evil-operator-state-map (kbd "C-c") 'keyboard-quit) ;; Not sure what behavior this changes, but might as well set it, seeing the Elisp manual's ;; documentation of it. (set-quit-char "C-c")
In Emacs, C-g is somewhat analogous to what C-c was in Vim. And since C-c is more ergonomic than C-g, I decided it’s useful and intuitive to translate C-c to C-g if I’m already escaped out of insert state.
Emacs defines C-c as a useful global prefix key. In order to use it, you may define a Key Translation as described in the Key Translation section. Emacs does not apply Key Translation twice so if you define a Key Translation from cc to C-c, cc will not escape but access the global prefix key for C-c as desired.
Another way is to use keychords.el as a basis for an escape key sequence. For example, this Elisp defines ,, as an escape key (very convenient for bépo layout, rather not for qwerty…):
(key-chord-define evil-normal-state-map ",," 'evil-force-normal-state) (key-chord-define evil-visual-state-map ",," 'evil-change-to-previous-state) (key-chord-define evil-insert-state-map ",," 'evil-normal-state) (key-chord-define evil-replace-state-map ",," 'evil-normal-state)
In Vim I like to have the status line change color when in insert mode and when the buffer is dirty (needs saving). It’s much easier to do in Evil than it is in Vim itself.
;; change mode-line color by evil state (lexical-let ((default-color (cons (face-background 'mode-line) (face-foreground 'mode-line)))) (add-hook 'post-command-hook (lambda () (let ((color (cond ((minibufferp) default-color) ((evil-insert-state-p) '("#e80000" . "#ffffff")) ((evil-emacs-state-p) '("#444488" . "#ffffff")) ((buffer-modified-p) '("#006fa0" . "#ffffff")) (t default-color)))) (set-face-background 'mode-line (car color)) (set-face-foreground 'mode-line (cdr color))))))
It would be nice with a brief overview over the objectives and difference to Viper.
The first thing I missed of Vim were the tabs. With elscreen.el and its dependencies installed, the following code emulates part of the Vim behaviour:
(load "elscreen" "ElScreen" t)
(define-key evil-normal-state-map (kbd "C-w t") 'elscreen-create) ;creat tab (define-key evil-normal-state-map (kbd "C-w x") 'elscreen-kill) ;kill tab
(define-key evil-normal-state-map "gT" 'elscreen-previous) ;previous tab (define-key evil-normal-state-map "gt" 'elscreen-next) ;next tab