I like Vim. People reading this should have noticed by now. Up until now, I've always been running a vanilla Vim with various adjustments and plugins. Vim distributions and forks regularly appear in my feeds. I also regularly look at LunarVim, SpaceVim and whatever they're called, but I usually stick with my hand-built
Vim +
vimrc. But now something came into my field of vision that hooked me:
NixVim.
0x01 - OVERVIEW
What exactly is
NixVim?
NixVim claims to be a NeoVim distribution, but unlike similar projects such as
LunarVim or
SpaceVim,
NixVim is based on being completely configurable via Nix modules. This means that NeoVim is not installed as a single package and configured via dot files, but is treated as a module in the
configuration.nix. This of course has the great advantage that if you change systems or reinstall, you can simply move your Vim config within the NixOS config and have your beloved and fully configured editor in front of you in no time.
0x02 - INSTALLATION
The installation of
NixVim is as easy as usual. In my case, there is a file called
"nixvim.nix" in the NixOS config path, as I have not (yet) switched to Flakes and Homemanager. The file itself is called up in
configurations.nix via import:
CONFIGURATION.NIX
imports = [./modules/nixvim.nix];
Of course, that alone is not enough. Inside
nixvim.nix happens what installs
NixVim or NeoVim and takes care of plugins, themes and configuration:
nixvim.nix
let
nixvim = import (builtins.fetchGit {
url = "https://github.com/nix-community/nixvim";
});
in
{ imports = [nixvim.nixosModules.nixvim];
programs.nixvim = {
enable = true;
};
}
After rebuilding and calling
$> nvim, NeoVim *magically* runs.
Yes! - but it runs completely in default. I don't think anyone who uses Vim seriously and regularly does so in default. What makes Vim and NeoVim interesting is the high level of configurability through plugins. NeoVim itself is compatible with Vim plugins (VimScript) but also builds its own interface for plugins that can interact with NeoVim-specific plugins (in this case in Lua).
0x03 - PLUGINS
There are currently
~1700 packages in the nix packages that are listed as
vimPlugins.***. So every plugin you need should be available. By default, the plugin manager (Pathogen, Pack, Vundle, etc.) takes care of installing and managing the plugins. The disadvantage of this quickly becomes apparent when you want to get your Vim running on another system. Annoying re-installing of plugins and other modules, configs, etc. Fortunately, NixOS and therefore also
NixVim are committed to reproducibility. In the future, we will be able to install all plugins and changes via
nixvim.nix. A clear list of plugins and their config options is provided in the documentation of
NixVim itself (
LINK). Basically, the installation of plugins follows the following syntax:
plugins.pluginname.enable = true; - so everything is as usual. How you structure your plugins is completely up to you. I have structured my plugins within
nixvim.nix as follows:
nixvim.nix
programs.nixvim = {
plugins = {
telescope = {
enable = true;
};
alpha = {
enable = true;
theme = "dashboard";
};
};
}
This allows you to manage all plugins in a structured manner and the whole thing can be reproduced in just one
nix file.
The same pattern applies to the settings or basic settings of NeoVim.
0x04 - CONFIG
Ok. Plugins are one thing - but you don't always need plugins for basic settings. Some options simply belong in
vimrc or, in NeoVim, in
init.lua. However, if I want to configure everything using the NixOS module, then without exception. So NeoVim options don't go in a separate file but also in
nixvim.nix. The whole thing works in a similar way to plugins. NeoVim or
NixVim doesn't have any line numbers by default. But they are quite useful - especially in NeoVim:
nixvim.nix
opt = {
number = true;
};
Instead of
"plugins.{pluginname}.enable" we go the route of
"opt.{optname}.true". This allows you to configure tabs, cursor lines, split behavior, line numbers and so on. Everything under the option
"opt".
What makes Vim/NeoVim so powerful is the ability to control everything via keyboard shortcuts. Keymappings can of course also be controlled within
nixvim.nix.
0x05 - KEYMAPS
The key combos that Vim/NeoVim offers are not always optimally chosen and you quickly get to the point where you would like to map some combinations differently. As with the options so far, this is of course also possible in
NixVim. Here, too, we simply swap
plugins.* or
opt.* for
keymaps.*. Keymaps are a little more complex and no longer consist of one-liners but are defined by submodules, but it remains understandable. For example, ESC can be mapped to deactivate the search highlighting of
hlsearch in normal mode:
nixvim.nix
keymaps = [
{
mode = "n";
key = "<ESC>"
action = "<cmd>nohlsearch<CR>";
}
];
mode defines the mode in which the mapping takes effect, in this case
n - Normal Mode, the option
key refers to the key that should be used and
action defines what happens, in this case the unmarking of the searched string. With these submodules, all the key combos you need are possible.
0x06 - CONCLUSION
Even if the switch from Vim to NeoVim feels a bit strange, it's worth it. These are probably just nostalgic thoughts that are completely unfounded, because Vim remains the basis. The advantage of NeoVim is of course the broad community that contributes to and develops it, but the switch from VimScript to Lua also brings a bit of speed to Vim. The whole thing now in combination with the central configurability of
NixVim is a dream. No more installing plugins or similar. Just load the module - done.
Happy hacking!