Evil is an extensible vi layer for Emacs. It emulates the main features of Vim, and provides facilities for writing custom extensions.

Installing

Add Melpa

1
2
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))
Code Snippet 1: melpa

with use-package

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
(use-package evil
  :ensure
  :preface
  (customize-set-variable 'evil-want-keybinding nil) ;; if using `evil-collection'
  (customize-set-variable 'evil-want-integration t) ;; if using `evil-collection'
  (customize-set-variable 'evil-undo-system 'undo-redo)
  (customize-set-variable 'evil-want-C-u-scroll t) ;; move universal arg to <leader> u
  (customize-set-variable 'evil-want-C-u-delete t) ;; delete back to indentation in insert state
      (customize-set-variable 'evil-want-C-g-bindings t)
  :config
  (evil-mode 1)
  ;; disable this when using `general.el'
  (evil-set-leader '(normal visual) (kbd "SPC"))
  (evil-set-leader '(normal visual) (kbd "C-c SPC") t))
Code Snippet 2: use-package

without use-package

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
;; Set up package.el to work with MELPA
(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))
(package-initialize)
(package-refresh-contents)

;; Download Evil
(unless (package-installed-p 'evil)
  (package-install 'evil))

;; Enable Evil
(require 'evil)
(evil-mode 1)
Code Snippet 3: without use-package

Configuration

Leader and Localleader key

This is inherited from vim1, So this isn’t really required, but as someone who use both vim and Emacs it certainly easier to memorize.

1
2
(evil-set-leader '(normal visual) (kbd "SPC"))
(evil-set-leader '(normal visual) (kbd "C-c SPC") t)
Code Snippet 4: leader and local leader key

The first line will set the <leader> key, while the latter will set the <localleader>.

additional packages

evil-collection

Setup keybindings for evil-mode

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
(use-package evil-collection
  :ensure t
  :after evil
  :init
  (evil-collection-init)
  :custom
  (evil-collection-setup-minibuffer t)
  (evil-collection-calendar-want-org-bindings t)
  :config
  (with-eval-after-load 'bookmark
    (evil-collection-bookmark-setup))
  (with-eval-after-load 'pass
    (evil-collection-pass-setup))
  (with-eval-after-load 'man
    (evil-collection-man-setup))
  (with-eval-after-load 'org
    (evil-collection-org-setup))
  (with-eval-after-load 'corfu
    (evil-collection-corfu-setup))
  (with-eval-after-load 'embark
    (evil-collection-embark-setup))
  (with-eval-after-load 'epa
    (evil-collection-epa-setup))
  (with-eval-after-load 'nov
    (evil-collection-nov-setup))
  (with-eval-after-load 'eww
    (evil-collection-eww-setup))
  (with-eval-after-load 'emms
    (evil-collection-emms-setup)
    (evil-collection-emms-browser-setup)))
Code Snippet 5: evil-collection

Notes:

  • evil-collection assumes evil-want-keybinding is set to nil and evil-want-integration is set to t before loading evil and evil-collection. Note some other packages may load evil (e.g. evil-leader) so bear that in mind when determining when to set the variables.

abbrev-mode

Not a mandatory package, but it’s built-in into Emacs so it nice to have,

1
2
(use-package abbrev
  :ensure nil)
Code Snippet 6: abbrev-mode

evil-terminal-cursor-changer

Change the cursor shape and color when in terminal.

1
2
3
4
5
(unless (display-graphic-p)
  (use-package evil-terminal-cursor-changer
    :ensure t
    :config
    (evil-terminal-cursor-changer-activate)))
Code Snippet 7: evil-terminal-cursor-changer

evil-args

Motions and text objects for delimited arguments in Evil, the extensible vi layer for Emacs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
(use-package evil-args
  :after evil
  :ensure t
  :hook (emacs-lisp-mode . +config/evil-args-lisp)
  :config
  (define-key evil-inner-text-objects-map "a" 'evil-inner-arg)
  (define-key evil-outer-text-objects-map "a" 'evil-outer-arg)
  (define-key evil-normal-state-map "L" 'evil-forward-arg)
  (define-key evil-normal-state-map "H" 'evil-backward-arg)
  (define-key evil-motion-state-map "L" 'evil-forward-arg)
  (define-key evil-motion-state-map "H" 'evil-backward-arg)
  (define-key evil-normal-state-map "K" 'evil-jump-out-args)
  (defun +config/evil-args-lisp ()
    (setq-local evil-args-delimiters '(" "))))
Code Snippet 8: evil-args