Add article about vim configuration.
This commit is contained in:
parent
04f8994933
commit
80a277b062
BIN
content/images/nvim-which-keys.png
Normal file
BIN
content/images/nvim-which-keys.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
327
content/software/nvim-configure.md
Normal file
327
content/software/nvim-configure.md
Normal file
@ -0,0 +1,327 @@
|
||||
---
|
||||
Title: Setup Neovim with kickstart.nvim
|
||||
Date: 2023-12-25 14:00
|
||||
Lang: en
|
||||
Author: Fabrice
|
||||
Category: software
|
||||
Tags: vim, neovim, setup
|
||||
Slug: nvim-kickstart
|
||||
table-of-contents: true
|
||||
Header_Cover: ../images/covers/antennae.jpg
|
||||
Summary: How to create a sane Neovim configuration with kickstart.nvim as a
|
||||
starting point.
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
## How I managed my configuration
|
||||
|
||||
When I started using Vim, I started editing my `.vimrc` bit by bit and
|
||||
incrementally before it starts getting too big for me to find anything inside
|
||||
it and not using even half of the plugins I installed. That goes without saying,
|
||||
there were quite a bit on conflicting keymaps as well as I'm using
|
||||
[bépo](http://bepo.fr/) as my keyboard layout with [partial remaps
|
||||
(fr)](https://cdn.bepo.fr/Vim-bepo-066.png).
|
||||
|
||||
Obviously, it slowly became quite a mess. To address this issue, I
|
||||
decided to reorganise my `$HOME/.config/vim` directory using the [vim directory
|
||||
structure](www.panozzaj.com/blog/2011/09/09/vim-directory-structure/) and did
|
||||
some cleanup at this point of time. I think it was also around this period that
|
||||
I discovered that Vim8 added a native package manager that I started to use.
|
||||
Thus, at this point, I started organising my configuration with semantic files,
|
||||
such as `$VIMHOME/plugin/spelling.vim` to manage my spelling configuration for
|
||||
instance. This approach makes debugging easier, and also checking custom
|
||||
keyboard shortcuts easier, as I just have to check
|
||||
`$VIMHOME/plugin/omnicomplete.vim` for instance to know which shortcuts I set up
|
||||
when I'm still getting the habits of using them.
|
||||
|
||||
At some point of time, I moved to Neovim, and I simply moved my configuration
|
||||
from Vim to Neovim and continue on adding more and more plugins on top of each
|
||||
other depending on my hype, especially because the world of Neovim plugins
|
||||
opened up to me. Needless to say that less than half of these plugins were put
|
||||
into good use. Which leads to my first configuration big cleanup.
|
||||
|
||||
Six months ago, I wiped my frankenconfig, and started back from scratch in
|
||||
[lua](https://lua.org/about.html), with the same structural approach as
|
||||
previously, but now wondering if the plugin would be useful or not. Since my
|
||||
first time using Vim, there were some big changes in the vim ecosystem,
|
||||
especially in language management with
|
||||
[tree-sitter](https://tree-sitter.github.io/tree-sitter/) and
|
||||
[lsp](https://en.wikipedia.org/wiki/Language_Server_Protocol). These two bring
|
||||
into the environment a unified way to manage languages without having to depend
|
||||
on language-specific plugins, henceforth I didn't need specific plugins to have
|
||||
nice syntax coloration for obscure languages anymore, or get frustrated with
|
||||
[omnicomplete](https://vim.fandom.com/wiki/Omni_completion) which decided not to
|
||||
work for some languages… While it's not an absolute rule (for instance, I'm
|
||||
using [vimtex]({filename}./nvim-latex.md) for latex, which includes a more
|
||||
accurate syntax coloring than tree-sitter). I also moved from the native vim way
|
||||
of managing plugins to use [`Lazy`](https://github.com/folke/lazy.nvim) as a
|
||||
proper plugin manager, which helped me synchronize my configuration between my
|
||||
different computers. It was working nice and well, with some weird bugs (see
|
||||
below) on first install, but as it was punctual… I just ignored it.
|
||||
|
||||
```plain
|
||||
E5113: Error while calling lua chunk:
|
||||
$VIMHOME/nvim/init.lua:13: E21: Cannot make changes, 'modifiable' is off
|
||||
```
|
||||
|
||||
However, I was unhappy with some of my configurations, and if I managed to have
|
||||
something functional, there were many details that annoy me that stemmed for
|
||||
some configuration I wrote some times ago and of course didn't document. This
|
||||
leads us to today, where I just decided to use
|
||||
[`kickstart.nvim`](https://github.com/nvim-lua/kickstart.nvim), which is a
|
||||
well-documented vim starting configuration (it's not a distribution, it still
|
||||
requires your input to obtain something that fits your needs), which was exactly
|
||||
what I needed to start anew… but not fully from scratch.
|
||||
|
||||
## The migration
|
||||
|
||||
To move my configuration from `kickstart.nvim`, I wanted to get the best of both
|
||||
world. For instance, I didn't want to have an
|
||||
[`init.lua`](https://github.com/nvim-lua/kickstart.nvim/blob/master/init.lua)
|
||||
that is over 600 lines long. I thus decided to split it into short files that
|
||||
manages a specific part of the configuration: completion, lsps, treesitter,
|
||||
mappings after reading the different configuration default from nvim-kickstart
|
||||
and changing what I disliked. To do that, I started with using the
|
||||
[`NVIM_APP`](https://practical.li/neovim/configuration/) environment option in
|
||||
order to make the move in a non-destructive way. After installing the bare
|
||||
minimum to make it usable for me (as a bépo user), I exported the `NVIM_APP`
|
||||
variable to start using my configuration to help me debug it on the fly.
|
||||
I also decided to write this blog post to remember the process and maybe helped
|
||||
some people who want to configure their text editor.
|
||||
|
||||
Note that in the following, we will assume that the reader is already familiar
|
||||
with Neovim and lua.
|
||||
|
||||
# Configuring Neovim
|
||||
|
||||
My (in use) configuration for Neovim is available [here](https://git.epheme.re/fmouhart/nvim-config-kickstart).
|
||||
|
||||
I started using git from the start in order to remember what I did by using its
|
||||
[history](https://git.epheme.re/fmouhart/nvim-config-kickstart/commits/branch/master).
|
||||
As it's not the easier thing to read however, here follows my rationals, and
|
||||
thought during this process in a chronological order.
|
||||
|
||||
## kickstart.nvim
|
||||
|
||||
`kickstart.nvim` is a starting Neovim configuration file which was created by
|
||||
[TJ DeVries](https://github.com/tjdevries), a core developer of Neovim, author
|
||||
of [telescope.nvim](https://github.com/nvim-lua/telescope.nvim) and content
|
||||
creator about Neovim. You can see a quick presentation on his YouTube channel
|
||||
[[here]](https://www.youtube.com/watch?v=stqUbv-5u2s).
|
||||
|
||||
To summarise, it is a starting configuration including a minimal set of plugins
|
||||
that helps to have a modern editor, that has a working and customizable LSP
|
||||
configuration with [Mason](https://github.com/williamboman/mason.nvim) to help
|
||||
install LSP servers, git helpers, completion, telescope, and a choice of
|
||||
shortcuts that are quite natural to learn (unlike what I used previously because
|
||||
I was simply adding shortcuts one after another without thinking of the
|
||||
compatibility between them).
|
||||
|
||||
Note that it is made for educational purpose, and thus is not modularised as is
|
||||
(hence the single self-contained `init.lua` file). Which leads us to our first
|
||||
step after simply pasting the content of `init.lua` into the `$VIMHOME/init.lua`
|
||||
file.
|
||||
|
||||
## Modular configuration
|
||||
|
||||
When in doubt about some shortcuts, I'm under the habit of going to read the
|
||||
corresponding configuration file in my `$VIMHOME/plugin` directory.
|
||||
`kickstart.nvim` includes `which-key`, that is a plugin that pops a helper when
|
||||
waiting for a command as shown hereunder.
|
||||
|
||||
[![which-key plugin
|
||||
illustration](../images/nvim-which-keys.png)](../images/nvim-which-keys.png)
|
||||
|
||||
Thanks to that, I start getting rid of this habit. However, having a modular
|
||||
configuration helps debugging it. Usually, when an error spawns, the filename
|
||||
and location of what has triggered it appears in the stack trace, and it's
|
||||
easier to search in a short file than a thousand-line long one.
|
||||
|
||||
After a first read of the configuration file, I decided to split it into smaller
|
||||
files. Note that if you want to start directly from there a project that does
|
||||
exactly that exists:
|
||||
|
||||
* [kickstart-modular.nvim](https://github.com/dam9000/kickstart-modular.nvim)
|
||||
|
||||
However, I find it easier for educational purpose to have everything in one
|
||||
place to linearly read it first.
|
||||
|
||||
The process was quite simple, as the file was already divided logically into
|
||||
components that make sense, I just had to take the content of those sections and
|
||||
move them into the `$VIMHOME/lua` folder before including them in `init.lua`. I
|
||||
hesitated to continue using the `$VIMHOME/plugin` directory for that, but I then
|
||||
realised that having it inside init.lua allows having a structure that allows
|
||||
using `init.lua` as an index, and I can start
|
||||
[jumping](https://vimhelp.org/motion.txt.html) from there to access my
|
||||
specific configurations.
|
||||
|
||||
To illustrate it, let's take the example of completion. In `kickstart.nvim`,
|
||||
there is a section called "Configure nvim-cmp", that deleted and pasted into a
|
||||
file `$VIMHOME/lua/complete.lua` before adding the line `require('complete')` to
|
||||
load it. You can see the result in this
|
||||
[commit](https://git.epheme.re/fmouhart/nvim-config-kickstart/commit/7ce423fade9d6877b2e9174dd9b9dea36254ac19).
|
||||
|
||||
## Survival
|
||||
|
||||
Now that it's done, I need my basic keymaps for using Vim/Neovim in bépo. I
|
||||
added the file `$VIMHOME/lua/bepo.lua` and simply load it with a line
|
||||
`require('bepo')` in my `$VIMHOME/init.lua` file.
|
||||
|
||||
I also merged my personal remap inside the `$VIMHOME/lua/mappings.lua` file
|
||||
which already contained the ones imported from `kickstart.nvim` from the
|
||||
previous step. These mappings are convenient ones such as the following one to
|
||||
easily open folds to a given level.
|
||||
|
||||
```lua
|
||||
local keymap = vim.keymap.set
|
||||
|
||||
-- z0…z9 to open folds to a certain level
|
||||
for i=0,9 do
|
||||
keymap('n', 'z' .. i , ':set fdl=' .. i .. '<CR>', {noremap = true, silent = false})
|
||||
end
|
||||
```
|
||||
|
||||
I also merged and cleaned redundant general options in the
|
||||
`$VIMHOME/lua/general-options.lua` file. For instance to ignore folded content
|
||||
when jumping between paragraphs for instance, there is the following line in the
|
||||
aforementioned file:
|
||||
|
||||
```lua
|
||||
-- folds
|
||||
vim.g.ip_skipfold=true
|
||||
```
|
||||
|
||||
Once all of that is done, at this point of time, I started moving to use the
|
||||
configuration by exporting `NVIM_APP=new_nvim` inside my `.zshrc`. The idea is
|
||||
that now I bootstrapped my Neovim config to proficiently edit the configuration,
|
||||
which in lua also uses LSP and many of `kickstart.nvim` features. During this
|
||||
process I notice what I liked and disliked to know how to edit the configuration
|
||||
while editing the configuration.
|
||||
|
||||
## Importing my former configuration
|
||||
|
||||
After having the minimal setup top edit a configuration, I now need to make
|
||||
things work for other things as well.
|
||||
|
||||
That is dependent of your workflow. For reference, I personally use Neovim to:
|
||||
|
||||
* Write text in [markdown](https://daringfireball.net/projects/markdown/) (such as what I'm currently doing)
|
||||
for different purposes;
|
||||
* blog post, emails or more generally text blocks that will be exported in
|
||||
html.
|
||||
* Read text written in Markdown;
|
||||
* Try to organise my life using [neorg](https://github.com/nvim-neorg/neorg);
|
||||
* [LaTeX](https://en.wikipedia.org/wiki/LaTeX) documents and slideshows;
|
||||
* Write code in a variety of languages.
|
||||
|
||||
To do that I went to my previous configuration (which fortunately was already
|
||||
using [`Lazy`](https://github.com/folke/lazy.nvim) as a plugin manager). To do
|
||||
that, I picked my specific plugins, for instance `Neorg`, to import the
|
||||
configuration. For the example of `Neorg` it has multiple steps as I had a
|
||||
`$VIMHOME/plugin/neorg.lua` that contained my general configuration and
|
||||
`$VIMHOME/ftplugin/norg.lua` which has specific configuration when editing a
|
||||
note in `Neorg`.
|
||||
|
||||
After asking `Lazy` to install `Neorg`, I first imported the general
|
||||
configuration from my previous `plugin` folder in my new `lua` folder, as
|
||||
depicted by this
|
||||
[commit](https://git.epheme.re/fmouhart/nvim-config-kickstart/commit/0e8587b461b67082c1e34ef9cb07180ccfee9f8b).
|
||||
|
||||
After wondering if I should create a `ftplugin` directory, I finally decided to
|
||||
move to autocommands to manage different filetypes. The reason behind that was
|
||||
that I had a limited amount of lines in total in my former `ftplugin` directory,
|
||||
and the subdivision with `augroup` and `autocmd` in Vim makes it reasonably
|
||||
readable. Which brought me to this
|
||||
[commit](https://git.epheme.re/fmouhart/nvim-config-kickstart/commit/c506a7ea7868ba80dc053a59cbb66c5efa666e2c).
|
||||
|
||||
Then some sanity and cleanup have been made. For example, adding a description
|
||||
field to my key maps so that `which-key` nicely prints them. See this
|
||||
[commit](https://git.epheme.re/fmouhart/nvim-config-kickstart/commit/689bb2024d97fdc9e5e656517f00e446e95ae198).
|
||||
|
||||
Now, rinse and repeat for each plugin/specific configuration set: `vimtex`,
|
||||
`vim-pandoc-syntax` (which I mainly use for the
|
||||
[concealer](https://vimhelp.org/syntax.txt.html#conceal)), spelling
|
||||
configuration, etc.
|
||||
|
||||
All the while keeping a critical eye on what I'm moving. For instance, I have a
|
||||
mapping on the following command to fix typo on a misspelled word under the
|
||||
cursor when writing text: <code>mz[s1z=\`z</code>. However, the key was bound at
|
||||
anytime, even when spelling was not enabled. To fix that, we changed the way the
|
||||
binding was called: instead of being called everytime, we embedded it inside an
|
||||
[`autocmd`](https://vimhelp.org/autocmd.txt.html#autocommands) which [triggers
|
||||
when the option](https://vimhelp.org/autocmd.txt.html#OptionSet) `spell` is set.
|
||||
To see the resulting configuration, see these two files:
|
||||
[`autocommands.lua`](https://git.epheme.re/fmouhart/nvim-config-kickstart/src/commit/d0afa1066cabab3d2b0aa7e2e84a267ce0532c61/lua/autocommands.lua#L32-L37)
|
||||
for the autocommand setting, and
|
||||
[`spelling.lua`](https://git.epheme.re/fmouhart/nvim-config-kickstart/src/commit/d0afa1066cabab3d2b0aa7e2e84a267ce0532c61/lua/spelling.lua)
|
||||
for the utils module.
|
||||
|
||||
Just for the record, this is what it does:
|
||||
|
||||
1. Store the current cursor location: `mz` [sets a
|
||||
mark](https://vimhelp.org/motion.txt.html#mark) z on current position;
|
||||
2. [Go to the previous spelling error](https://vimhelp.org/spell.txt.html#%5Bs): `[s`;
|
||||
3. [Pick the first spelling suggestion](https://vimhelp.org/spell.txt.html#z%3D): `1z=`;
|
||||
4. Go back to the stored location: <code>\`z</code> [jumps to
|
||||
mark](https://vimhelp.org/motion.txt.html#%60) z at the right column.
|
||||
|
||||
## Adjusting the configuration
|
||||
|
||||
While testing the default behaviour of `kickstart.nvim`, which changes quite a
|
||||
few things for me, I realised that some of them were quite smart, such as
|
||||
<Space> as the leader key, which was on `,` before because of its accessibility
|
||||
in bépo, disabling quite a [useful motion
|
||||
binding](https://vimhelp.org/motion.txt.html#%2C), some are more personal
|
||||
tastes, such as the default register to be the system one or not.
|
||||
|
||||
I thus tried some of these options and decided while editing the configuration
|
||||
and writing this blog post which one where working nicely for me (with the help
|
||||
of `which-key` to help me during this whole process), and which one were not
|
||||
quite working (`unnamedplus` as default clipboard, I really use both separately,
|
||||
and I don't want to have my system clipboard polluted)
|
||||
|
||||
Moreover, `:healthcheck which-keys` was really helpful to debug some colliding
|
||||
key bindings, especially because of bépo, which has been incrementally fixed
|
||||
while editing the configuration. I already wrote a blog post about how I handle
|
||||
those in [vimtex]({filename}./nvim-latex.md).
|
||||
|
||||
My former configuration also featured LSP, but Mason was not used, which made me
|
||||
install my LSP server from my system package manager. However, I still prefer
|
||||
using the system one for some languages that features some changes between
|
||||
versions, which I [also
|
||||
configured](https://git.epheme.re/fmouhart/nvim-config-kickstart/src/commit/d0afa1066cabab3d2b0aa7e2e84a267ce0532c61/lua/lsp.lua#L120-L149)
|
||||
in the `$VIMHOME/lua/lsp-configure.lua` file.
|
||||
|
||||
# Final thoughts
|
||||
|
||||
To conclude, I would like to say thanks to the French
|
||||
[tuppervim](https://tuppervim.org) community, which regularly organises meetings
|
||||
where we can show our latest configuration file, or just exchange nice tips. I
|
||||
discovered both [TJ DeVries](https://www.youtube.com/c/TJDeVries) and
|
||||
[`kickstart.nvim`](https://github.com/nvim-lua/kickstart.nvim) there.
|
||||
|
||||
I still have to get rid of some habits (such as the comma as a leader key) and
|
||||
get used to it, but I'm happy with the change so far, beside knowing exactly
|
||||
what is in my configuration, it also helped me fix some weird key conflicts
|
||||
while editing markdown, making writing this blog post quite pleasant.
|
||||
|
||||
While trying the Git-related key bindings utilities bundled with
|
||||
`kickstart.nvim`, while being quite minimal, it still filled my needs
|
||||
(especially adding a hunk from visual selection, which is helpful to split
|
||||
commits into sub-blocks when `git add -p` would have been quite tedious to use).
|
||||
|
||||
The [status bar](https://github.com/nvim-lualine/lualine.nvim) was also a
|
||||
pleasant surprise for me. It is exactly the kind of things I find useful but a
|
||||
pain to configure. I may tweak it a bit in the future, but so far it's fine as
|
||||
it is.
|
||||
|
||||
The configuration will continue to evolve from this point, as my use of computer
|
||||
and Neovim will change as well. And to finish, I think what TJ Devries said in
|
||||
[this video](https://www.youtube.com/watch?v=QMVIJhC9Veg) about text editor is
|
||||
quite on point: you don't have to spend time in your configuration if it is not
|
||||
fun for you, just take something that works for you. I actually took the time to
|
||||
do it because I find it interesting and fun 🙂
|
||||
|
||||
If you also find it fun, and want to try it, I strongly encourage you to take a
|
||||
cup of hot cocoa, put on some relaxing music, and just dive head first!
|
Loading…
Reference in New Issue
Block a user