I started using Neovim (nvim for short) about three years ago, in Sep. 2018. At that time, nvim had just released version 0.3.1. Over the years, I have been an adamant nvim user, constantly learning new knowledge, and sharing tips, tricks and interesting plugins in my blog posts.
How I started with Neovim
Back when I was still in university, I had dabbled in Vim a little bit. I remember that in those days, most posts on the Internet recommended using a plugin manager called vundle. As for auto-completion, ycm was the most popular plugin at the time. However, it is difficult to configure and install, and I never succeeded in installing it. I copied some basic config from various posts and did not really understand what they mean. Vim script seemed weird and hard to understand, so my first trial of Vim didn’t really take off. I learned the basic motion and know how to save and quit a file, but no fancy and advanced features such as text objects. I was still using PyCharm and Sublime Text for serious project development.
After I graduated and started working, since we need to run the code on a remote server which has no GUI environment available, I was forced to make choices:
- Develop on a remote server without GUI, which implies using a TUI editor. Vim is apparently the choice.
- Develop on my local PC and sync the code to remote via Git or other tools.
I find choice one more elegant, since I do not need to set up dev environment on my local machine, and I can run my code directly on the server (running the code requires GPU and there is no GPU on my local machine). At the time, I came to know the Neovim project. I choose Nvim because it is easily installable. It provides binary releases, so I do not need to compile from source myself. I also like its development model more than Vim’s. Nvim use GitHub and all modern dev tools for better collaboration, while Vim is still using google groups1.
Finally, I was on the Neovim boat and started my journey.
My learning story
The initial learning curve of nvim was indeed quite steep. I needed to constantly check the documentation or search on the Internet, then tweak the configuration to do what I want. Sometimes, a small setting may waste a lot of time, since I needed to understand what it does and how it works. I also spent a lot time tweak the settings of various plugins to fit my need.
My way of learning Nvim is to add the features and plugins I need incrementally. At the start, I only added the settings I want most, like autocompletion, linting, file explorer etc. I searched intensively on the Internet for the state of the art plugins for a particular need. I will try several similar plugins, and only keep the one that best suits me. The most important point to remember is that never rush to master Vim in a few days. Vim has so many hidden features and settings, and it is impossible to master it quickly.
After about three or four months of rapid learning process, I was at ease using Nvim for my development work. I published a post on how to configure Nvim for Python development.
After building a usable config, when I want to do something, I always seek if there is a better way to do it. I searched on the Internet and learned new tricks, and perfected those skills through practicing. Notice that not all tricks are good and are written by advanced Vim users. We need to constantly learn new Vim knowledge and update our existing settings.
Another great learning resource is the configurations of other people. We can find numerous dotfile repos on GitHub and learn from them little tips and tricks that we do not know yet. I have always advised against copying the config of others without knowing what you are doing. At the very least, we should read the documentation and understand what a particular setting does. If we copy other’s config blindly, it may cause endless pains afterwards when we spend hours debugging misbehaving Nvim.
As I became more proficient in Vim, I started learning more advanced features such as text objects. I also created some custom text objects for my own use. I have always wanted to write my own plugin and contribute to the community. After learning enough about Vim script, I wrote a plugin called better-escape.vim in Dec. 2020. The goal is to help users escape insert mode quickly without lagging caused by timeoutlen option.
This year (2021), I have been learning Lua and migrating some of my config to pure Lua.
Evolution of my configuration
Initially, all my config is stored in a single file
init.vim which in its peak exceeded 2000 lines.
Later, as I learned more about how Vim works (autoload, ftplugin, after folder etc.)2,
I started splitting my config into different parts for better maintainability.
My config has been all vim script for a long time.
Since nvim is adding more lua support and using lua to implement its builtin LSP support,
I have also been updating my config and adding a little lua.
I have slowly moved my completion system to the builtin LSP3.
After that, part of my configuration is moved to
What remains, what has changed, and some new plugins
Plugins have always been an essential part to enhance the power of Vim. Since there is no central plugin market like Emacs MELPA, finding good plugins is not always easy.
That a plugin is popular and has more stars does not mean that it is better or it suits you5. Over the course of three years, I have always tried to find better alternatives for my existing plugins. Admittedly, trying a new plugin and adapt to it is a time-consuming process, especially if a plugin does not work out of the box and requires some degree of customization. However, the efficiency boost brought by a well-designed plugin can be huge.
A few plugins still remain:
- git gutter plugin: I still use vim-signify, but gitsigns.nvim seems promising.
- snippet plugin: I am still using ultisnips due to its powerful interpolation features. There are also many lua-based snippet engines.
- git plugins: still using vim-fugitive. I have also tried gina, but find it too complicated. There are also lua-based git plugins such as neogit, which aims to replicate the functionality of magit.
- markdown plugins: vim-markdown for editing and markdown-preview.nvim for preview.
What has changed
I have also updated a large part of my plugins during the process:
- plugin manager: from vim-plug to packer.nvim. I changed to packer.nvim this middle this year, because it allows all sort of crazy lazy loading and bring package management to a whole new level.
- autocompletion plugins: from deoplete + deoplete-jedi to vim-lsp + deoplete to nvim-lsp + nvim-compe to nvim-lsp + nvim-cmp.
- pair management: from vim-surround to vim-sandwich. Vim-sandwich is well-designed and has better UX than vim-surround.
- comment plugin: from nerdcommenter to commentary.vim. I like commentary’s feature of commenting via motion.
- file explorer: from nerdtree to none. I use fuzzy file finder instead. If I need to explore a project, I check it in another tmux pane.
- statusline plugin: from vim-airline to lualine. Vim-airline is great, but it is also bloated with two many 3rd part plugin integration. Lualine is simple, faster, and easy to customize.
- change of linting: from Neomake to ALE to nvim-lsp
- auto-pair plugin: from auto-pairs to delimitMate. DelimitMate has saner behaviour for pair insertion than auto-pairs.
- in-buffer jump: from vim-sneak to hop.nvim. Vim-sneak has been a great plugin. I changed to hop.nvim because it may support jumping via pinyin (PR here), which is convenient for Chinese users.
- search item indexing: from vim-anzu to nvim-hlslens. Nvim-hlslens is a lua plugin that provides better UX for search item indexing using virtual text feature of Nvim.
- clear search highlight automatically: from vim-cool to nvim-hlslens
- format plugin: from Neoformat to none (using LSP for formatting).
- multiple cursors: from vim-multiple-cursors to none. I now use
gnmostly. vim-visual-multi may be a good replacement (also recommended by vim-multiple-cursors).
- yank highlight: from vim-highlightedyank to nvim builtin, see this post.
- fuzzy finder: from fzf.vim to LeaderF. LeaderF works fast and reliably across different systems.
- startup screen: from vim-startify to alpha-nvim.
- tabline plugin: from vim-airline to bufferline.nvim.
- indent line plugin: from indentLine to indent-blankline.nvim. Indent-blankline uses the virtual text feature to make indent line flawless even on blank lines.
- auto save plugin: from vim-auto-save to AutoSave.nvim.
- showing tags: from tagbar to vista.
I have also added some new and interesting plugins:
- nvim-treesitter: more accurate highlighting, text object and more.
- nvim-notify: show notification on floating windows
- unicode.vim: check, search and insert unicode characters
- asyncrun.vim: run code asynchronously in the background and show results in quick fix window.
- firenvim: run neovim inside text area in the browser.
- vim-oscyank: yank text from remote server directly to your local clipboard.
- wilder.nvim: autocompletion in command line for Nvim.
- whichkey.nvim: show key mappings and register contents etc.
My thoughts on several topics
Vim or Neovim?
This is a question which gets asked almost monthly by beginners (e.g., see this post). The short and unbiased answer is that it does not really matter.
Since Nvim is a fork of Vim and merge patches from Vim regularly, the basic features are almost the same. There are some subtle differences (see vim-differences), but that is largely irrelevant for beginners. If you are a beginner, you can pick either one and learn the basics6. Later when you become proficient in using Vim, you can choose a side.
It is a sad truth that Vim and Nvim are going on quite different paths. Neovim is investing more on Lua, and its Lua plugin system is thriving. Vim is trying hard implement the vim9 script, a completely new and incompatible version of viml. There might be more incompatible changes happening on both sides. It might be getting harder to port Vim patches to Neovim. Personally, I doubt whether the amount of effort put into building vim9 script will ever pay off. Considering that a lot of vim plugins are still trying to support Vim 7.xxx, I doubt how many of these plugin authors are willing to rewrite their plugins in vim9 script, especially when their plugins have very large code bases.
Personally, I will stick to Neovim and migrate to all-lua config some day.
init.vim vs init.lua?
Since nvim has added support for init.lua, many people have completely moved from viml-based to lua-based config. Currently, my config is still a mix of vim script and lua script due to several reasons:
- Lua support in Nvim is still not complete and mature enough. For example, sometimes we still need to use
vim.cmd()to run vim command. We still need to learn how to use Vim script.
- Some viml command is more concise to write, and lua tends to be more verbose, e.g., when defining mappings or setting an option.
- I am still using quite a few vim script plugins, and it makes sense to configure these plugins in vim script.
Should I use a pre-made config distribution?
There are several so-called Vim/Nvim distributions, which aim at providing IDE-like and out-of-the-box experience of using Neovim. Some of the most popular distributions are Spacevim, LunarVim and NvChad.
People ask frequently on r/neovim and r/vim whether they should use a vim/Nvim distribution. If you are serious about Vim and want to learn how to use it properly and eventually master it, I think it is better to avoid those distributions and build your own config from scratch:
- Those distributions may add their own configuration layer and complicate things. Users end up learning two much distribution-specific config without learning real Vim stuff.
- Even if you use those distributions, when you want to customize certain things, you still need to learn how Vim/Nvim works under the hood. Otherwise, you can only count on other developer to implement the feature for you.
- When you meet issues with those distributions, you may have a hard time debugging it, since they all include various configurations.
However, this does not mean that you can not learn from these distributions, e.g., how they configure, how they organize their directory structure. You can even steal some configs for your own use.
Looking back, I think I have made the right choice to learn Vim/Nvim. It has been a rewarding jounery for me. I am so used to vim’s style editing that Vim becomes second nature.
I am thankful to all the contributors of Vim/Nvim for building and maintaining such a great editor. I am grateful for the efforts that plugin authors put into in building those great plugins.
I am not saying that Vim’s development model is worse, I just like Nvim’s development model more. ↩︎
If you decide to go all Lua and use
init.lua, then you should definitely use Neovim. ↩︎
License CC BY-NC-ND 4.0