Quick Start emacs with evil

Jan. 13, 2018

This post is intended to present a minimal example of setting up emacs with evil as well as a few evil plugins.

The emacs ecosystem is constantly changing, and evil and its plugins, being part of that ecosystem, are changing as well. Hence, the snippet below will be updated as I see fit.

Care is taken to ensure the evil packages are lazy-loaded.

  ;; load package manager, add the Melpa package registry
  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
  (package-initialize)

  ;; bootstrap use-package
  (unless (package-installed-p 'use-package)
    (package-refresh-contents)
    (package-install 'use-package))
  (require 'use-package)

  (use-package evil
    :ensure t
    :defer .1 ;; don't block emacs when starting, load evil immediately after startup
    :init
    (setq evil-want-integration nil) ;; required by evil-collection
    (setq evil-search-module 'evil-search)
    (setq evil-ex-complete-emacs-commands nil)
    (setq evil-vsplit-window-right t) ;; like vim's 'splitright'
    (setq evil-split-window-below t) ;; like vim's 'splitbelow'
    (setq evil-shift-round nil)
    (setq evil-want-C-u-scroll t)
    :config
    (evil-mode)

    ;; vim-like keybindings everywhere in emacs
    (use-package evil-collection
      :after evil
      :ensure t
      :config
      (evil-collection-init))

    ;; gl and gL operators, like vim-lion
    (use-package evil-lion
      :ensure t
      :bind (:map evil-normal-state-map
                  ("g l " . evil-lion-left)
                  ("g L " . evil-lion-right)
                  :map evil-visual-state-map
                  ("g l " . evil-lion-left)
                  ("g L " . evil-lion-right)))

    ;; gc operator, like vim-commentary
    (use-package evil-commentary
      :ensure t
      :bind (:map evil-normal-state-map
                  ("gc" . evil-commentary)))

    ;; gx operator, like vim-exchange
    ;; NOTE using cx like vim-exchange is possible but not as straightforward
    (use-package evil-exchange
      :ensure t
      :bind (:map evil-normal-state-map
                  ("gx" . evil-exchange)
                  ("gX" . evil-exchange-cancel)))

    ;; gr operator, like vim's ReplaceWithRegister
    (use-package evil-replace-with-register
      :ensure t
      :bind (:map evil-normal-state-map
                  ("gr" . evil-replace-with-register)
                  :map evil-visual-state-map
                  ("gr" . evil-replace-with-register)))

    ;; * operator in vusual mode
    (use-package evil-visualstar
      :ensure t
      :bind (:map evil-visual-state-map
                  ("*" . evil-visualstar/begin-search-forward)
                  ("#" . evil-visualstar/begin-search-backward)))

    ;; ex commands, which a vim user is likely to be familiar with
    (use-package evil-expat
      :ensure t
      :defer t)

    ;; visual hints while editing
    (use-package evil-goggles
      :ensure t
      :config
      (evil-goggles-use-diff-faces)
      (evil-goggles-mode))

    ;; like vim-surround
    (use-package evil-surround
      :ensure t
      :commands
      (evil-surround-edit
       evil-Surround-edit
       evil-surround-region
       evil-Surround-region)
      :init
      (evil-define-key 'operator global-map "s" 'evil-surround-edit)
      (evil-define-key 'operator global-map "S" 'evil-Surround-edit)
      (evil-define-key 'visual global-map "S" 'evil-surround-region)
      (evil-define-key 'visual global-map "gS" 'evil-Surround-region))

    (message "Loading evil-mode...done"))