Vim is a fundamental application in Linux. Oiled editing significantly aids in handling various Linux applications. Consider Vim as a means to elevate mastery of Linux. This configurable, open-source tool, driven by community contributions, offers numerous packages(plugins/add-ons) and features its own scripting language. It is like a Minecraft sandbox that allows one to create mind tools to process texts.

This article covers some essentials for customizing the vimming experience, including vim/neovim versions and some common logic in the Vim manual.

Vim/Neovim loads a bundle of built-in packages at the start. One of the builtin packages is ftplugin. It is a filetype package that highlights syntax colors for common formats. Then, it reads the user configuration file, which can be .vimrc or init.vim or init.lua, etc.

If one finds the basic functions insufficient, he can install packages or write scripts.

Vim and Neovim are similar. Let's talk about the common parts and then the differences.

Common

Vim and Neovim share mostly the same configuration in Vimscript. The editor has numerous settings and almost any complex behavior can be configured. The examples include syntax highlight, indentation, spell checking, windows' tag bar, and package installation. Vim packages also work in Neovim.

Entry config file

Use :echo stdpath('config') to lookup the user configuration directory. By default, Vim's is ~/ and Neovim's ~/.config/nvim/. Vim uses ~/.vimrc and Neovim uses ~/.config/nvim/init.vim. Both .vimrc and init.vim are Vimscript files.

How did I know the first time actually? Online tutorial.

Options and Global variables

There are two groups of configuration, the terms are options and global variables. Mostly, one changes the behaviors of Vim by setting/overriding the variables in Vimpscript/lua. The load order of variables in configuration files matters, the last comes first, so mind accidental override.

Options are builtin Vim configuration (exist even if no package loaded), refer to :h options. The examples are textwidth, hlsearch, colortheme, etc. They are set by :set textwidth=80 or :set tabstop=4 in runtime temporarily but also can be set in the .vimrc file in permanence. Options are customizable behaviors of bare-metal Vim. One can read the state of an option by :set option?. Example: :set textwidth?

Global variables are used for packages or small scripts. Global variable looks like g:var with g: prefix. They are just values across scopes (functions, scripts) in scripting. In custom, the global variables are read by third-party packages or scripts and affect the behavior of the packages. g:variable is mostly a configuration defined in a package. Global variables need to be set before the package loaded For example, check :h ft-markdown-plugin, let g:markdown_folding = 1 enable markdown folding when ftplugin is turned on.

Shorthand

Quite often, it is too verbose to type :set textwidth=80, so there is shorthand for options. For example, :set tw=80 is equivalent to :set textwidth=80. The shorthand is useful for quick setting during a session. However, it is not recommended to use shorthand in the configuration file, be more explicit. Some examples:

  • pp is packtpath
  • ft is filetype
  • w is write
  • bd is bdelete (buffer delete)

Package path

Where is the vim/nvim session looking for packages?

Use :set packpath? Besides the aforementioned user configuration directory, vim/nvim also looks for factory/distribution packages in the packpath which are usually under system directories rather than user directories. Therefore, a fresh installation of vim/nvim is capable of a lot of features already, and I believe these core packages are well-tested and first-class which I meant to use them first rather than third-party packages.

To look up the runtime file path, use :set rtp? command. It is similar to bash's PATH variable which directories the Bash is looking for executables.

Window

Each window is a state object, and each window can have a local value of an option. Note the scope, :set and :setlocal are different. :set is global in the vim session. :setlocal is local to the window.

Bootup options

The executables vim and nvim have options to control the startup behavior.

# start executables without packages including the builtin:
vim -u None
nvim -u None

# enter verbose mode, output details how packages loaded during startup
vim -V
nvim -V

# launch with debug REPL, used to debug during startup
vim -D 
nvim -D
  • load a custom vim config file: -u : Use instead of any .vimrc
  • -V[N][fname] Be verbose [level N] [log messages to name]
  • For more detail vim --help

Vim

Typically, my configuration is a set of files starting with ~/.vimrc

" ~/common.vim:
set textwidth=80
let g:markdown_folding = 1
" and more settings into groups of files

" ~/.vimrc:
source ~/common.vim
call plug#begin('~/.vim/plugged')

"call :PlugInstall to install this
Plug 'tpope/vim-surround'
Plug 'tpope/vim-repeat'
call plug#end()

Installation of any packages is to copy the correct files and folders into one of packtpath directories. However, this is not a standard go-to and is cumbersome. To use many packages well, first manually install a package manager. There are choices, one of them is vim-plug

Refer to vim-plug

It is up to the user how to organize the configuration files. One may group them by functionality, such as keybindings, coding utilities, filetype auto commands, typing aids, snippets, platform-specific setting etc.

Neovim

The context in Neovim adds complexity, as Neovim supports both vimscript and lua for scripting and configuration. There are portions of community packages that are only available in Neovim since they are written in lua and use Neovim's API.

Should I use multiple package managers? This is tempting if one wants to use both Vim/Nvim and keep a minimal effort to manage vimscript and lua packages. No, it generally mess up the package dependency. From the communities, Neovim's newest package manager is Lazy now. Refer to lazy.nvim

There is API bridge for nvim lua to use the vimscript APIs. Here is an example of using vimscript to bridge lua settings in nvim:

-- ~/.config/nvim/lua/init.lua
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system {
    'git',
    'clone',
    '--filter=blob:none',
    'https://github.com/folke/lazy.nvim.git',
    '--branch=stable', -- latest stable release
    lazypath,
  }
end
vim.opt.rtp:prepend(lazypath) --rtp: runtimepath

-- and lua packages follow here...
" ~/.config/nvim/common.vim:
set textwidth=80
let g:markdown_folding = 1
" and more settings into groups of files

" ~/.config/nvim/init.vim:
runtime common.vim " load the common.vim
lua require('init') " load the init.lua from init.vim

It is free to use Vimpscript or lua in Neovim interchangeably.

Conclusion

For more information, refer to :help config. There are plenty of references from communities.

Users don't have to adjust every option. Instead, they can select the features, options, or packages that best suit their work requirements. It's a personal choice, and mindlessly adding packages could negatively affect performance.

Vim configuration is one of the hurdles to mastering Vim. Here I want to complement some often missed key points about configuring Vim. There's no rush to create an ideal work environment. It's a continuous journey, as the package ecosystem evolves consistently.

I also put my handy Vim configuration on Github dotfiles for reference.

Your thoughts...