My Neovim Configuration

2/4/2022 VIMProgramming

This post documents how I set up my personal configuration of Neovim

# Background

After using VIM for about half a year in my daily workflows, I finally transit to Neovim. In most cases, VIM and Neovim doesn't make a difference, especially my main usage of them is for writing documents, taking notes and altering configurations. In fact, I have both of them installed and shared the same _vimrc (for most part). However, from time to time, I will need to write some scripts and programs. I had to fall back to vscode for those tasks because VIM doesn't really make a great IDE.

However, with Neovim 0.5.0 and after, the native language server support makes it a great vscode replacement. I like it better even on Windows because it's just so natural to directly open any file or scripts from the terminal. With Neovim and its language server support, it becomes a perfect combination of VIM's legendary text editor and a universal light IDE.

I also transit to Lua for Neovim's configuration from classic vimscript. Lua is such an efficient and elegant scripting language. It took me a while to understand how to configue Neovim's LSP and Auto-completion. But thanks to the tutorial from LunarVim's "Neovim-from-scratch" (opens new window), I was finally able to bring my Neovim configuration to a level that I enjoy using as my daily editor.

# Installation

Neovim is open source so you can download it from its official Repository (opens new window) for different environments. I use Scoop (opens new window) to install most of my software on my Windows machines. Simply:

scoop install neovim

# Folder Structure

Depending on how you installed Neovim, the Neovim binary files will be installed to your normal software folders. Inside the folder, there will also be a Neovim GUI application but I usually just use nvim command in my terminal to launch Neovim. In some situation, if your terminal doesn't recognize nvim as a command, it is due to the binary file location not added to the your system's PATH.

You should never worry to mess with your Neovim binary folder because the configuration you are going to deal with will live in your user folder. In Windows, it is usually located in C:\Users\YOURUSERNAME\AppData\Local\Nvim. In addition, a data folder will also be created at some point in C:\Users\YOURUSERNAME\AppData\Local\Nvim-data. The plugins will usually live in this data folder but you will probably not need to worry about it either because your plugin manager will usually take care of it.

Here is my Neovim configuration folder structure:

nvim
│   init.lua
│   Readme.md
│
├───lua
│   │   keymappings.lua
│   │   lsp.lua
│   │   myConfigs.vim
│   │   nvim-cmp.lua
│   │   options.lua
│   │   plugins.lua
│   │   treesitter.lua
│   │
│   └───lsp
│           js-ts-ls.lua
│           json-ls.lua
│           lua-ls.lua
│           python-ls.lua
│           sumneko_lua.lua
│
└───plugin
        packer_compiled.lua

# Configurations

I have a handful of Lua files and a vim file (which I will eventually migrate to Lua as well) for my personal configuration. You could have them all in one single init.lua file similar to what I used to have for VIM in a single _vimrc.

  • init.lua: This is the main entry point for all configurations. It simply requires (which is the Lua way of saying references) other config files. It looks like this:
require("plugins")
require("options")
require("keymappings")
require("lsp")
require("nvim-cmp")
vim.cmd("source " .. vim.fn.stdpath("config") .. "/lua/myConfigs.vim")
  • lua/options.lua: This file is for regular neovim options/preferences. You can think of this being the "preference" or "options" menu in most of the windows software where you can choose different start-up options that you want your Neovim to behave.

  • lua/keymappings.lua: This file is for all custom keybindings. VIM/Neovim has an extremely powerful keybindings system but you will find certain bindings not worrking as conveniently as you would like it to be. For example, for someone like me spending most of our life on Windows machines, Ctrl-v to paste text has just became the muscle memory. While I kept using VIM's native paste "p" in normal mode, I have my own keymappings to use Ctrl-v in both insert mode and command mode.

  • lua/plugins.lua: This is where I keep all my plugins. As all plugins are directly installed from the Github repository, it became so easy to maintain and control them in a few lines of code.

  • lua/lsp.lua: I use this file for language server configurations. It used to be confusing to install and maintain different LSPs with Neovim. But now with the plugin "nvim-lsp-installer", things have become much easier to follow.

  • lua/nvim-cmp: This is also somewhat LSP related. It controls auto-completion settings from a variaty of plugins from the "nvim-comp" family. This is such a big life quality improvement. It not only auto completes your coding like any other IDE. It also helps tremendously with the spelling when writing English for someone like me who isn't a native speaker.

  • lua/lsp/*: I reserved this folder for keeping language server specific settings.

# Plugins

I use a dozen of plugins. They can be categorized into the following:

  1. Theming and cosmetic:
  • vim-github-colorscheme
  • onedark.vim
  • nightfox.vim
  • vim-airline
  • vim-airline-themes
  1. Easier navigation
  • nerdtree
  • vim-sneak
  • vim-surround
  • auto-pairs
  1. For documentation and note taking
  • vimwiki
  1. For programming
  • nvim-lspconfig
  • nvim-lsp-installer
  • null-ls.nvim
  • nvim-cmp family

# Other customizations

Except for the customized key mappings that I like to use, I also have the following customizations.

cnoremap <A-v> <C-\>esubstitute(getline('.'), '^\s*\(' . escape(substitute(&commentstring, '%s.*$', '', ''), '*') . '\)*\s*:*' , '', '')<CR>

When you are in the command mode, you can press alt-v to paste the current line in the command.

autocmd FileType python nnoremap <buffer> <F5> :update<bar>!python %<CR>

I like to use F5. This command will directly run your python file in the terminal with one key stroke.

autocmd bufenter *.md noremap <silent> <f5> :! start msedge "%:p"<cr>

Again, use F5 to display the current markdown file in the browser, where I have an extension installed to render the markdown.

augroup clear_trailing
    autocmd BufWritePre * if &ft != "vimwiki" | %s/\s\+$//e
    autocmd BufWritePre * if &ft != "vimwiki" | %s/\n\+\%$//e
    autocmd BufwritePre * noh
augroup END
Last Updated: 2/19/2022, 5:44:51 PM