from Vim to Emacs - part 2

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.

    1. 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".

    2. 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!).

None
A comma-separated list of terms describing this content. Example: funny, bungee jumping, "Company, Inc.".