Now I am about to write a lot of neovim configuration code, the first configuration will be settings that help me working with the configuration itself.
Read more about keyboard sequences and leader keys
Open and re-source the configuration
As I already mentioned that the number one reason for why I structure my configuration the way I do is because I need to be able to changes, when I'm in my daily work, and I find that something is lacking in my configuration. I need to quickly make the change, and get back to where I was, which is why closing and reopening vim for these kinds of changes is something I really want to avoid.
So the first thing, I do is setup keyboard shortcuts to edit and rerun, or "re-source" the configuration. This tip, I learned from Learn Vimscript The Hard Way
I also want to map my leader key to something easily accessible, and my thumb is always resting on the space bar, so that will be my leader key.
local function reload()
dofile(vim.env.MYVIMRC)
print("Configuration reloaded")
end
vim.g.mapleader = " "
vim.g.maplocalleader = " "
vim.keymap.set("n", "<leader>ve", ":tabnew $MYVIMRC<cr>", { desc = "Open neovim configuration file" })
vim.keymap.set("n", "<leader>vs", reload, { desc = "Re-source neovim configuration file" })
Note: while resourcing could have been achieved using :source $MYVIMRC
, I will later need to add more behaviour to the reloading, which is why I already have made a function for the behaviour. For more info, see :help :source
For more information on leader keys and mapping sequences, see Leader keys and mapping keyboard sequences
Escape hatch
The default key for exiting insert-mode, <Esc> is a little far away. I have remapped that to jk, a sequence of keys that quick exits to normal mode, and it's a sequence that is never used in real words or code sequences (I've used this mapping for about 8 years now, and the only time it conflicts with a real use case is when I write about my vim configuration) - this was also a tip I learned from "Learn Vimscript ...".
vim.keymap.set("i", "jk", "<esc>", { desc = "Exit insert mode" })
If you are used to vim, and want to adopt to this pattern, it can be helpful to remap <Esc>, to the no-op (see :help <nop>
)
vim.keymap.set("i", "<esc>", "<nop>")
I had this mapping setup when I first adopted this strategy. Now, it's no longer necessary for me.
Quicker save
After having used Windows for many years, I'm used to <Ctrl>+s for saving a file. And I have remapped the CAPS LOCK key to work as <Ctrl>, so that combination is one that only requires my left pinky to move slightly to the left to reach. I also want to have this mapping available in both normal and insert-mode, as every edit normally ends with a save anyway, i.e. after saving from insert-mode, I'll be back in normal mode for editing.
vim.keymap.set("n", "<C-s>", ":w<cr>", { desc = "Save current file" })
vim.keymap.set("i", "<C-s>", "<esc>:w<cr>", { desc = "Save current file" })
Sensible indentation
While writing the reload
function, vim by default inserted a tab
. I want spaced, and I want two of them.
vim.opt.expandtab = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.softtabstop = 2
Note, that these are now the default settings. Each file can overwrite the settings. E.g. in Go, I do want to have tabs1.
Disable swap file
Vim keeps a "swapfile" that serves as a backup while working, and can help recover unsaved work in the case of a crash. I don't find this very helpful. I save often, and I have version history in git.
The swapfile is not so much a nuisance in neovim as it was in vim, as neovim stores the swapfile away from your working directory. The vim versions I have used stored the swap file in the same folder as the edited file, making it a lot of noise in the file system.
vim.opt.swapfile = false
When connecting to a remote server, a swapfile can be helpful to recover from a broken connection. But tmux can also solve the same problem.
Line numbers
Showing line numbers can be helpful, as it helps you navigate quickly to the desired line, e.g. 30gg or 30G both jump straight to line 30. Relative line numbers on the other hand will show how many lines above or below each line is, often making for a shorter input, e.g. 8j, rather then 128gg.
Combine relativenumber
with number
to show the absolute line number for the current line, and relative numbers for all other lines
vim.opt.number = true
vim.opt.relativenumber = true
![[Pasted image 20240702110735.png|Screenshot showing the actual line number for the current line, and for all other lines, it shows the number of lines above or below]]
I have previously been a bit annoyed by the constant moving around of the numbers in the gutter, but right now I'm trying out relative numbers. I may disable it again in the future if I'm unhappy with it.
Note: Absolute line numbers may be more helpful for pair programming, as the navigator can quickly reference the concrete line, "I'm not sure the conditional logic on line 30 is correct" (the number remains correct even if the driver moves around at the same time).
Search options
By default, when searching with / or ?, the search is case sensitive. I generally don't want to be bothered with typing the right case. Just that the right letters are in the search should be enough. I set ignorecase
to have case insensitive search
When searching, the search results are highlighted, and the command :nohighlight
or :noh
disables it again. I have setup a shortcut to more quickly dismiss this
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.keymap.set("n", "<leader>h", vim.cmd.nohlsearch)
Remove useless functions
If the cursor is located on a number, the shortcuts <Ctrl>+a and <Ctrl>+x increments/decrements that number. Not only do I not have any use for this behaviour, <Ctrl>+a is also used to control tmux, which I normally use together with neovim.
When I am unexpectedly not in a tmux session, and I try to control tmux, I have on more than one occasion incremented a number, not realising it until I observe a bug in my code. So I get rid of these two useless mappings
vim.keymap.set("n", "<C-a>", "<nop>")
vim.keymap.set("n", "<C-x>", "<nop>")
A note on termguicolors
Other tutorials often set the termguicolors
. This shouldn't be necessary in neovim, only vim. By default neovim detects if your terminal supports 24-bit colours. If you find that colours are off if you don't enable this setting it's more likely that it's your terminal is misconfigured, not neovim. From :help termguicolors
Nvim will automatically attempt to determine if the host terminal
supports 24-bit color and will enable this option if it does
(unless explicitly disabled by the user).
Coming up
Now, I have the bare essentials up and running, and now is a good time to commit to the git repository. That's a task I want to perform from within neovim itself, so in the next part in the series, I will add git support to neovim, which again requires some kind of package management, so I'll also add a package manager rather than managing that by myself (although that is perfectly doable).
-
Go is so opinionated about formatting that there is only one way to format indentation, and that is using tabs. You can configure your editor to how you want it to look. It still uses spaces for alignment, ensuring it is not dependent on editor settings. ↩