Quick guide for coming to the dark side (a.k.a. painless Vim to Emacs transition)
Ranting
Being an avid (neo)vim user for the last two years and a half, I couldn’t envision myself using anything else. Vim has everything: fast start-up times, sane keybindings, an infinite amount of plugins, … But as everything in life it doesn’t come without flaws. The vim community is already splitting, as neovim slowly diverges from its predecessor. Because of the Lua scripting present in neovim, new plugins may not be compatible with original vim. As much as Vim is trying to catch up with NeoVim, I don’t see Bram Moolenaar introducing Lua scripting inside Vim.
But, although Vim is chasing NeoVim, the latter is really chasing Emacs. The ground breaking features once introduced in NeoVim such as async, terminal emulation and scripting (through Lua) were already features of Emacs. And Emacs still offers unique utilities such as magit, org-mode or TRAMP, and other excellent quality packages of which we will talk later.
Emacs is also constantly evolving on its own, bringing exciting new features to every new release. The experimental feature (at the time of writing) that made me give Emacs a second try was gccemacs. The concept is simple, instead of just compiling elisp (the Emacs scripting language) to bytecode, you could just use gcc to compile every piece of elisp code into native machine code. That way, Emacs becomes blazingly fast, the only tradeoff being a bit longer installation process.
Despite being an experimental feature, I’ve been using gccemacs
consistently for one month and never ran into a problem (just saw some
compilation warnings when installing packages but nothing
important). What’s more, thanks to the way Emacs is designed, my
single init.el
file worked seamlessly across five different Linux
installations, from Ubuntu 16 to Arch, And even on a MacOS High Sierra
virtual machine. This is one thing that I couldn’t do with NeoVim, as
I had to download a lot of dependencies, which was a nightmare
especially in Ubuntu 16 for being an ‘old’ distro. A lot of people
fall for the ‘bloat’ meme when talking about Emacs, and although it is
slower (not gccemacs in my experience) and consumes more memory (not
that much compared to NeoVim with coc.nvim), the Emacs packages that I
use do not need external tools such as Python or NodeJS. And I have the
same functionality if not more.
But enough ranting, in this post I’d like to share the packages that I’ve been recollecting that replicate (and enhance) the workflow I had with vim. I hope this blog post can serve as a quick start for someone who is as lost as I first was.
Installation
You can install Emacs from your package manager of preference. If you want to try out gccemacs, you’ll have to follow the instructions here. You’ll most likely need to compile Emacs from source, but it’s not very complicated.
Package manager
Next comes the package manager. Emacs lets you manage all your packages by hand, but if you are a sane person, you’d like some sort of package management. straight.el has lots of interesting features that contribute to reproducibility and hackability, but one feature that doesn’t get mentioned right away is that it automatically detects if you are using gccemacs, and if so, it autocompiles all your packages in a non blocking way. This is very sweet, as you can use your packages while they are being compiled.
Another feature I liked was the ability to do a shallow clone of the packages, thus saving a lot of space. But at the time of writing this feature is still experimental and I experienced some problems with it, so I did not enable it.
Evil mode
The next step is Evil mode, as leaving vim does not imply leaving the ‘vim language’. Evil mode is an emulation layer of vim, that makes emacs behave like vim in almost every part of the editor. You’ll need to learn some basic Emacs keybindings tough, like ‘C-g’ for exiting. In my config I have the following Evil packages:
- evil-snipe: same functionality as vim snake.
- evil-numbers: imitates C-a and C-x in vim, although I haven’t found an equivalent to g C-a yet.
- evil-magit: integration with magit (more on magit later).
- evil-leader: emulates vim leader, required by some other packages.
- evil-surround: the same as vim-surround. A feature I still don’t understand why it is not already part of vim.
- evil-nerd-commenter: nerd-commenter but in Emacs.
- evil-org: evil integration with org-mode.
Config for comfy programming
Since most of what I do is programming, writing LaTeX for university assignments and notes, my current config revolves around just that. I don’t want Emacs to creep up and become my Operating System (yet). So this are the packages I’m using at the moment:
- lsp-mode: Language Server Protocol client. Its configuration is minimal, as I only tell it to start when opening a C/C++ file, yet it just works. It autodetects the language server you have installed and uses it. In my case I use clangd (and clangd-8 in Ubuntu, but that also worked without the need of making an ugly alias). lsp-mode is fast and integrates very well with other packages to offer an even more complete experience.
- company: when you stop writing, a list of possible completions appears just as in vim. Can be used by lsp-mode to offer autocompletion suggestions.
- yasnippet: snippet engine. Ultisnips counterpart, although I think Ultisnips is more powerful.
- yasnippet-snippets: collection of snippets for almost every major mode.
- cmake-mode: cmake syntax highlighting. straight downloads the entire CMake respository, thus uses over 100Mb of space. I have yet to find a workaround for that.
- pdf-tools: view PDFs inside emacs, very useful when writing LaTeX.
- auctex: for editing LaTeX, provides complete compilation and preview, along very useful keybinds and functionality.
Productivity
I also use other packages, both for extra functionality and for GUI goodness. For enhancing your workflow I recommend the following:
- helm: fuzzy finder in Emacs. Comes in very handy when selecting between a lot of options, such as when M-x’ing.
- helm-projectile: helm integration with projectile.
- magit: ‘git porcelain’. The absolute best git interface out there, there is no vim equivalent. You can do almost every git command with a few keystrokes, as well as selecting graphically the parts of a file that you want to stage. It also is able to show you the commands it uses under the hood so you can learn them and use them when outside Emacs.
- projectile: makes Emacs project-aware. Thus you can change between projects, find files in projects, compile a project with its own command and a big etcetera.
- general.el: a package that allows to define your key bindings in a unified way. Very powerful.
- avy: move anywhere you see on the screen with few
keystrokes. Personally, I only use
avy-goto-char-timer
, which lets me type as much as I want and when I stop it lets me select the matching strings. - which-key: one of the things that I love about Emacs is its self
documentation. But when
C-h k
is not enough, which-key has you covered. If you start your command but don’t remember the next keystrokes, just wait a second and which-key will show you all the possible commands that you can do.
GUI enhancements
The GUI part is the most subjective, and that’s why I left it last. The packages I use are:
- dashboard: you are welcomed by a clean dashboard, where you have quick access to your last edited files and projects, your org-agenda, …
- all-the-icons: simply installs icons. Farewell font-awesome and powerline.
- telephone-line: a lightweight and extensible modeline, with Evil support and other niceties.
- doom-themes: collection of famous color schemes.
- dimmer: dim the windows that are not focused.
Conclusion
I am very surprised by how much Emacs can be made to behave like Vim, there is virtually no difference.
If you don’t like slow start-up times, you can just make your computer
run emacs --daemon
when logging in. This creates an Emacs server, to
which you then can connect running emacsclient -c
. That way you can
‘open’ Emacs almost instantaneously.
There is room for lots of improvements, as I only have been using Emacs for less than a month. But with this configuration of less than 300 lines I am pretty comfortable.