This flake provides modules for NixOS and Home Manager, which provide the nixneovim
configuration options.
Using nixneovim
, you can configure Neovim, including plugins, through nix.
This makes your Neovim config reproducible, and easier to manage.
This was originally based on pta2002/nixvim. However, today, it shares very little code, approaches problems very differently, and is completely independent.
To use the modules, add this flake to the inputs of your nix configuration.
inputs.nixneovim.url = "github:nixneovim/nixneovim";
Then, apply the overlay and import the modules. This is needed, because NixNeovim uses NixNeovimPlugins to get access to more Neovim plugins.
{
nixpkgs.overlays = [
nixneovim.overlays.default
];
}
And import the module to your Home Manager (recommended) or NixOS configuration.
Depending on your nixos version, you have to import different modules.
In particular, the default
and homeManager
modules only work with the Nixpkgs/HomeManager unstable
releases.
When you use Nixos/HomeManager XX.XX, please import homeManager-XX-XX
or nixos-XX-XX
.
For example, when using Home Manager please use:
home-manager = {
users.<user> = {
imports = [
nixneovim.nixosModules.default # with Home Manager unstable
# nixneovim.nixosModules.homeManager-XX-XX # with Home Manager XX.XX
];
programs.nixneovim.enable = true;.
};
};
and when you do not use Home Manager please use:
imports = [
nixneovim.nixosModules.default # with Home Manager unstable
# nixneovim.nixosModules.homeManager-22-11 # with Home Manager 22.11
# nixneovim.nixosModules.nixos # without Home Manager
];
}
All options are documented at: NixNeovim Documentation. Alternatively, you can use this search: NixNeovim Options Search.
Finally, you can generate the docs using nix build .#docs
.
Importing the modules gives you access to the programs.nixneovim
config.
A wiki for all options will be available in the near future.
{
programs.nixneovim = {
enable = true;
extraConfigVim = ''
# you can add your old config to make the switch easier
${lib.strings.fileContents ./init.vim}
# or with lua
lua << EOF
${lib.strings.fileContents ./init.lua}
EOF
'';
# to install plugins just activate their modules
plugins = {
lspconfig = {
enable = true;
servers = {
hls.enable = true;
rust-analyzer.enable = true;
};
};
treesitter = {
enable = true;
indent = true;
};
mini = {
enable = true;
ai.enable = true;
jump.enable = true;
};
};
# Not all plugins have own modules
# You can add missing plugins here
# `pkgs.vimExtraPlugins` is added by the overlay you added at the beginning
# For a list of available plugins, look here: [available plugins](https://github.com/NixNeovim/NixNeovimPlugins/blob/main/plugins.md)
extraPlugins = [ pkgs.vimExtraPlugins.<plugin> ];
};
}
Warning: Using this is currently discouraged as it can cause build failures. I am working on it.
By default, NixNeovim prints all config to init.lua
in order to have a more stable config.
You can turn this off by setting nixneovim.usePluginDefaults
.
This way, NixNeovim will only print the configs you have changed.
Setting nixneovim.usePluginDefaults
to true
reduces the size of your init.lua
but can lead to unexpected changes of your setup,
when a plugin author decides to change their defaults.
You can define your key mappings using the mappings
option.
{
programs.nixneovim = {
mappings = {
normalVisualOp = {
";" = "':'"; # vimscript between ' '
};
normal = {
"<leader>m" = {
action = "'<cmd>make<cr>'"; # vimscript between ' '
silent = true;
};
"<leader>h" = "function() print(\"hi\") end"; # Lua code without ' '
};
};
};
}
This uses vim.keymap.set
under the hood.
Therefore, you can specify lua functions directly.
However, this also means, when writing vimscript, you have to put that between extra quotation marks.
This is equivalent to:
vim.keymap.set("", ";", ':')
vim.keymap.set("n", "<leader>m", '<cmd>make<cr>', { silent = true })
vim.keymap.set("n", "<leader>h", function() print("hi") end)
First, you specify the mode; you can choose between the keywords below.
NixNeovim | Neovim | Description |
---|---|---|
normalVisualOp | "" | Normal, visual, select, and operator-pending |
normal | "n" | Normal |
insertCommand | "!" | Insert and command-line |
insert | "i" | Insert |
command | "c" | Command-line |
visual | "v" | Visual and Select |
visualOnly | "x" | Visual |
select | "s" | Select |
operator | "o" | Operator-pending |
terminal | "t" | Terminal |
lang | "l" | Insert, command-line, and lang-arg |
When specifying the mapping with an attribute set you can set the following options.
NixNeovim | Default | VimScript |
---|---|---|
silent | false | <silent> |
nowait | false | <silent> |
script | false | <script> |
expr | false | <expr> |
unique | false | <unique> |
noremap | true | Use the 'noremap' variant of the mapping |
action | Action to execute |
You can define augroups with the augroups
option.
{
programs.nixneovim = {
augroups = {
highlightOnYank = {
autocmds = [{
event = "TextYankPost";
pattern = "*";
# Or use `vimCallback` with a vimscript function name
# Or use `command` if you want to run a normal vimscript command
luaCallback = ''
vim.highlight.on_yank {
higroup = (
vim.fn['hlexists'] 'HighlightedyankRegion' > 0 and 'HighlightedyankRegion' or 'IncSearch'
),
timeout = 200,
}
'';
}];
};
};
};
}
Until we find a better way of documenting this, you can find a list of supported language servers here: servers.nix
Contributions are very welcome. They help improve this project and keep it up to date.
- Look at the automatically generated issues. Those are plugins available in the original repo, but not yet in this. Start with those, if you like
- Copy
plugin_template.nix
orplugin_template_minimal.nix
- Add the following information:
name
pluginUrl
moduleOptions
extraPlugins
- If not otherwise specified,
mkLuaPlugin
will add the following string toinit.vim
:extraConfigLua = "require('${name}').setup ${toLuaObject pluginOptions}";
- This can be disabled with
defaultRequire = false
- When using the
plugin_template.nix
you add options to themoduleOptions
attribute set.
{
moduleOptions = with helpers; {
mappings = mkOption {
type = types.attrs;
default = { };
};
enableAuto = boolOption false "Enable auto expanding snippets";
};
}
- In
helper/custom_options.nix
we have defined several functions for basic plugin options like bool, strings or integer. - In particular, ther are:
boolOption, intOption, strOption, attrsOption, enumOption
- With
nix run .#configparser
you can convert a Lua setup configs to nix module options (you might need to update the submodule withgit submodule update tree-sitter-lua
). - For example, you can input the following Lua configs (taken from NvimTree; Example-comment added)
nix run .#configparser <<EOF
require("nvim-tree").setup({
sort_by = "case_sensitive",
view = {
-- Example comment
width = 30,
},
renderer = {
group_empty = true,
},
filters = {
dotfiles = true,
},
})
EOF
- The output will be
{
sort_by = strOption "case_sensitive" "";
view = {
# Example comment
width = intOption 30 "Example comment";
};
renderer = {
group_empty = boolOption true "";
};
filters = {
dotfiles = boolOption true "";
};
}
The output is best-effort and will likely contain errors.
For example, the script cannot detect if a variable is a string or an enum
.
Therefore, you likely have to edit and correct the output before you add it to the module.
{
programs.nixneovim = {
options = {
number = true; # Show line numbers
relativenumber = true; # Show relative line numbers
shiftwidth = 2; # Tab width should be 2
};
};
}
Please note that to, for example, disable numbers you would not set
options.nonumber
to true, you'd set options.number
to false.
Sometimes you might want to define a global variable, for example to set the
leader key. This is easy with the globals
attribute:
{
programs.nixvim = {
globals.mapleader = ","; # Sets the leader key to comma
};
}