Emacs/Evil-mode - A basic reference to using evil mode in Emacs.
09 Mar 2017This cheat sheet will be used to provide a very basic reference to using evil mode , vi emulation layer inside of emacs. For people who would want to still have access to base emacs lisp layer while working with vim’s modal, noun verb editing features. Since evil-mode is trying its best to emulate vim, this post might even serve as a basic reference to vim’s editing features for folks familiar emacs with cursory (no pun intended) curiosity with vim.
Introduction
Evil mode for emacs has been out for a while and is available to clone from
$ git clone https://github.com/emacs-evil/evil.git
It can be installed by cloning the above repo into your .emacs.d/site-isp
and adding it to your load-path
:
(add-to-list 'load-path "~/.emacs.d/site-lisp/evil")
(require 'evil)
(evil-mode 1)
Modes and States
If you eval the above code you will see a <N>
in the mode line. This
reflects the fact that evil mode is running in vim’s equivalent of
normal mode. To revert from normal vim emulation to emacs use
Ctrl-z
. This will put you back into emacs mode you are used
to. Typing Ctrl-z
again will take you back into evil’s vim normal
state. Other list of modes include:
1. `<N>` - Normal state - for most vims commands.
2. `<V>` - Visual state - Vim's rich selection sate.
3. `<R> - Replace state
4. `<M>` - Motion state
5. `<E>` - Emacs state - will be receptive to usual emacs key bindings in the buffer.
Each state has will have its own customization and bindings. Most of
the bindings can be seen in evil-maps.el
.
Some of the key maps are
evil-emacs-state-map
evil-ex-completion-map
evil-inner-text-objects-map
evil-insert-state-map
evil-motion-state-map
evil-normal-state-map
evil-operator-state-map
evil-outer-text-objects-map
evil-read-key-map
evil-replace-state-map
evil-visual-state-map
evil-window-map
You can checkout evil-commands.el
for list of examples of commands
that have already been defined. As you begin to look at the custom
macro evil-define-motion
used while defining motion types you will
see most of the commands take in a count for the number of times the
motion needs to be performed. This is a basic implementation of vim’s
numeric parameterization of motion commands See references.
;; Simpler way to exit to normal states than pressing <ESC>
(define-key evil-visual-state-map (kbd "C-c") 'evil-normal-state)
(define-key evil-insert-state-map (kbd "C-c") 'evil-normal-state)
(define-key evil-motion-state-map (kbd "C-e") nil)
(define-key evil-visual-state-map (kbd "C-c") 'evil-exit-visual-state)
Additional plugins
While base evil is fairly feature complete I have found the following additional plugins to be useful at times.
Key chord mode
Key chord mode will make it easier to jump between modes which becomes important when we enter the world of modal editing.
(require 'key-chord)
(key-chord-mode 1)
(require 'key-seq)
(key-chord-mode 1)
(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)
(key-chord-define evil-normal-state-map "jk" 'evil-force-normal-state)
(key-chord-define evil-visual-state-map "jk" 'evil-change-to-previous-state)
(key-chord-define evil-insert-state-map "jk" 'evil-normal-state)
(key-chord-define evil-replace-state-map "jk" 'evil-normal-state)
(key-chord-define evil-normal-state-map "ee" 'evil-emacs-state)
(key-chord-define evil-insert-state-map "ee" 'evil-emacs-state)
(key-chord-define evil-emacs-state-map "ee" 'evil-normal-state)
This will allow one to jump back into normal mode using the jk
keys
hit in quick succession. Also hitting ee
keys quickly will allow one
to exit and leave default emacs mode in the buffer quickly.
Vim Basics
For people new to vim’s philosophy of using here is a quick recap.
Motion Commands
Character Level Motion :
+---+------+
| h | left |
| j | down |
| k | up |
| l | right|
+---+------+
Are single character motions actions. All of which can be
prefixed with numeric arguments. Thus 7j
will move down 7
lines in normal mode.
Screen Level Motions :
+---------+------------------+
| Ctrl-F | back screen |
| Ctrl-f | forward screen |
| Ctrl-B | page down |
| Ctrl-b | page up |
| Ctrl-U | half page up |
| Ctrl-D | half page down |
| <n>G | goto line n |
| gg | goto first line |
| z. | center to point |
| zz | center to point |
| zt | center point top |
| zb | center bottom |
+---------+------------------+
Motions can also be performed at the page level using Ctrl-F
will move
back one screen full. Where as Ctrl-U
will move up one half page-full.
Most motion commands can be given as targets to action commands like copy, paste
delete. Thus yCtrl-F
will copy a screen full of text back from the cursor position.
Additionally z.
, zt
, zb
can be used to center and scroll screen
top and bottom.
Line Level Motions:
+---+-----------------------------+
| 0 | beginning of line |
| ^ | beginning of non black line |
| $ | end of line |
+---+-----------------------------+
To operate on current line some useful commands are shown
above. For example y^
will copy the line to beginning current
line. and y$
will copy it to the end of the current line. yy
will copy the current line.
Line forward and backwards
| f{char} | forward search in line for {char} |
| F{char} | backward search in line for {char} |
| t{char} | forward search till {char} in line |
| t{char} | forward search till {char} in line |
| T{char} | backward search till {char}in line |
| ; | repeat last search forward |
| , | repeat last search backward |
While working within lines it may be convenient to jump forward to a
character. 2f,
will jump forward to the second comma in a
line. Previous searches can be repeated forward and backwards using
comma and semicolons.
Sentence and Paragraph Motions
| ( | sentence back |
| ) | sentence forward |
| { | paragraph forward |
| | | paragraph backward |
All sentence and paragraph motions can take in numeric arguments.
Search and Replace:
| / | search forward |
| ? | search backwards |
| n | continue search forward |
| N | continue search backward |
| :%/<pat>/<pat2>/gc | search and replace |
/
and ?
allows you to search forward and backwards also allowing
you to perform actions as you search. So y?##
will copy text till
previous heading in markdown and P
will allow you to paste after
current cursor position. One can perform search and replace using
:%/<pat1>/<pat2>/g
which will replace every occurance of regex
<pat1>
with <pat2>
.
Marks
| m{char} | store current position in {char} register |
| '{char} | jump to position stored in {char} register |
Much like emacs marks allow one to jump back and forth between a
history of positions. ma
for example will set a mark in register
named a
. One can then yank from current line to mark using y'a
.
Notice the usage of single apostrophe works line wise whereas using
back-quote will act line wise.
Macro recordings
| q{char} | record following commands in {char} register |
| @{char} | re-run recorded commands from {char} register|
| . | re-run last macro |
Much like emacs macros qa
can start recording a macro into register
a
. After you are done recording press q
to indicate its end. @a
can then be used to re-run recorded macro. .
can be used to repeat
last run commands.
Why bother?
The basic idea is to create as rich of a structured language for editing allowing us to instruct the editor at the level of intentionality using composable editing abstractions. To get a more visual guide to possibilities of evil mode checkout some of thoughtbot’s evil mode/vim videos or bailey ling’s guide. Another extremely useful resource is the vim reference manual which seems to be written in a very deliberate manner by Bram Moolenaar available here.