This is my neovim configuration implemented as a flake. Thanks to the power of nix and flakes, my whole neovim configuration can be built with a single command.
Based on the template from kickstart-nix.nvim. If you come from this template, please know that I made some slights modifications a little.
Some of the features:
- Neovim nightly.
- LSPs, linters, formatters for Python.
- Use Neorg for note taking.
Note: Many LSPs, formatters and others are not packaged in this flake. You have to provide them yourself. See this debate for more.
There are multiple themes available and you can activate a specific theme by
passing the config.theme
value to the nix package at build time. You can
choose between the following themes:
You can also configure whether you want the background to be transparent or not
using the config.transparentBackground
value.
See ./nix/module.nix
for the available option values.
If you have Nix installed (with flakes enabled), you can test drive this by running:
nix run "github:pierrot-lc/nvim-nix"
Add this flake to your NixOS flake inputs.
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
nvim-nix = {
url = "github:pierrot-lc/nvim-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
# ...
};
# ...
}
Overlays are a way to provide additional packages to the list of available
pkgs
. This flake output such overlay to add our nvim-pkg
derivation to
pkgs
. Here is a minimal example with home-manager:
# flake.nix
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
nvim-nix = {
url = "github:pierrot-lc/nvim-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs @ {
self,
nixpkgs,
home-manager,
...
}: let
system = "x86_64-linux";
lib = nixpkgs.lib;
pkgs = import nixpkgs {
inherit system;
config = {
allowUnfree = true;
};
overlays = [
# We provide our `nvim-pkg` package by giving the overlay here.
inputs.nvim-nix.overlays.${system}.default
];
};
in {
homeConfigurations = {
username = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
./home.nix
];
};
};
};
}
# home.nix
{pkgs, ...}: {
home.packages = with pkgs; [
nvim-pkg # This package will be found thanks to the added overlays.
];
}
This flake also provide a module. It provides an interface to provide options
before building the derivation. You can have a look into ./nix/module.nix
to
see the available options for yourself, along with their default values.
To make this work, you do not have to add this flake overlay but you have to provide the module. Here is a minimal example:
# flake.nix
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
nvim-nix = {
url = "github:pierrot-lc/nvim-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs @ {
self,
nixpkgs,
home-manager,
...
}: let
system = "x86_64-linux";
lib = nixpkgs.lib;
pkgs = import nixpkgs {
inherit system;
config = {
allowUnfree = true;
};
};
in {
homeConfigurations = {
username = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
./home.nix
# Add the module here.
inputs.nvim-nix.nixosModules.${system}.default
];
};
};
};
}
# home.nix
{pkgs, ...}: {
nvim-nix = {
enable = true;
theme = "gruvbox";
transparentBackground = true;
};
}
- Manage plugins + external dependencies using Nix (managing plugins shouldn't be the responsibility of a plugin).
- Configuration entirely in Lua1 (Vimscript is also possible). This makes it easy to migrate from non-nix dotfiles.
- Usable on any device with Neovim and Nix installed.
- Ability to create multiple derivations with different sets of plugins.
- Use either nixpkgs or flake inputs as plugin source.
- Use Neovim's built-in loading mechanisms.
- See
:h initializaion
and:h runtimepath
.
- See
- Use Neovim's built-in LSP client.
This derivation creates an init.lua
as follows:
- Add
nvim/lua
to theruntimepath
. - Add the content of
nvim/init.lua
. - Add
nvim/*
to theruntimepath
. - Add
nvim/after
to theruntimepath
.
This means that modules in nvim/lua
can be require
d in init.lua
and
nvim/*/*.lua
.
Modules in nvim/plugin/
are sourced automatically, as if they were plugins.
Because they are added to the runtime path at the end of the resulting
init.lua
, Neovim sources them after loading plugins.
You can use nix-portable to bundle the derivation into a dependency-free executable.
nix bundle --bundler github:DavHau/nix-portable -o bundle
You still need nix to generate the bundle, but then you can simply pass around
the generated ./bundle/bin/nvim
wherever you want and execute your nvim
package!
Make sure that the target machine has no conflicting nvim configuration. Have a
look at ~/.config/nvim
, ~/.local/share/nvim
and ~/.local/state/nvim
, and
remove those directories if you have any conflict (make sure to make a backup
before if you have important data there).
Footnotes
-
The absence of a Nix module DSL for Neovim configuration is deliberate. If you were to copy the
nvim
directory to$XDG_CONFIG_HOME
, and install the plugins, it would work out of the box. ↩