Nixvim Manager (yalms.nvm)
Table of Contents
Nixvim Manager
Nixvim Manager lets you run multiple Neovim configurations on the same machine, each with its own plugins, settings, and keymaps. Each configuration is a self-contained Nixvim instance built with Nix.
You define instances by directory — for example, use one config when working in ~/work
and a different one when editing ~/personal projects. The manager picks the right
binary automatically based on your current working directory.
It provides:
- An
nvCLI tool to manage instances from the terminal - Automatic instance selection based on your current directory
- Neovim integration for building, rebuilding, and managing instances interactively
Usage Guide
Prerequisites
- Nix package manager installed
- Home Manager configured (recommended)
Installation via Home Manager
This is the recommended installation path. It installs the nv CLI tool and sets up your
first instance automatically.
Step 1: Add the flake input
Add YALMS to your flake inputs:
{
inputs = {
yalms.url = "github:anomalyco/yalms";
# ... other inputs
};
}
Step 2: Import the module
Import the Nixvim Manager Home Manager module:
{
imports = [
inputs.yalms.homeManagerModules.nixvim-manager
];
}
Step 3: Enable and configure instances
{
programs.nixvim-manager = {
enable = true;
settings = {
nixvims = {
default = {
module = { opts.number = true; };
dirs = [ "~/projects" ];
};
};
};
};
}
When you apply this configuration, Home Manager:
- Installs the
nvCLI tool - Creates instance declarations in
$HOME/nixvim/declarations.json - Writes Nix module files to
$HOME/nixvim/<name>/nixvim.nix - Runs
nv -fnc initto build all instances - Automatically registers the default instance with the YALMS Neovim plugin
Daily Usage with the nv CLI
Once installed, manage your instances from the terminal:
# Build or rebuild all configured instances
nv -fnc init
# Add a new Nixvim instance
nv add myconfig --module '{ opts.number = true; }'
# Rebuild a specific instance
nv build myconfig
# See which Nixvim binary to use for a given directory
nv resolve ~/.config/nvim
After building, each instance produces a nvim binary at
~/.nixvim/<name>/result/bin/nvim.
Configuring Instances
Each instance needs a Nix expression that defines its Neovim configuration. In the Home Manager setup, you provide this as a Nix module:
programs.nixvim-manager.settings.nixvims = {
myconfig = {
module = { opts.number = true; opts.relativenumber = true; };
dirs = [ "~/myproject" ];
};
};
| Option | Type | Description |
|---|---|---|
module |
string or lambda | Nix expression for the Nixvim module |
dirs |
list of strings | Directories this instance serves |
link |
null or string |
Optional path to symlink the instance binary to |
The dirs list controls which directory triggers this instance. When you are in
~/myproject or any subdirectory, nv resolve returns this instance's binary.
Extending the default instance
The Home Manager module creates a builds.default that you can extend in other instances.
This lets you share a base configuration:
programs.nixvim-manager.settings.nixvims = {
myconfig = {
module = { builds, ... }: builds.default.extend {
opts.relativenumber = true;
};
dirs = [ "~/myconfig" ];
};
};
You can also use the np argument to import additional Nixvim modules:
module = { builds, np, ... }: builds.default.extend {
imports = [ np.nixvimModules.langs.svelte ];
opts.clipboard = "unnamedplus";
};
Quick Setup Without Home Manager
You do not need Home Manager. You can set everything up from inside Neovim:
-- Enable with defaults (stores instances in ~/.nixvim)
require('yalms.nvm').setup(true)
-- Or with a custom directory and instances
require('yalms.nvm').setup({
dir = vim.fn.stdpath("data") .. "/nvm",
nixvims = {
default = {
name = "Default",
dirs = { vim.fn.stdpath("config") .. "/nixvim" },
module = [[
{ opts.number = true }
]]
}
},
force_rebuild = false,
})
After calling setup(), access the manager from anywhere in Neovim:
local nvm = require('yalms.nvm').get()
Developer Guide
Programmatic Instance Management
Add a new instance at runtime:
local nvm = require('yalms.nvm').get()
nvm:add({
name = "myconfig",
dirs = { "~/.config/nvim" },
module = [[
{ opts.number = true; opts.relativenumber = true; }
]]
}, function(err, nixvim)
if err then
print("Error: " .. err)
else
print("Added: " .. nixvim.name .. " -> " .. nixvim.link)
end
end)
Rebuild an instance (defaults to "default"):
nvm:rebuild("myconfig", function(err, nixvim)
if err then
print("Build failed: " .. err)
else
print("Built successfully: " .. nixvim.status)
end
end)
Configuration Reference
| Option | Type | Default | Description |
|---|---|---|---|
dir |
string or function | $NIXVIM_MANAGER_DIR or ~/.nixvim |
Directory for flake files and config |
nixvims |
table | {} |
Instances to register at startup |
force_rebuild |
boolean | false |
Rebuild all instances on load regardless of saved status |
Each instance entry requires a name (used as the flake attribute), a dirs array
(directories this instance serves, used for automatic binary resolution), and optionally
a module (Nix expression written to the instance's nix file).
Automatic Binary Resolution
The manager matches your current directory against each instance's dirs array, picking the
longest prefix match. If no match is found, it falls back to the instance with no dirs
constraint (the default).
local link = nvm:resolve_link(vim.fn.getcwd())
if link then
vim.cmd('exec ' .. link .. '/bin/nvim')
end
Events
The manager emits lifecycle events. Register callbacks with on():
| Event | Fires when |
|---|---|
"index" |
Configuration is first loaded from disk |
"ready" |
Initial load and queued builds are complete |
"change" |
Configuration changes (add, update, remove, build) |
"build" |
A build starts or finishes |
"remove" |
An instance is removed |
local nvm = require('yalms.nvm').get()
nvm:on("build", function(e, payload)
print("Build status for " .. payload.nixvim.name .. ": " .. payload.nixvim.status)
end)