Why Neovim

I consider the IDE or text editor I use to be a very important tool. When you think about it, if you write code on a daily basis it’s the program you spend the most time with. I’ve used a variety of IDEs from when I first started to learn coding in highschool, but when I started my first job as a full time software engineer I made the decision to use neovim as my editor of choice. It’s been about a year since I first jumped down the neovim rabbit hole, and I don’t see myself switching to something else anytime soon. Here’s why I chose neovim, and what my config structure looks like.

Before neovim

The first editor I ever saw was codeblock’s. At the time I was working off of a learn to code book my parents bought me. I struggled to comprehend the material in the book and soon left it to collect dust on my bookshelf. I didn’t look at another code editor until my last year of high school in my comp-sci class.

If I had to list out all the programs I used to write code from my high school comp-sci class to the last year of my college degree, it would look a little like this:

  1. Eclipse
  2. CLion
  3. IntelliJ
  4. Visual Studio Code

Not to mention the other programs I don’t remember the name of (and I’m not sure if some of them could be considered code editors). Things like Matlab, ModelSim, Atom, and even Notepad++.

Something I subsconciously noticed with a lot of the big IDEs I used in college were that they had long start times, Eclipse, CLion, and IntelliJ began to feel clunky at times. A smaller yet equally important aspect of the editors I noticed were that some just had ugly UIs. I’ll give a pass to JetBrains products since I find their interfaces pleasing, but stuff like Eclipse look so unappealing to me that I realize working with them becomes more of a pain. My personal take is that if I’m spending hours starting at a screen I want it to be pleasing to the eye. Lastly, I wasn’t a fan of how different languages require different programs installed on my computer. E.g. if was working on a C project and a Java project at the same time I had the overhead of having two separate programs installed for each language.

In comes VSCode - I discovered it in my junior year of college and it changed the game for me. The extensibility and customizability were features I took full advantage of. I probably installed more VSCode extensions than one should. Being able to use the same editor across different projects was also huge for me. VScode felt snappier, and moving to a simple editor forced me to get well-acquainted with the command line - opening up a whole new world to me at the same time.

A gradual change

I was content with VSCode, but at the same time as I started to get more familiar with Linux I noticed people using this editor called vim. VSCode had its uses, but when I was ssh’d onto a machine I wouldn’t be able to use it. (I knew at the time that there was a SSH feature for VSCode, I just would rather whatever editor was available to me in the terminal for some reason). Getting into vim was a slow learning curve and I remember a classic experience of rebooting my computer because I couldn’t exit vim. However, I liked the philosophy behind vim’s keybinds and how you can keep your hands on the keyboard and use it at the same time to move the cursor around the screen. Determined to stick with it, I gradually learned enough to be comfortable with using it on a semi daily basis.

I had known about neovim for a while before starting to use it, but was reluctant to leave my VSCode comfort zone. When I started my first job I decided it might be as good a time as any to try to use neovim as my daily driver. I looked up several guides online and got a minimal config going. The biggest change was when I realized neovim could be combined with tmux. It was a game changer to be able to effortlessly switch between different terminal sessions and neovim with a few keypresses.

My config

After a year of configuring and re-configuring my neovim install, here is what my config directory looks like at the time of writing this.

/Users/marcuskok/.config/nvim
├── README.md
├── coc-settings.json
├── init.lua
├── lazy-lock.json
├── lua
│   ├── core
│   │   └── plugin_config
│   │       ├── autopairs.lua
│   │       ├── barbar.lua
│   │       ├── catppuccin.lua
│   │       ├── comment.lua
│   │       ├── completions.lua
│   │       ├── debugging.lua
│   │       ├── harpoon.lua
│   │       ├── lsp_config.lua
│   │       ├── lualine.lua
│   │       ├── nvim-lint.lua
│   │       ├── nvim-tree.lua
│   │       ├── nvim_tmux_navigation.lua
│   │       ├── obsidian.lua
│   │       ├── orgmode.lua
│   │       ├── refactoring.lua
│   │       ├── startup.lua
│   │       └── treesitter.lua
│   ├── keys.lua
│   ├── opts.lua
│   ├── plug.lua
│   ├── plugins
│   │   ├── blamer.lua
│   │   ├── completions.lua
│   │   ├── debugging.lua
│   │   ├── harpoon.lua
│   │   ├── linting.lua
│   │   ├── markdown-preview.lua
│   │   ├── mason.lua
│   │   ├── neodev.lua
│   │   ├── obsidian.lua
│   │   ├── orgmode.lua
│   │   ├── qol.lua
│   │   ├── refactoring.lua
│   │   ├── theme.lua
│   │   ├── tmux.lua
│   │   └── trouble.lua
│   └── vars.lua
├── plugin
└── snippets
    ├── _.snippets
    ├── all.snippets
    ├── c.snippets
    ├── markdown.snippets
    ├── python.snippets
    └── yaml.snippets

I’m not going to go into depth here (maybe that can be a separate post) but here are the broad strokes:

  • I use init.lua to add individual config files to neovim.
  • plug.lua used to be where I defined neovim plugins when I used Packer. Recently I switched to lazy and now I define plugins under the plugins/ directory.
  • keys.lua for custom keybinds (for example I use ‘jj’ instead of to get out of insert mode)
  • core/plugin_config/ for storing plugin specific configs.
  • opts.lua for neovim options.
  • vars.lua for setting global variables used by other files.
  • a snippets/ directory for storing quick and easy snippets of code I use repetitively.

Over the course of a year using neovim for all my work I’ve noticed some benefits, beginning with less cognitive friction when writing code. Once I learned vim movement, having quick and easy ways of editing text while keeping my hands on the keyboard means that the time it takes for a thought to formulate in my head to when I translate that to code on the screen is nearly instantaneous. Certain plugins allow me to efficiently search through code and go to references and usages. Parsing through code has never felt smoother. Having a curated list of plugins also means that I have an editor specially built for me and my needs. I can also put my config files in a git repository which allows me to have the same neovim experience across my personal and work machines.

I’ve had a great experience with neovim, and I’m even using it to write this post. People may be intimidated by it’s somewhat high learning curve (I certainly was), but I can also attest that the effort pays off. You end up with a deeper understanding of the tool you use and (in my opinion) the learning process is fun. Worst case scenario you can switch back to a more out-of-the-box editor if neovim doesn’t work for you. Give it a try and you may be surprised with how your workflow changes. 🙂