Emacs + Evil = ecumenicalism
Early on in the history of the editor wars, adherents of Emacs banded
together to form a religion. As a result of this ecclesiastical schism, vi
came to be known as "the editor of the beast". It comes as no surprise that
something denounced by a particular religious sect turns out, in reality, to
be very awesome, useful, and generally good for society.
I am talking, of course, about the power of modal editing.
The ubiquitous, second-nature process of reading and writing belies the fact
that working with text is a subtle, complex, and multifaceted task.
Moreover, in our interactions with text we typically spend the majority of
the time reading, searching, and editing. This is doubly true for structured
text, such as Wikipedia markup or computer programs. Key-chord-based text
editors make this process needlessly slow and inconvenient.
But this post isn't just another vi/Vim paean. This post is about Evil, the
Extensible Vi Layer for Emacs written by Frank Fischer and Vegard Øye.
It allows to combine the incredible power of Emacs with
the ergonomics, terseness, and efficiency of Vim, and if you are an Emacs
user, you should check it out. If you are a Vim user, here's your chance to
switch to a better editor without having to retrain the muscle memory.
Currently, most Evil users seem to come from the Vim camp. As a result,
Evil's defaults skew towards Vim behavior. This makes it somewhat difficult
to adopt for us Emacs users: we have to face the double task of learning
Vim, as well as figuring out how to make the modal editing paradigm work
smoothly with the existing Emacs usage patterns. As someone that has done
this journey, I would like to share some tips.
So let's assume you successfully installed Evil. Great! Now, what exactly
did you get yourself into? Well, effectively, all Evil does is redefine the
key bindings depending on the context, or "state". As a user, you will
primarily deal with three states: normal (for navigating/editing), insert
(for typing characters), and motion (used for read-only buffers such as
help). There is also the Emacs state, which simply gives you familiar Emacs
behavior, the same as what you'd get if you turned off Evil.
One option, therefore, is to use Evil's Emacs state as a default, using =C-z=
to toggle between it and the normal state. However, I don't recommend this
approach, as one would be tempted to revert to old Emacs habits, thereby
missing 90% of the awesomeness Evil provides. Let's just plunge in:
(setq evil-default-state 'normal)
Now do a Google search for a good Vim tutorial, and experiment lots!
Issues you might encounter as an Emacs user
Insert state clobbers some useful Emacs keybindings
The solution to this is to clear the insert state keymap, leaving you with
unadulterated Emacs behavior. You might still want to poke around the
keymap (defined in =evil-maps.el=) and see if you want to salvage some useful
insert state command by rebinding them to keys of your liking. Also, you need
to bind =ESC= to putting you back in normal mode. So, try using this
code. With it, I have no practical need to ever switch to Emacs state.
(setcdr evil-insert-state-map nil)
(read-kbd-macro evil-toggle-key) 'evil-emacs-state)
I want the keybinding /X/ to work in Evil!
You can always override or add bindings to any Evil state. Just use
something like this:
(define-key evil-normal-state-map "\C-r" 'isearch-backward)
(define-key evil-normal-state-map "\C-e" 'evil-end-of-line)
(define-key evil-motion-state-map "\C-e" 'evil-end-of-line)
Evil bindings for key /X/ shadow the default bindings in mode /Y/
A common culprit here is the =return= key, which is ordinarily bound to
=evil-ret= (a command that, as of this writing, doesn't know about what
return is supposed to do in a current mode).
A crude but effective solution is to change Evil bindings on a per-state,
per-mode basis, like so:
(evil-declare-key 'motion completion-list-mode-map (kbd "<return>") 'choose-completion)
(evil-declare-key 'motion completion-list-mode-map (kbd "RET") 'choose-completion)
(evil-declare-key 'motion browse-kill-ring-mode-map (kbd "<return>") 'browse-kill-ring-insert-and-quit)
(evil-declare-key 'motion browse-kill-ring-mode-map (kbd "RET") 'browse-kill-ring-insert-and-quit)
(evil-declare-key 'motion occur-mode-map (kbd "<return>") 'occur-mode-goto-occurrence)
(evil-declare-key 'motion occur-mode-map (kbd "RET") 'occur-mode-goto-occurrence)
Note that I am using both the =RET= and =<return>= forms to make sure the key
works both in terminal and under X.
This issue becomes more tricky in "read-only" modes that use letter keys for
navigation (e.g. info, dired, ibuffer). It's not obvious to me what the best
practices are for such modes. Should the Emacs bindings shadow Evil normal
state? Does insert or normal state make more sense as the default? Currently,
I don't have clear-cut answers.
I don't want Evil to ever touch keybinding /X/
This can too be arranged! Define the following function:
(defun evil-undefine ()
(call-interactively (key-binding (this-command-keys)))))
Now, to make sure that Evil's normal state never touches =TAB=, just wire
this fall-through binding like so:
(define-key evil-normal-state-map (kbd "TAB") 'evil-undefine)
Mode /X/ should start in normal state, but mode /Y/ should start in insert state
(evil-set-initial-state mode-x 'normal)
(evil-set-initial-state mode-y 'insert)
Doing a copy via M-w loses a character
If you are running Emacs 24, see if you are being affected by this bug: (https://bitbucket.org/lyro/evil/issue/110/kill-ring-save-doesnt-work-properly-in).
My selection is off by a character
This can be somewhat subtle, as Emacs and Vim have different defaults
regarding the visual/transient mark. In particular, in Emacs, the last selected
character is always the one before the point. This makes operating on text
from left to right and from right to left asymmetrical: if you wanted to
select the string =123=, and your cursor is on the 1, you press
=C-SPC,C-3,C-f=. However, if your cursor is on the 3, you /first have to
move it past the 3/, and only then do =C-SPC,C=3,C-b=. In Vim, on the other
hand, the last selected character is always under point, so you'd just do =v2l= if
the cursor is no the 1, or =v2h= if the cursor is on the 3. The fact that in
Emacs, you always deal with this asymmetry, whether you are aware of it or
not, can lead to selections (or, in general, cursor positioning) being off by
a character when you use commands that are, conceptually, the same in Emacs
and Vim, but differ in their treatment of character under point vs character
before point. The good news is that Evil provides the following setting,
which might help with correct character selection at beginnings and ends of
(setq evil-want-visual-char-semi-exclusive t)
You might also look into changing Vim's default behavior whereby the cursor
moves back one space (although this behavior makes a fair amount of sense (http://unix.stackexchange.com/questions/11402/why-does-esc-move-the-cursor-back-in-vim)).
For this, you could look into
(setq evil-move-cursor-back nil) ;;and maybe also:
(setq evil-highlight-closing-paren-at-point-states nil)
You could also try playing with =(setq evil-visual-char 'exclusive)=, but I
personally see no good reason to use that setting. In my own configuration,
I just turned on =evil-want-visual-char-semi-exclusive= and it's been working
well for me thus far.
Favorite Vim / Evil usage patterns
I will keep this section brief, since I am relatively new to the Vim way of
Here are a few things that I have found handy or elegant in my 1.5
months with Evil. Some of these are pretty trivial, and some have Emacs
equivalents (either built-in or via add-on Elisp). However, everything just
feels cleaner without having to press =C= or =M= all the time.
* Searching via =/=
We all know that isearch is the way to navigate text in Emacs buffers, and
=/= is very similar to isearch. Because =/= is ergonomically superior to
=C-s=, I find myself using the search-to-navigate paradigm much more than
with my old Emacs setup.
* Block selection
In Vim/Evil, =C-v= allows you to select rectangles and do things like insert
or paste text before every line in a rectangle. In Emacs, CUA rectangle mode
does something similar, but you have to enable it. In Evil, it comes
* Combining search, motion, deletion, and selection commands
Such combinations are very powerful. Here are a few examples to give you a
flavor of what I am talking about:
- =d/foo[RET]=: deletes from point to string "foo"
- =dfa=: deletes from point to character "a", inclusive
- =cta=: deletes from point to character "a", exclusive, and puts you in
- =viw=: selects inside word
- =vfa;=: selects from point until the second occurrence of char "a", inclusive
- =yi)=: copy text inside parens
- =di"=: delete text inside double quotes
* Operating on surrounding delimiters (quotes, parentheses, etc.)
These are enabled by the port of Vim's surround plugin, available at https://github.com/timcharper/evil-surround
You can do things like change double quotes to single quotes via =cs"'=,
surround words with HTML tags, and if you have selected some text, surround
it with delimiters via e.g. =s)= or =s'=.
* Defining your own normal mode commands
For instance, I have =gj= mapped to =org-goto= in org-mode, and =gb= mapped
to =ido-switch-buffer=. I like those way more than the original bindings.
One can take this idea further and create keymaps starting with a dedicated
leader key (=,= has been suggested as a good leader key choice).
See [[https://gitorious.org/evil/evil/merge_requests/12][this discussion]] for more insight into how one might do this via a plugin or Emacs
built-in keymap functions.
Where to learn more
Evil is a relatively new project, and resources online are somewhat sparse at
the moment. Some of the useful resources out there are:
- http://www.emacswiki.org/emacs/Evil Evil on Emacswiki
- http://blog.gmane.org/gmane.emacs.vim-emulation Official mailing list
- Michael Markert's Evil config file (https://github.com/cofi/dotfiles/blob/master/emacs.d/cofi-evil.el is an excellent example of how one might want to customize Evil bindings and behavior, and do so in a clean
manner. There are lots of goodies there, my favorite being a method to
dynamically change the look of the cursor based on the state (insert vs
normal). (Note that the code in that file sometimes relies on external utility functions.)
- For a quick run-down of Evil's internals, consult the PDF or Info
documentation that comes with the code.
I would have very much liked to include some Vim tutorials here, for the
benefit of Emacs users, however, most of the materials that I have stumbled
upon seem to be either too basic or too advanced. If you have something that
you like, please leave a comment!
Most of the choices we make result in imperfect compromises, which makes it
easy to lapse into the "grass is greener" mentality. I am a lindy hopper that
envies salsa dancers, and a Linux/Android user that evangelizes all things
Apple. Up until recently, I've been an Emacs devotee that coveted modal
editing. Today, however, my CapsLock key is mapped to ESC instead of Ctrl,
and the world is a slightly more perfect place -- all thanks to the powers of
How to derive the volume of an n-dimensional hypersphere in 3 minutes.
1. Fly to Stockholm
2. Get online at the airport
3. Decide that official public transit directions are lame, and official bus is too expensive.
3a. Through random googling, find a Swedish transit planner
4. Board an awesome train to Uppsala. Pay $20 for a 20-minute, 20-ish mile ride. Sure NJ transit and LIRR are cheaper, but are there amazing cavernous underground stations carved out of rock?
5. Follow signage ideograms and Swedish/Russian cognates to find the way to the bus company ticket counter. Buy a ticket to Hallstavik.
6. Have lunch at Hallstavik. Gyros and fries. Yum.
7. Have a local trade you some bus coupon for 10 kr since you can only buy bus tickets via SMS.
8. Enjoy the short bus ride to Herrang
9. Set up a tent
11. Dance until 8 AM
12. Breakfast and general hanging out with people
13. Cold shower
14. Write this post to make others jealous
Today's Google Offer in Omaha - $20 for $40 at Newegg.com toward compute...
More than half a million products. 2 million real customer reviews. Top brands like Intel, Microsoft, Sony, Samsung. Detailed descriptions a
TechCrunch | Peter Thiel To The New Yorker: “I Don’t Consider [The iPhon...
Peter Thiel is a grump, but a special kind of grump. He is a dystopian utopian (if such a person can exist). The investor who wrote the firs
How to derive the volume of an n-dimensional hypersphere (the long version)
I was trying to get a better intuition for "the curse of dimensionality" in machine learning, and needed to know the volume of a unit n-sphe