Hello nix community,
I am a total nix beginner, have read nix pills and many other resources and am still struggling with a small project I am trying to achieve:
- I want to use neovim with a custom configuration, using the lazy package manager.
- Not every neovim plugin is available through the nix store so I would like to leave plugin managament to lazy (using its lockfile).
- I also want to make sure, the runtime dependencies are available with installation, e.g. python3-pip, npm, java17, …
- I want to pin the system dependencies / runtime dependencies for neovim to specific commits.
- Additionally I want to share the configuration also with users, not using nix at all (another reason to not define plugins and other configuration the nix way).
Thus my questions is about how to do orchestration or packaging to meet the requirements above.
I was trying the following things so far, but my impression is more and more that an experienced nix user can give a hint that ends the struggle:
Approach 1: Dev shell
I tried defining a dev shell as follows but had the problems, that
- opening the dev shell takes very long (some seconds)
- I don’t know how to pass arguments to neovim using
nix develop --command nvim
, e.g.nix develop --command nvim my_file.txt
. My goal would be to use neovim instantly (e.g. using an alias for this command) and not to first have to enter the dev shell seperately. - After exiting neovim, the dev shell should be closed as well
My flake.nix
:
{
# Versioning of tools: https://mplanchard.com/posts/installing-a-specific-version-of-a-package-with-nix.html
description = "very epic stuff";
inputs = {
# --- Nixpkgs
nixpkgs.url = "github:NixOS/nixpkgs/release-23.11";
# Unstable nix. You can name this whatever you want. We'll call it nixpkgs-unstable.
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
# Some particular revision for installing fd
nixpkgs-fd.url = "github:NixOS/nixpkgs/bf972dc380f36a3bf83db052380e55f0eaa7dcb6";
# --- Overlays
# Provides rust and friends
rust-overlay.url = "github:oxalica/rust-overlay";
# neovim
neovim-overlay.url = "github:nix-community/neovim-nightly-overlay";
# --- Utilities
# Proivdes legacy compatibility for nix-shell
flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
# Provides some nice helpers for multiple system compatibility
flake-utils.url = "github:numtide/flake-utils";
};
outputs = {
self,
# --- Nixpkgs
nixpkgs, nixpkgs-unstable, nixpkgs-fd,
# --- Overlays
rust-overlay, neovim-overlay,
# --- Utilities
flake-utils, flake-compat
}:
flake-utils.lib.eachDefaultSystem
(system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [
rust-overlay.overlays.default
neovim-overlay.overlays.default
];
};
pkgs-unstable = import nixpkgs-unstable { inherit system; };
pkgs-fd = import nixpkgs-fd { inherit system; };
in
with pkgs;
{
devShell = mkShell {
buildInputs = [
# Add your system dependencies here
pkgs-unstable.coreutils
pkgs-fd.fd
rust-bin.stable.latest.default # this package is provided by the overlay
rust-analyzer
pkgs-unstable.bashInteractive
pkgs-unstable.zulu17 # java17 and openjdk
pkgs-unstable.neovim
pkgs.python3
pkgs.python311Packages.pip
pkgs.luajitPackages.luarocks
pkgs.go
pkgs.php
pkgs.php83Packages.composer
pkgs.julia_18
pkgs.nodejs_21
];
};
derivations = {
neovim = pkgs.neovim-nightly.overrideAttrs (oldAttrs: {
src = ./.;
});
};
}
);
}
Approach 2: Use derivation
I tried to make aderivation myneovim
, where neovim is copied into $out/bin
and a script points to it, using my configuration.
Problems I had:
- Runtime dependencies seem not to be installed. E.g. pip is not available when running
myneovim
and doing healthcheck - As I understood, the dependencies have to be used in the installation process to be persisted. But in the
postInstall
phase, I cannot usemyneovim
to make neovim try to check the dependencies through the healthchecker. Runningnix-env --install --file default.nix
fails with/nix/store/xfhkjnpqjwlf6hlk1ysmq3aaq80f3bjj-stdenv-linux/setup: line 1579: /nix/store/264zxspxsim23p6k2sn4qahz62yxmhwd-myneovim/myneovim: No such file or directory
My default.nix
:
{ pkgs ? import <nixpkgs> {} }:
pkgs.stdenv.mkDerivation {
name = "myneovim";
buildInputs = [
pkgs.neovim
pkgs.git
pkgs.python3
pkgs.python3Packages.pynvim
pkgs.python3Packages.pip
];
src = ./.;
phases = [
"unpackPhase"
"buildPhase"
"installPhase"
"postInstall"
];
buildPhase = ''
mkdir -p $out/bin
echo "#!/bin/sh" > $out/bin/myneovim
echo "NVIM_APPNAME=\"myneovim\" $out/bin/nvim -u $out/config/init.lua \"\$@\"" >> $out/bin/myneovim
chmod +x $out/bin/myneovim
'';
installPhase = ''
ls ${pkgs.cowsay}/bin/
mkdir -p $out
cp -r ${pkgs.neovim}/bin/* $out/bin
cp -r $src/src/config $out/
'';
postInstall = ''
$out/myneovim --headless "+checkhealth" "+w!health.log" +qa
'';
}
Having a dev shell seems to be clean regarding runtime dependencies. But it looks like I need to use a derivation to “seamlessly” use neovim with my configuration.
With the latter approach, I am not sure how to install the runtime dependencies and how to make neovim check them. Or should I instead use nix-env --install
instead initially for all runtime dependencies?
Afterall, I have the feeling, there could be a much easier and cleaner way and that I might not think “nixy” enough or have not yet enough/correct understanding of how to achieve this.
Any help is appreciated.
Best wishes,
snaeil