Yet Another (N)Vim Config
Introduction
You can find my configs for everything here.
The Basic Vim Config
I've used Vim since about 2018. Over these last eight years, my Vim config has changed very little. Here's the entire .vimrc as of today:
" Make sure Python virtualenvs don't throw a warning when starting vim.
if exists('$VIRTUAL_ENV')
let &pythonthreedll = system("find /usr/lib64 -name 'libpython3.*.so.1.0' | tail -1 | tr -d '\n'")
python3 << EOF
import sys
import sysconfig
sys.path.insert(0, sysconfig.get_path('purelib', vars={'base': '/usr', 'platbase': '/usr'}))
EOF
endif
" Uncomment this instead if using neovim:
" if exists('$VIRTUAL_ENV')
" let g:python3_host_prog = '/usr/bin/python3'
" endif
execute pathogen#infect()
syntax on
colorscheme desert
" Use filetype detection and file-based automatic indenting
if has('filetype')
filetype plugin indent on
endif
set autoindent " automatically indent
set hidden " allow switching buffers without saving
set hlsearch " highlight search results
set ignorecase " case-insensitive search...
set incsearch " show search results as you type
set mouse= " disable mouse
set pastetoggle=<F2> " hotkey for paste mode to avoid extra indentation
set ruler " show cursor position in status bar (redundant with airline but harmless)
set scrolloff=5 " keep 5 lines visible above/below cursor when scrolling
set smartcase " ...unless you use uppercase in the search term
set textwidth=80 " wrap width
set updatetime=100 " reduce time between updates from 4000ms to 100ms
set visualbell " don't beep
set wildmenu " better tab completion in command mode
if has("autocmd")
" Use actual tab chars in Makefiles
autocmd FileType make setlocal tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab
autocmd FileType c setlocal tabstop=8 shiftwidth=8 softtabstop=8 noexpandtab
autocmd FileType python setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab
autocmd FileType rust setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab
autocmd FileType yaml setlocal tabstop=2 shiftwidth=2 softtabstop=2 expandtab
autocmd BufNewFile,BufRead *.v,*.vs setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab
endif
let g:airline_powerline_fonts = 1
with the following installed as plugins:
- fugitive
- nerdtree
- vim-airline
- vim-gitgutter
Switching to NeoVim
There have been times when I've made an attempt to switch to NeoVim, but I've always found the popular distros to be too much even on first install - there are a lot of changes and new features that feel too different from the default Vim behaviour I expect on a random system. Now that I use Claude for a bit of pair programming and clean-up, I asked it about how I could achieve a similar minimal setup with NeoVim. It gave me this config structure:
/home/tgamblin/.config/nvim/
├── init.lua
└── lua
└── plugins.lua
and these files:
init.lua
-- Bootstrap lazy.nvim
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",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- Load plugins
require("lazy").setup("plugins")
-- Appearance
vim.cmd("colorscheme desert")
vim.opt.number = true
vim.opt.ruler = true
vim.opt.visualbell = true
vim.opt.colorcolumn = "81"
-- Editing behaviour
vim.opt.autoindent = true
vim.opt.textwidth = 80
vim.opt.scrolloff = 5
vim.opt.hidden = true
vim.opt.mouse = ""
-- Search
vim.opt.hlsearch = true
vim.opt.incsearch = true
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.wildmenu = true
-- Performance
vim.opt.updatetime = 100
-- Filetype-specific indentation
vim.api.nvim_create_augroup("FileTypeIndent", { clear = true })
-- Use Esc to exit terminal mode
vim.api.nvim_set_keymap('t', '<Esc>', '<C-\\><C-n>', {noremap = true})
local function set_indent(pattern, opts)
vim.api.nvim_create_autocmd("FileType", {
group = "FileTypeIndent",
pattern = pattern,
callback = function()
vim.opt_local.tabstop = opts.tabstop
vim.opt_local.shiftwidth = opts.shiftwidth
vim.opt_local.softtabstop = opts.softtabstop
vim.opt_local.expandtab = opts.expandtab
end,
})
end
set_indent("make", { tabstop=8, shiftwidth=8, softtabstop=0, expandtab=false })
set_indent("c", { tabstop=8, shiftwidth=8, softtabstop=8, expandtab=false })
set_indent("python", { tabstop=4, shiftwidth=4, softtabstop=4, expandtab=true })
set_indent("rust", { tabstop=4, shiftwidth=4, softtabstop=4, expandtab=true })
set_indent("yaml", { tabstop=2, shiftwidth=2, softtabstop=2, expandtab=true })
-- Verilog files (.v, .vs)
vim.api.nvim_create_autocmd({"BufNewFile", "BufRead"}, {
group = "FileTypeIndent",
pattern = {"*.v", "*.vs"},
callback = function()
vim.opt_local.tabstop = 4
vim.opt_local.shiftwidth = 4
vim.opt_local.softtabstop = 4
vim.opt_local.expandtab = true
end,
})
plugins.lua
return {
-- Statusline
{
"vim-airline/vim-airline",
dependencies = { "vim-airline/vim-airline-themes" },
config = function()
vim.g.airline_powerline_fonts = 1
end,
},
-- Git
{ "tpope/vim-fugitive" },
{
"lewis6991/gitsigns.nvim", -- gitgutter equivalent, native neovim plugin
config = function()
require("gitsigns").setup()
end,
},
-- tpope essentials
{ "tpope/vim-surround" },
{ "tpope/vim-commentary" },
{ "tpope/vim-repeat" },
{ "tpope/vim-sleuth" },
}
It seems like a nice upgrade, but the differences are subtle. Terminal Mode got me at first. Note this part
-- Use Esc to exit terminal mode
vim.api.nvim_set_keymap('t', '<Esc>', '<C-\\><C-n>', {noremap = true})
More?
I think at this point this may be the heaviest I want to make my editor, but we'll see. Maybe I'll publish it with a setup script as an alternative to the bigger options. There are also still a lot of shortcuts in Vim I ought to make much better use of before trying to add extra stuff. There's a great reference here.