-
Notifications
You must be signed in to change notification settings - Fork 466
NixOS Support
This repository contains the homeManagerModule
for home-manager using flakes.
No matter which OS you are using, you can use this configuration out of the box, as long as you use home-manager to manage your environment.
Add the home-manager
URL and nvimdots
to inputs
in the top-level flake.nix
.
Next, add the following snippets to your configuration.nix
and nvimdots.nix
.
Re-login to your shell after executing nixos-rebuild switch --flake <flake-url>
or home-manager switch --flake <flake-url>
.
flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nvimdots.url = "github:ayamir/nvimdots";
home-manager = {
url = "github:nix-community/home-manager";
nixpkgs.follows = "nixpkgs";
};
# ...
};
# ...
}
-
configuration.nix
- This is only required if you're using NixOS. See the FAQ section for details on this.
{
# Other contents...
programs.nix-ld.enable = true;
# ...
}
-
nvimdots.nix
-
setBuildEnv
: If set, automatically configures your$CPATH
,$CPLUG_INCLUDE_PATH
,$LD_LIBLARY_PATH
,$LIBRARY_PATH
,$NIX_LD_LIBRARY_PATH
, and$PKG_CONFIG_PATH
. -
withBuildTools
: If set, automatically installs some build utils such asgcc
andpkg-config
. -
Caveats:
-
setBuildEnv
andwithBuildTools
is only required on NixOS. Q&A for this details - These are required tooling so that
mason.nvim
andnvim-treesitter
can work as expected. - They bundle with
neovim
and won't affect other sessions.
-
-
{
programs.neovim.nvimdots = {
enable = true;
setBuildEnv = true; # Only needed for NixOS
withBuildTools = true; # Only needed for NixOS
};
}
This repository provides programs.dotnet.dev
to manage dotnet
installation and environment variables inspired by programs.java
in home-manager
.
See dotnet/default.nix for a list of available options.
programs.dotnet.dev = {
enabled = true;
environmentVariables = {
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT = "0"; # Will set environment variables for DotNET.
};
}
By default, lazy-lock.json
is not shared between machines.
This is because placing it under nix
's control would make it a read-only file, making it difficult to update at will.
This goes against the nix
ethos in terms of reproducibility, but it is a trade-off for convenience.
If you want more strict management that ensures reproducibility, you can set programs.neovim.nvimdots.bindLazyLock=true
and place the file under nix
management.
Running :Lazy restore
restores the plugin versions.
You will get an error that it is a read-only file, but this can be ignored.
The following sample workflow updates the plugin version regularly.
sample github workflow
name: auto merge upstream
on:
workflow_dispatch: # allows manual triggering
schedule:
- cron: "0 17 * * 5"
permissions:
contents: write
pull-requests: write
jobs:
auto-merge-upstream:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: andstor/file-existence-action@v3
id: check_lockfile
with:
files: "lazy-lock.json"
- name: Merge upstream
id: merge-upstream
continue-on-error: true
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git remote add upstream https://github.com/ayamir/nvimdots.git
git fetch upstream
git merge upstream/main --allow-unrelated-histories --no-commit --no-ff
git reset HEAD lazy-lock.json
git checkout lazy-lock.json
- uses: rhysd/action-setup-vim@v1
if: steps.check_lockfile.outputs.files_exists == 'true'
with:
neovim: true
- name: Run lockfile-autoupdate
if: steps.check_lockfile.outputs.files_exists == 'true'
timeout-minutes: 5
run: |
./scripts/install.sh
nvim --headless "+Lazy! update" +qa
cp -pv "${HOME}/.config/nvim/lazy-lock.json" .
git add lazy-lock.json
- uses: stefanzweifel/git-auto-commit-action@v5
if: steps.check_lockfile.outputs.files_exists == 'true' || steps.merge-upstream.outcome == 'success'
with:
commit_message: "chore: auto merge upstream and update lazy-lock.json"
commit_user_name: "github-actions[bot]"
commit_user_email: "41898282+github-actions[bot]@users.noreply.github.com"
commit_author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
You can set programs.neovim.nvimdots.mergeLazyLock=true
, if you want to allow changes using lazy.nvim
while still managing versions.
This option has the following logic:
-
lazy-lock.json
in the repository is managed aslazy-lock.fixed.json
in/nix/store
. - Not existing
lazy-lock.json
under${XDG_CONFIG_DIR}/nvim
, copy to then. (probably for first time.) - Existing
lazy-lock.json
under then, one of the following will be executed. - When the hash of
lazy-lock.fixed.json
changes (i.e. when the upstreamlazy-lock.json
is changed),
Creating newlazy-lock.json
by mergedlazy-lock.fixed.json
to existinglazy-lock.json
(not managed bynix
) under then.
In this case, the version inlazy-lock.fixed.json
takes precedence. This means that plugins that are already managed upstream will have the lazy-lock.fixed.json version prioritized, and new plugins added that haven't yet been pushed upstream will be preserved. - When the hash of
lazy-lock.fixed.json
no changes (i.e. when the upstreamlazy-lock.json
is not changed),lazy-lock.json
under${XDG_CONFIG_DIR}/nvim
is unchanged.
This means that your local changes will be preserved untillazy-lock.json
is changed upstream.
If you want to pin the package version in lazy-lock.json
permanent, push your local lazy-lock.json
to the your repository.
If you have made local changes but would like to revert to the upstream version, follow these steps:
- unlink
${XDG_CONFIG_DIR}/nvim/lazy-lock.fixed.json
- Run
systemctl restart home-manager-<user>.service
(NixOS) or
home-manager generations | head -n1 | awk -F '-> ' '{print $2 "/activate"}'
(standalone home-manager).
Have a look at default.nix (selection) for more information.
This is because some dependencies are not distributed along with the system - NixOS does not conform to the Filesystem Hierarchy Standard (FHS), so some ingenuity is required.
This homeManagerModule
provides several options to simplify dependency resolution. Nevertheless, you may still use programs.neovim.extraPackages
, programs.neovim.extraPython3Packages
, programs.neovim.extraLuaPackages
provided by home-manager.
nvimdots.nix
{pkgs, ...}:
{
programs.neovim.nvimdots = {
enable = true;
setBuildEnv = true;
withBuildTools = true;
withHaskell = true; # If you want to use Haskell.
extraHaskellPackages = hsPkgs: []; # Configure packages for Haskell (nixpkgs.haskellPackages).
extraDependentPackages = with pkgs; [] # Properly setup the directory hierarchy (`lib`, `include`, and `pkgconfig`).
}
}
You should include the necessary packages for building this dependency, including include
, lib
, and pkgconfig
requirements, in programs.neovim.extraDependentPackages
.
- As an example, for runtime dependencies, add the corresponding dependencies to
home.packages
orprograms.neovim.extraPackages
. - NOTE:
home.packages
is effective inside the user scope whereasprograms.neovim.extraPackages
is effective inside the entire neovim scope. Some languages may also require the use of wrapper, see below example for details.
{ pkgs, ... }:
{
# Install to the user scope.
home.packages = with pkgs; [
go
];
programs.neovim = {
# Packages only accessible from neovim
nvimdots = {
# Packages that require `include`, `lib`, `pkgconfig`
extraDependentPackages = with pkgs; [ icu ];
# Haskell packages can be easily installed with the `nvimdots` options.
extraHaskellPackages = hs: with hs; [ ghcup ];
};
extraPackages = with pkgs; [
go
# Some languages require the use of wrapper.
rWrapper.override
{
packages = with pkgs.rPackages;
[ xml2 lintr roxygen2 ];
}
];
# Python and Lua packages can be easily installed with the corresponding `home-manager` options.
extraPython3Packages = ps: with ps; [
numpy
];
};
}
Contains a verification script.
Running script with nix run github:ayamir/nvimdots#check-linker
that can be used to check ${XDG_DATA_DIR}/nvim/mason/bin
directory (the default on Linux is XDG_DATA_DIR=~/.local/share
) for missing symlinks.
If NVIM_APPNAME
environment variable is set, the script will check ${XDG_DATA_DIR}/${NVIM_APPNAME}/mason/bin
directory instead.
Contains a minimal shell environment trying ayamir/nvimdots
.Build the environment with nix develop github:ayamir/nvimdots
.
Since NVIM_APPNAME=nvimdots
is set, it will not conflict with the existing neovim environment.
Plugins download to ${XDG_DATA_DIR}/nvimdots
.
If you want to try your own settings, after cloning the repository, edit lua/user
and nixos/testEnv.nix and run nix develop .#default
.
This list is incomplete - not all mason.nvim
's dependent sources are tracked and included. You can help by adding missing items.
Language | extraPackages | extraDependentPackages |
---|---|---|
Go | - | hunspell |
PHP | php phpPackages.composer |
- |
R | rWrapper.override { packages = with pkgs.rPackages; [ xml2 lintr roxygen2 ]; } |
- |
Vala |
meson vala
|
vala jsonrpc-glib
|
- For binaries,
patchelf --print-needed <binary>
will list the required packages. - You can also check the information used by
ldd
in this package and/or dynamiclib withldd <binary>
. - You can check the list of dependencies required during build time using the build log (via
mason.nvim
's UI). - If this dependency is included in
nixpkgs
, you may be able to find the package you need by looking at the*.nix
sources. - If you want to be on the safe side, here is a list of dependencies for all packages that have already been registered in
mason-registry
:
libamd <==> https://github.com/zship/libamd
libc <==> https://www.gnu.org/software/libc/
[OR] libc++ <==> https://libcxx.llvm.org/
libevent <==> https://libevent.org/
libiconv <==> https://www.gnu.org/software/libiconv/
libmsgpack <==> http://msgpack.org/
libz <==> https://www.zlib.net/
libzstd <==> https://github.com/facebook/zstd
If it is provided by nixpkgs
, you should be able to use it by adding the following settings. This is the same as setting up other packages that require external installation:
-- Setup lsps that are not supported by `mason.nvim` but supported by `nvim-lspconfig` here.
if vim.fn.executable("dart") == 1 then
local _opts = require("completion.servers.dartls")
local final_opts = vim.tbl_deep_extend("keep", _opts, opts)
nvim_lsp.dartls.setup(final_opts)
end
NixOS (home-manager) creates a symbolic link to a read-only file, so lazy.nvim
cannot write to the file and cannot manage packages.
This implementation avoids linking lazy-lock.json
by default.
Therefore, it is possible that a package newer than lazy-lock.json
managed by ayamir/nvimdots
has been installed, and that it does not work because a breaking change has been made in that package.
Copy lazy-lock.json
from ayamir/nvimdots
to XDG_CONFIG_HOME/nvim
and start neovim
again to check if it works.