One month with Emacs and counting - Part 2
Other posts in the from Vim to Emacs series:
part 1
A while ago I've blogged about my switch from Vim
to Emacs, promising a blog post series, quite a
mouthful
nevertheless, it's time to continue the series. The first part was
about why I think that nowadays Emacs is ready to be
switching to. This second part is about flawed Vim design choices which
substantially contributed to my choice.
(Of course all this post is under a IMO-/rant-disclaimer,
it can't be otherwise, so take it cum grano
salis)
Flawed Vim design choices
Vim started as a wonderful editor, following the path of Vi,
which in turn has got right a good deal of design choices. One is
the often debated modality. In spite of being a
HCI
PITA in general,
modality is not a problem at all for software you are using every
single day (and the editor is the 2nd program I use the most, with
the terminal being the 1st), because you learn it as a habit. In
the case of Vim, modality is good because it let you use powerful
yet simple motions
in command mode, which can be easily combined with
operator-pending commands.
This can be considered yet another incarnation of the UNIX philosophy,
casted inside the editor itself. ... which brings us to
the good old joke which describes Emacs as a great operating
system, lacking only a decent editor. In fact, Vim
is no longer the nice Unix philosophy player which it used
to be, and Emacs plays much more nicely with external tools than
Vim.
As arguments, let's consider a few (not so) recent Vim
evolutions:
Spell checking. Starting with version 7, Vim
has got support for on-the-fly spell-checking of text
buffers. It is a super-nice feature, which I've advertised in the
past, because spell checking is needed in many tasks we daily
do with editors (mail/doc writing, code commenting), and having a
single interface to do it comes handy.
Unfortunately, how that is implemented in Vim is
definitely not along the lines of the UNIX philosophy. We
have countless different FOOspell implementations whereas Vim
implemented yet another one, without relying on any pre-existing
implementation. Even more so, the file format of spell files is
basically ad-hoc, and not sharable with other tools. This is
already a PITA for packaging (let's add to Debian another 20 binary
packages vim-spellfiles-FOO), but is even worst than
that: the spell files must be generated in ad-hoc ways which are
seriously prone to failures (guess why in Debian we don't have yet
the vim-spellfiles-FOO packages which used to exist in
experimental a long time ago?).
What would have been the UNIX-friendly way of achieving the same
result? Well, obviously spawning FOOspell and
interact with its process from the editor. Keep that in
mind.
Internal grep. A feature of Vim I've always
loved is :grep
(yet another instance of quick-fixing,
which is also used for jumping to compile-time errors). In its
original incarnation it was as simple as invoking grep
and parse its output. KISS.
Then, Vim started to have a problem: grep -r can
take ages and in the meantime the editor was stuck. Hence, starting
with Vim 7, vimgrep
has born: an internal re-implementation of grep. OK, it is
more portable (but how many of us do care? on how many system you
use you are missing grep? damn, I used to install it also on
Windoze!), and the editor retain control. Control that is exploited
just to show a nice progress bar of what is being scanned ...,
while the editor is still stuck.
Well, to me it looks like the problem would have been solved
much more nicely by adding the ability to interact with an
external process (deja vu?). That process can then be
grep -r. Full stop.
Lack of debugging support (on purpose). Long
standing missing feature of Vim: you can not "easily" drive a
debugger from Vim, because a firm choice in Vim is to ... (OK, I
confess, I'm starting to beat a dead horse) ... not have
support for interaction with external processes.
I found such a choice quite dumb: to me it is evident that it
induces a trade-off between being feature-complete wrt programmer
needs (as available external tools get available to face those
needs) and not "re-implementing the wheel" inside the
editor.
Going back to the lack of debugging support in Vim, that has
spawned projects like GdbVim, Clewn, Bram's Agide, and my own tiny teeny
incarnation specific to ocamldebug
called WOWcamldebug. Every
single project of that list acts as an intermediary between Vim and
an external process (a debugger of some sort), whereas that could
have been implemented by an editor plugin, provided that the editor
offer, guess what, support for interaction with external
processes.
Top-level. Similar to the debugging support
issue, there is the interpreter issue, namely how to
evaluate "phrases" of your interpreted language of choice directly
from the editor. Nowadays a lot of languages have the so called
top-levels which evaluate language phrases interactively (Python,
Ruby, OCaml, many Lisps, ...) and show evaluation results. That
ability can speed up testing considerably, but can become
cumbersome to use for large code snippets without editor support
(good luck with copy and paste).
Yes, Vim has support for that, but the implementation choice is
close to be ridicolous: only if you have linked Vim
together the interpreted for a given language, then you will be
able to interactive evaluate phrases of that language. What if you
program in Python, Ruby, and Perl? Well, you need to link all of
them. What if you also program in OCaml? Then you're screwed,
because Vim currently does not support linking with it.
(Yes, I know that there are other reasons for doing that
linking, they are discussed below.)
Do I need to tell you which feature will be enough to address
top-level support? interaction with extern.. OK,
I'll drop it, you know that already.
Well, I acknowledge that Emacs got this choice right, and that
it's an important one: Emacs supports interaction with
external processes, and plugin authors have been happy to exploit
it to create really cool stuff (sticking to the UNIX philosophy).
Please welcome:
Flyspell, M-x
grep (shameless smartass plug: same number of keystroke
of :grep),
Grand Unified Debugger, a sampling of
language-specific major modes with top-level support. (But I
recommend having a look at least once at the coolness of other
stuff built-on top of external process support, like Flymake, mentioned
by dancer not a long ago.)
Its own scripting language. I've bored you
enough with the external process topic, hence here is the second
one: the saga of Vim and its scripting language, i.e., the
programming language using which you can customize the editor.
Note that the choice of scripting language impacts on 2
different targets: final users in need of fire and forget
automations (when they start to get to complex to be implemented on
top of, say, macros),
and developer of editor extensions such as addons.
The impact of scripting language on extension developer is
crucial for the evolution of an editor aiming at being powerful. If
the scripting language and the API towards the editor is flexible
enough, then a lot of cool extensions and features will be
developed by third party authors, otherwise the burden stays on
editor upstream author.
In its phase 1 (my term, Vim < 7.0) Vim pretended
that it needed only a minimal scripting language (Vim script)
and that everything else can be developed using external
programming languages, linked in the editor. As a consequence Vim
script was just a tiny teeny procedural language with editor
interfacing capabilities, most notably lacking any "decent" data
structures (no lists, no dictionaries, ...).
In that phase, if you were a user it was fair enough. You just
had to chose your external programming language (at compile time
...), and you were able to write your quick hacks with it. But if
you were willing to develop an extension you were screwed, because
you had either to impose your external programming language to the
final user (that is what gave born to absurdities like vim-full,
look at the deps!) or to enjoy a good deal of masochism to explode
your 30 lines of Python extension into 200 lines of Vim script to
make your Vim extension more "portable".
In its phase 2 (Vim >= 7.0) it has been realized
that something were wrong in the initial choices about Vim script,
and data structures (lists, dictionaries, function references!)
have been added to it, relieving a bit the pain of programming
portable extensions.
Nevertheless, and probably due to how it started, Vim script is
far from being a programming language one can enjoy programming in.
Consider for example the standard
library of the language. It started as a random collection
of unrelated functions being added on a "as-needed" basis, ... and
continued along that path! Now the API reference lists together
totally unrelated functions, organized inconsistently, and making
really painful finding what you need (assuming it exists).
Even in this respect, I acknowledge that Emacs got this right.
It has chosen a single, now full-fledged, programming language
(Elisp),
which is offered both to the final user (fact: the average
Emacs user knows much better how to program her own editor than the
average Vim user) and to extensions developer. The standard library
of the language is organized with a consistent naming (even though
not always intuitive) and documented
in an organized manner.
You might not like the language, but at least is has been taken
seriously and managed as such. Finally, being a Lisp dialect, you
might need what you learn with Elisp elsewhere. Vim script is too
committing: it is useful only inside Vim. I believe that
contributed significantly in its scarce diffusion among Vim
users.
The fact that Elisp was born together with Emacs and that it is
also used internally for the editor implementation is not relevant
here: I do care about what is offered to me as an user and as an
extension developer. What I see on the Emacs side in this respect
is much better that what I see on the Vim side. Moreover, from the
point of view of the users, is the difference between what is
inside the editor and what is outside (i.e., the
extensions) that relevant? I think it is not, and that brings me to
the final Vim choice which I consider flawed and which has the
potential of seriously limit its future evolutions:
Editor as a distribution. Emacs is managed as a
intermediate software distribution layer, similarly to what happens
in other softwares where many third party authors cooperates (e.g.,
TeXLive). The
distribution architecture has advantages and contributes to the
longevity and potentialities of a software project.
What does this mean concretely in the Vim vs Emacs dispute? For
example it means that Emacs get more feature-complete each passing
release, still preserving uniformity in documentation and
keybindings. On the contrary Vim sports many addons, which are very
likely to step on each other feet when enabled simultaneously.
Actually, that is one of the reason which brought me to the
creation of vim-addons:
you cannot enable all the content of vim-scripts
together due to various kind of conflicts. As we know well in
Debian, distributions have a fundamental role in blending together
lightly-coupled software components, that's role is missing in Vim
evolutionary path and I find that worrisome.
Where to from here in this blog post series? For sure some tips
on how to migrate for hard-core Vim users, then we'll see ...
If you did enjoy the read please let me know commenting in the
discussion page (as you did in the last post, thanks!).