I currently use a highly customized Sublime Text 3 as my text editor for
almost all programming. However, people are often surprised to learn that I’ve
used Vim for 6 months, Emacs/Spacemacs for 10 months (including much elisp
hacking) and Atom for a month, yet I still prefer Sublime.
This post explains my journey between text editors, what I learned, what I
like and dislike about each of them, and why in the end I’ve chosen Sublime
(for now). Most detailed is my reasoning for abandoning Spacemacs, despite
being a top contributor and power user, although many of
my criticisms of Vim also apply to Spacemacs (and vice versa).
The Early Days: Textmate & Sublime Text 2
My text editor when I first learned programming was Textmate, and I stuck with
it for a few years (I forget how many) before I at some point switched to
Sublime Text 2’s trial, and then paid for a license.
Back then I only used the basics: syntax highlighting, find/replace,
autocomplete, file tree… I didn’t know any keyboard shortcuts besides
standard OS ones like copy-paste and undo. I used the mouse for all selection
and eventually learned the Sublime command pallete and “open file in project”
This setup didn’t cause me any trouble, I was productive and nothing was
painful. But, I heard tell of the true power one gained upon learning to use a
real editor like Vim or Emacs. I watched screencasts where Vim masters would
perform impressive editing operations in a couple keystrokes.
Vim: A Taste of Power
In late 2012 I switched to Vim. I learned the keyboard shortcuts with
and printed cheat sheets. I read tons of blog articles (often conflicting) on
learning and using Vim the right way.
I tried using a blank
.vimrc and building pieces from scratch making sure I
understood what each piece did each time. However, this was taking far too
long, my editor was missing key functionality from Sublime and Textmate like a
file tree, good autocomplete, open in project, and support for languages I
used. It was also ugly.
So I started using the spf13 Vim
distribution. It was nice, and had most of the features I wanted. You can
still find my modified spf13-based vimrc here.
I was reasonably happy with this setup and continued using it for over 6 months.
However, there were many pain points. One of these was that things often
didn’t work. For example, my tab key was bound to tons of different things
like autocomplete, snippet expansion, indentation, moving between snippet
fields and inserting the literal tab character. Many of those overrode each
other in different contexts, but very often it chose the wrong one. I ended up
fixing this somewhat but not completely, but I didn’t have this issue in
Sublime because everything was designed to work together so the tab key just
always did what I wanted. Even after I fixed it, the hours I spent
diagnosing the issue, figuring out how to resolve the conflicts, implementing
it, then re-learning my muscle memory probably erased weeks of sub-
second Vim speed gains.
Another issue I had was that Vim was mouse-hostile. I was fully aware that the
Vim philosophy is to just never use the mouse. However, even with plugins like
EasyMotion and ideal vim
shortcut use the keyboard is slower for some selection tasks like selecting a
range of text far from the cursor than the mouse is. Often using Vim shortcuts
felt faster because my brain was engaged figuring out the optimal combination
of motions and looking for EasyMotion hints, but whenever I timed myself I was
consistently much slower than I was with the mouse. I’m only talking about
long range selection and cursor movement here, I totally concede that keyboard
shortcuts are better for short range movement and selection. Vim wasn’t that
bad for the mouse, but lots of plugins didn’t really work well with it and
mouse selection often worked weirdly in some states.
Back to Sublime (with a stint in Atom)
I realized that I didn’t like fighting my editor and loved the ease of use and
mouse support of Sublime. However, I also loved the power of Vim’s keyboard
model. Luckily, I could use Vintageous.
This way I could get all the power I liked about Vim with all the niceties of
In fact, Vintageous is arguably more powerful than Vim itself because it works
with multiple cursors. Using multiple cursors with Vim bindings is incredible,
it’s basically the same power as Vim macros give you, except you can compose
them on the fly with instant feedback about what commands did at each place
you wanted to use them (see gif below). I found I rarely used macros with Vim because I had to
think hard about which commands I could use that would work on every instance
and make sure I didn’t screw anything up, then figure out how I wanted to run
the macro for each location, but with Sublime it was so easy I did it all the
time. Yes, I know both Vim and Emacs have multiple cursor plugins, but they are
hacks and don’t seamlessly work with all commands and together with the mouse.
I started using Sublime as a power user’s text editor just like I had used Vim.
I learned the keyboard shortcuts, read about the functionality and installed plugins.
For a month I also tried out Atom. I pretty much replicated my Sublime Text
setup with the equivalent Atom plugins, plus some extras that only Atom offered.
However, I preferred Sublime’s speed. It wasn’t just that some editing operations
had a bit of latency, but that Sublime could offer features that Atom couldn’t
because of it’s speed. For example Sublime’s “open in project” panel instantly
previews the files as you type because it can load files in milliseconds, and search
is incremental by default.
I used this setup quite happily from mid-2013 to late-2014. However, I started
thinking about the possibility of using Emacs with
evil-mode. I’d heard its
Vim emulation was fantastic and the possibility of using Emacs lisp to craft
the perfect text editing experience given time was enticing.
I started looking around at various Emacs starter kits like Prelude
and tried out a few. I read Emacs articles, documentation and blog posts
about people’s Emacs configs. However, everything had really horrible convoluted
hard to remember keyboard shortcuts that didn’t fit well with Vim’s.
Then, I found Spacemacs. It was exactly what I was looking for. It was pretty,
integrated Vim and Emacs functionality in an interesting and discoverable way,
and promised to have everything set up to work out of the box. Somehow this
project only had around 12 stars on Github and no other contributors. It
seemed the creator had poured tons of effort into making a fantastic project,
but unlike most people’s dotfiles, he put effort and thought into making it
adaptable to individual needs and documenting how to do so. I was stunned that
this project only had ~20 stars and no other contributors.
So I downloaded it, started working on my own
.spacemacs file and joined the
Gitter chat the creator had set up. A little while later I submitted the first
contribution to the project.
Little did I know at that point that the reason it only had 20 stars was that
by chance and lots of Googling I had just stumbled upon it earlier than
everyone else. Over the coming weeks I continued tweaking and sending PRs and
other early adopters like Diego trickled in to
the chat and started contributing.
As I used Spacemacs I often noticed things that worked poorly or not at all.
I kept steadily fixing most problems I found and adding new contribution layers
for the things I wanted. When I was using Spacemacs for something where I had
already fixed most of the bugs, it was quite nice and felt efficient.
I continued using Spacemacs for around 6 months and maintained my position
as top contributor for most of that time. I helped newbies out in the Gitter
chat, triaged PRs and contributed and maintained a few different layers.
I thouroughly enjoyed contributing to Spacemacs, but nearly everything I
contributed was fixing a bug or annoyance I encountered while trying to get
something done, often writing the elisp to fix an earlier problem.
These yak-shaving tasks ranged from fixing annoying keybinding conflicts that Sublime Text had built-in logic for,
to getting LaTeX support to work. I even wrote a general mechanism for tabbing OSX windows to get around how bad all the Emacs tab/workspace plugins were.
I definitely noticed my annoyance
but I ignored it since I was having fun and I had hope that things would get better after more work.
However, after six months of making almost no progress on other projects while
discovering and fixing bugs and implementing things I missed from other
editors, I realized that there might not be an end. Part of the problem is
that I love learning new languages and doing different kinds of projects. Other
Spacemacs users might make a few fixes here and there for their primary use case,
whereas I was stuck adding support for D,
Racket, Nim and Rust and then
fixing the bugs I exposed when changing my workflow.
I think the underlying reason is that everything in Emacs, and especially
Spacemacs, is a hack. Core Emacs offers almost nothing and everything is
layered on top as ad-hoc Emacs Lisp additions. Different third-party plugins
and to some extent base functionality step on each others toes and make
conflicting assumptions all the time. One particularly bad example I ran into
is my Emacs hanging mysteriously when autocompleting on some two character
suffixes. After much searching it turned out to be a known issue where if what I was
completing looked like a domain name Emacs would try to ping it because of an
interaction between autocompletion, file finding, and remote server support.
Lack of Consistency and Discoverability
Another problem with this pile-of-hacks design is that nothing was consistent
or discoverable. Every moment I saved on common operations due to efficient
keyboard shortcuts was cancelled out by a minute spent searching for how to do
a less common operation that I didn’t do often enough to memorize.
An example of an occasional workflow I can do in Sublime is:
- Paste my clipboard into the search box.
- Search all files in a project for without regex support (useful when searching for a string with special
characters that you don’t want to escape), case insensitively.
- Narrow it down to a glob of certain files without re-typing my query.
- Edit my query slightly to refine the results, again without re-typing it.
- Replace the content of all those occurences once satisfied.
- Find “Save All” in the “File” menu to save all edits, I don’t remember the shortcut.
I tried to do this in Emacs once, and had to spend a ton of Googling and investigating
- Look up how to search in project without regex (I’ve never figured out a way to do this)
- Look up the shortcut for pasting into the minibuffer (I use Evil so I can’t use
p like usual).
- Hope that the command is Helm-based so I can edit my query, otherwise re-type everything to narrow it down.
- Look up how to replace in project without regex, oops it’s an entirely different command from searching.
- Re-enter everything into the new command and run it.
- Look up how to save all modified buffers, I don’t remember the shortcut.
Navigating Multiple Files
The last major problem I had was how difficult it was to work with code spread
across multiple files compared to Sublime Text.
There’s three main ways for working with files in Emacs: buffers, files and windows.
I tried using buffers but the problem is that buffer switching is slow and
difficult. It only takes one keystroke to switch to the most recently opened
other buffer, if you remember which that is, but switching to other buffers
requires waiting for a list to show, reading it, then multiple additional keys to select the right one.
Buffers also tend to proliferate like mad and these lists end up enormous taking many keys to filter to the right one.
They are also nearly impossible to navigate with the mouse if I’m reading code and that’s where my hand is.
Navigating using normal
helm mechanics has a similar problem:
switching is just slow. It takes a lot of key strokes, and those strokes sometimes
involve waiting for a list to appear that you can read.
Having your frame/screen split into a bunch of windows (Emacs reverses the
meaning of window and frame from every other editor) in Spacemacs has the
advantage that each window has a number on it and you can hit
SPC+9 to switch directly to them. This is great in that it is very fast and
easy to remember, find and see where you want to go and how to get there. The
problem is that you sacrifice screen real estate for every new file you work
with. I normally ameliorate this with golden-ratio
mode, which shrinks unfocused windows, but they still take up space.
With Sublime Text I use tabs, which are amazing. I can switch quickly and directly
between files with
cmd+9, see all the files I’m working with at a glance,
and navigate with the mouse if I want to. I can also easily rearrange tabs so that the
most frequently used and important files are on lower consistent numbers that I can subitize.
I can even use ZenTabs to ensure that I only
ever have my 9 most recently used files open in tabs, eliminating buffer proliferation.
Infrequent but useful actions like moving a file between windows and panes, and copying the file
path are all obvious discoverable mouse actions. The file I’m working on always fills the full screen,
unless I want to reference other code in another pane. When the file I want isn’t a tab
I can open it with “Goto Anything”, which is similar in speed to narrowing to a buffer by name.
When I want to navigate based on a project’s directory structure I have access to a fantastic
Yes, Emacs has plugins to add tabs but they are hacks. They’re ugly, slow, break when used
with other plugins, don’t have good keyboard shortcuts, and display tons of useless buffers I don’t care about.
When I watch friends and coworkers use Vim and Emacs this is the thing I
notice most. They look super efficient since they’re furiously typing things
or navigating directories, but often the file they are opening is one that
they looked at just a minute ago and would have taken me a single keystroke to
switch to. They however have to type a bunch of characters to narrow to the
buffer name. I even frequently see Vim/Emacs users opening files by
navigating directories when I would have just typed a few characters into
“Goto Anything”. Emacs and Vim also have ways to fuzzy search for a file in a
project, but the heuristics and tools are often so bad and slow that they give
up and fall back on manually finding the file. I’ve never seen a Vim or Emacs
users who navigates between files as fast as I do in Sublime.
I realized that despite all my work and the work of other contributors using
Emacs was still a pain and I longed for the just-works nature of Sublime Text.
It didn’t help that many operations in Spacemacs had surprisingly high latency
(similar to Atom) and many things were ugly (like the file tree). I said my goodbyes
to the Spacemacs community and headed back to Sublime Text.
I still think Spacemacs is overall quite good though. If you’re someone who
mainly codes in one language, especially a popular one, then you can get
Spacemacs set up to do exactly what you want, and the huge community nowadays
means that either the bugs will have been fixed or you can easily get help
with the ones you encounter. I’ve listed a bunch of disadvantages, but Emacs
has powerful features that Sublime doesn’t, I just didn’t like what I had to
give up to get them.
Sublime Text 3: Back With Vengeance
So I switched back to Sublime Text 3, but just like after Vim, I took some of the
things I enjoyed back with me. I updated my plugin and keybinding arsenal to include
many of the handy things I used in Spacemacs.
One thing I really enjoyed in Emacs was Magit, so I installed
GitSavvy in Sublime and found it had almost
everything I liked about Magit. I even like its workflow marginally better and the
Github integration is top notch.
I set up the Alfred Git Repos workflow
to replicate opening projects with Projectile, and used my OSX window tabbing plugin
to manage my Sublime Windows as well.
The fanciest thing I did was create my own set of keybindings
that work like Vim except with the palm keys of my custom keyboard
as the mode. That way it is faster to quickly do movement and editing actions in
the middle of writing. It also synergizes way better with the mouse because
I never am in an unexpected mode when I use it and then move back to the keyboard
since they physical state of my hands is the state of the editor. I still drop into
Vintageous mode for fancier editing though.
And all this took me only a few evenings to get to a point where I was happier
with it than the Spacemacs setup that had taken me six months. I’ve been using
this setup happily since mid-2015 with only a couple bugs which were quickly
fixed, despite using the dev builds of ST3 and many plugins it’s been orders
of magnitude more reliable than Emacs.
Then I went to work at Jane Street for an internship
and ended up migrating back to Spacemacs for a little while. Jane Street has a bunch
of internal Emacs tooling, and even a bunch of custom integration with Spacemacs,
along with much more mature tooling for OCaml than Sublime Text.
It was mostly pretty good, but far from smooth sailing. Various internal
and external Emacs plugins I used conflicted on their idea of where windows
should go and took over other windows, almost actively replacing whichever
window I cared about most. I encountered tons of bugs, both large and small.
Many of these I ended up patching myself, either with dotfile snippets or pull requests.
Not only did I encounter over 20 different Emacs, Spacemacs and plugin bugs
(some annoying me quite regularly) during my four months, but there were other
problems. Jane Street’s massive code base made many plugins slow to a crawl.
Synchronous autocompletion with Merlin occasionally hung Emacs. Using
was unbearable without caching and slow even with it. Until I disabled a bunch
of hooks saving files took seconds due to
hg commands running slowly on the large repo.
Eventually I talked to the one guy using Sublime Text at Jane Street and got
his set of plugins and settings for working on Jane Street’s OCaml with Sublime.
I modied the Sublime Merlin plugin
to support tooltips that showed the inferred
type of an expression and clickable links to the file of definition and declaration.
I then started using Sublime Text for sprees of reading code, but not for writing it.
Sublime still had far worse support for building and indenting Jane Street code.
But, this way I could understand things faster by using quick fuzzy search of files,
excellent tabs, smooth scrolling with the mouse, and tooltip links to navigate the codebase.
Eventually I started using Sublime for editing as well, after I improved indenting,
highlighting and autocompletion slightly. I still kept Emacs open to run the source
control, code review and Jenga build plugins,
but I set up elisp so that it navigated to compile errors in both Sublime Text and Emacs.
This offered an excellent compromise between nice plugins and a good editor that I was happy with.
Despite all the additional functionality and improvements I made to Sublime, I actually
think I spent less time on getting Sublime to work than on fixing, debugging and setting
up Spacemacs while I was there.
Overall, I’m still very satisfied with Sublime Text. I think text editors could
go a lot further than they are now, but so could most software. I feel very
productive, I never fight my editor, and it works for any language I throw at it.
I would love it if Sublime was open source, or if there was an open source editor
that was as good. However, I realize that many of the reasons I love Sublime
wouldn’t be possible without it making money. The reason the creator(s) can pour
so much effort and care into every detail is that Jon (and now also Will) can work
on it full time for years. No other text editor has a custom cross-platform UI toolkit,
a custom parallel regex engine, and incredibly fast indexing, search and editing engines.
I also realize that in some respects Sublime’s rather limited plugin API is an advantage.
Unlike Emacs/Vim/Atom I rarely have to worry about plugins slowing down my experience
by accidentally doing something synchronously on the entire file, since the API almost enforces
asynchronous design. No plugin can break core functionality or slow startup times.
Plugins are forced to work only in ways where it is difficult to conflict with each other
since two plugins can’t implement hacks in the internals that interfere with each other.
When Emacs plugins implement “helpful” hacks to basic functionality that conflict and break
things, my approach is often to disable them since I rarely want these hacks anyway.
Sublime can also get faster and better every release because they don’t have to worry as much
about piles of hacks restricting how they can change their internals. Like how Atom constantly
has to deprecate old APIs whenever they restructure to improve performance.
Also, the recent dev builds have patched what I think was the number one
hole in Sublime’s plugin API: tooltips and inline annotations. Now plugins can
implement fancy custom tooltips
with links and colours and formatting using a subset of HTML. This same HTML
subset can also be used to inject “phantoms”: rich text annotations of code
for things like previewing LaTeX formulae, colours, types, lints and errors.
This should allow most of the useful plugins that previously were only
possible in Atom/Emacs to be ported to Sublime, but since it is implemented
centrally instead of a bunch of different ways it will work seamlessly and
I’m optimistic for the future of Sublime Text. I’d love to see a new editor that’s open source
and as fast, nice and powerful as Sublime, but I don’t expect to since it would be a ton of work.
excellent tooling integration, but for less common languages it doesn’t look any better than Sublime.
I wrote this post because I often find myself justifying my use of Sublime Text to
Vim and Emacs users. They often look down on Sublime users as people who haven’t put
in the effort to learn a real power user’s text editor. They’re confused when they learn
that I have tried Vim and Emacs extensively and still choose to use what they see as
a basic newbie editor. I hope this post explains why Sublime is an excellent choice
for a highly customizable power user’s text editor.