Wednesday 10 August 2022, 12:30PM
In mid 2017, during the tail end of my first year of studies, I decided to take a plunge and dive into using Vim as my full-time text editor. The switch had been a long time coming, and given that in November the previous year I installed Arch Linux on my laptop one could say it was pretty much destined. I'd known about Vim since starting my programming education (in first year of my degree), but as a fresh introductee to all things coding, I was already overwhelmed by too many other things (mainly, how to code) to be trying anything too ambitious other than Atom or IntelliJ. Yet, I was eventually lured over by the promises of blazing, extreme customization options and most importantly, how cool I would look being a h4Ck3r boy
that did everything inside a terminal. And boy, have the last 5 years been a ride...
Skip this bit if you're only interested in the Vim bits.
In late 2016, VSCode wasn't the behemoth that it is today. At Imperial College, we were taught programming in Haskell then Java, so the tools of choice for many (including myself) were Atom (remember Atom?) and IntelliJ. I honestly can't really remember how good Atom was or if it had any autocompletion at all (I suspect not, as otherwise I would have wanted it a lot more in Vim early on), but IntelliJ was and still is a beast. I've occassionally used IntelliJ here and there over the years, most notably when I spent a few months doing Java inside a Big Bank.
Honestly, IntelliJ is just so damn good and can do things that the LSPs don't yet support, so I would wholeheartedly recommend it to anyone knee deep in the JVM ecosystem. Note that I did, however, customize the hell out of my IntelliJ with Vim bindings and distraction-free UI that brought it's feel quite close to Vim. Atom on the other hand, is pretty much dead, but it's spiritual successor VSCode has also become so damn good it's hard for me to justify trying to convince anyone to use (Neo)Vim instead unless I know they're that type of person. Anyways, onto the parts actually about (Neo)Vim...
The first thing I wanted to accomplish was to replicate a pretty basic, barebones setup with Vim and Tmux that I saw from one my university lecturers. I looked up a basic Tmux tutorial from somewhere, another basic Vim tutorial from somewhere else (I really should have just used Vim tutor, to be honest), then setup a few lines of configuration in my .vimrc
and .tmux.conf
to accomplish the following:
<C-a>
.hjkl
navigation.J
to 8j
and K
to 8k
because I thought I was being smart and efficient. (Don't do this, use C-u
and C-d
instead!)This got me going well enough for me to start using Vim as a text editor, and use multiple tmux panes to have multiple instances of Vim for different files. Was this optimal? No, far from it, though 1.) I was happy to take a hit in productivity short term in order to learn and 2.) as a first year student, it's not like I was already a wiz in other editing tools (or coding, really) anyways. I also went full cold turkey, barring myself from using any other editing tools apart from Vim.
The first project I had since making the switch was a group project in C. Since this was a group project, I was able to see my peers' editing tools and quickly identified the two things that they had that I did not, but wanted:
For autocomplete, I looked around and saw two options at the time: Supertab, and YouCompleteMe. After spending a few hours trying to install YouCompleteMe (and failing), I ended up with a realization. Compiling it from scratch and getting it to work across multiple machines would be far too much work to do and maintain, so I quickly moved to Supertab. Supertab's autocomplete was far more basic, just looking at text in the same buffer (so no auto imports, and you would only get useful results if you called the same variable or function somewhere else in the same file already), but honestly it worked and I was happy with it.
For error diagnostics, I went with Syntastic. Fortunately, this was a pretty easy setup and I was able to get it to work with C (specifically, gcc
errors and warnings) quite easily. In hindsight, it was quite good that I first used Vim with C, as it was probably the most supported language in the Vim ecosystem at the time.
In July a few weeks after completing the C project During the summer holidays, I heard through the grapevine about Neovim, a complete rewrite large refactor/near-rewrite of Vim that was supposed to be better. Better how? Well, I certainly didn't know nor did I care about actually looking into it. I was young and stupid, and I thought newer is better, so why not make the switch? So, I made the switch to Neovim, which made no difference at all apart from the fact that my config file was in a different location and had a different name - but it felt cool to be using something newer.
Also around the same time, Plug got released. In this instance, I did do some reading and realized the automatic plugin installation and updates it provided was far superior to having to manually clone plugins like with Pathogen that I was previously using, so I switched over. The ease of adding plugins with Plug
quickly lead to an exponential boom in the number of plugins I was using...
Over the next year or so, my init.vim
became quite big, quite quickly. I had around 40 plugins (which to be honest, I didn't really need), but my Vim experience had become quite IDE-like.
In summer of 2018 I was working on a JavaScript group project for uni, then went into Python for an internship, and my config very much reflected that. ALE had become a thing a few months earlier, and I had set up ESLint, Prettier and PEP8 along with diagnostics with it. ALE
really felt like a turning point in my Vim experience, giving me autoformat on save and near-instant linting and diagnostics. It's errors window popping up annoying whenever there was even a single warning also really instilled in me the discipline of fixing errors as soon as they showed up, which is something I'm grateful for to this day.
Deoplete was also one of the first contenders in the emerging contest between various autocomplete plugins, and soon I had jedi up and running for my Python needs. I think I also setup snippets around the same time, but if I'm being honest I don't think I used them very much.
More than any plugin or configuration, the biggest game changer and productivity boost to my Vim experience has been understanding Vim's language of actions and motions. Quite frankly, I'm personally ashamed that it took me so damn long to learn these things. I won't go into too much depth, but here's quick gist.
Lots of things you want to do with editing text can be summarised as an action that you want to perform over a certain range, or motion. For example, you want to delete a word? Then you can use daw
in normal mode to do that! Or you want to yank inside brackets? You guessed it, you can do yib
! There's like a couple dozen textobjects you can do this with, as well as the standard vim motions like f
and t
.
For a much better explanation, see this infamous StackOverflow post.
Another big game changer was CoC, which was a single plugin to do all things autocomplete and linting related. At the time, VSCode had smashed onto the code editors scene and showed that IDE-like features such as really smart autocomplete, refactoring, and code-actions weren't just IDE-exclusive. CoC's aim was to do the same, but for Vim. It was also really fast compared to previous engines like YCM and Deoplete, and you could install engines via :CocInstall
commands really easily and things would just work out of the box.
CoC has probably been the autocomplete/linting solution I used for the longest while, and though it's not perfect (configuration via a proprietary JSON file was a bit annoying, and in really big projects it can get quite slow), it was the plugin that brought VSCode-like features to Vim and propelled Vim into being a "modern", truly featureful text editor. As of August 2022, I would still recommend CoC to anyone looking to achieve VSCode-like functionality inside Vim/Neovim without spending an exorbitant amount of time on what I'm about to discuss next...
In late 2021, I read about built-in support for LSPs arriving in Neovim version 0.5. For those of you that don't know, LSP stands for Language Server Protocol and is basically a standard interface for servers that can perform language-related tasks such as linting, autocomplete, code actions, i.e. the usual IDE things to communicate with clients AKA text editors. LSPs are essentially an effort to bring IDE features of many languages into the open where any text editor can utilize them, and is fundamentally the reason why you can get very similar IDE functionality out of VSCode and any other LSP-supporting text editor.
Initially I wasn't particularly interested as I was more than happy with my setup with CoC, BUT at the same time as LSP support arriving in Neovim, there was also another huge update: Lua integration. I've never liked VimScript - despite having tinkered with Vim and Neovim configurations for millions of times, the syntax always seemed completely alien to me. Whilst I'd never really looked into Lua, I knew it was a very popular mainstream general-purpose scripting language and that it was probably far more sane in design and idiomatic than VimScript. A quick bit of research also showed that it was much faster than VimScript as well, which was an important point considering my Neovim startup times were becoming rather noticeable.
So during my brief period of unemployment between jobs in December, I decided to jump in and redo my entire Neovim configuration in Lua. And since I was redoing my config in Lua, I might as well see what Neovim Lua plugins out there could replace my existing VimScript plugins. And since I was already putting in so much effort to do those things, surely a quick dip into the native LSP world. This was by far the most amount of work I've put into one batch of config updates, and I initially had some trouble replicating some of my previous functionality from CoC, but I got it working in the end.
Another important addition during these past few months is also Treesitter, which is basically a language parser on steroids. It's made my syntax highlighting much prettier, and enabled a number of powerful plugins (that are really fast!).
After sticking with this "version" of configs for a few months and ironing out the kinks, this is by far the best and fastest my Neovim has ever felt.
Neovim isn't just a text editor, it's a way of life. And as usual with life, there are things to look forward to! Personally for me:
As for Neovim and the community in general, there's a couple of things as well:
Though this post wasn't originally meant to be an article about what plugins I'm using, I realize I might as well cover some of the most important ones now. After all, with the great Lua-fication of my setup, there are now a manageable number of them to discuss...
C-p
, but I'm trying to use it more for fuzzy word search and switching between buffers as well. Note: you need ripgrep and fd to really make the most of this.C-u
and C-d
.There are a few other plugins I'm using, but they're either language-specific (mainly TypeScript) or are far more personal preference rather than something I'd blanket recommend. For anyone interested, my personal dotfiles are here and they're usually pretty up to date, so feel free to check them out as a point of reference.
If you enjoy the above article, please do leave a comment! It lets me know that people out there appreciate my content, and inspires me to write more. Of course, if you really, really enjoy it and want to go the extra mile to support me, then consider sponsoring me on GitHub or buying me a coffee!