Neovim Nightly on NixOS with Home-Manager and Plugins from Git
I recently switched to NixOS with Home-Manager and wanted to try out Neovim Nightly, aka Neovim 5.0.
What is different about my setup? I will show you how to ditch all plugin managers and use one Nix function to fetch all Neovim plugins from git. It will also keep them up to date every time you rebuild your system.
I assume you already have Home-Manager installed on your system. To install Neovim Nightly:
nixpkgs.overlays = [
(import (builtins.fetchTarball {
url = https://github.com/nix-community/neovim-nightly-overlay/archive/master.tar.gz;
}))
];
programs.neovim = {
enable = true;
package = pkgs.neovim-nightly;
};
Below is an example configuration of my custom plugin manager.
I tried adding comments to every important line.
The function pluginGit
creates a Nix Vim plugin with a built-in function called buildVimPluginFrom2Nix
. This function is a wrapper for almost every Vim plugin that you will find in the official NixPkgs.
The downside of using the package from NixPkgs is that your plugins only update when the package updates. Usually, Vim plugin managers always fetch the plugins from git, unless you specify a commit.
This is also possible with my function. The first parameter is a commit, tag, or branch. The plugin
function is a wrapper around pluginGit
, which defaults to HEAD
. This will always point to the latest commit on the repo.
{ config, pkgs, lib, vimUtils, ... }:
let
# installs a vim plugin from git with a given tag / branch
pluginGit = ref: repo: vimUtils.buildVimPluginFrom2Nix {
pname = "${lib.strings.sanitizeDerivationName repo}";
version = ref;
src = builtins.fetchGit {
url = "https://github.com/${repo}.git";
ref = ref;
};
};
# always installs latest version
plugin = pluginGit "HEAD";
in {
programs.neovim = {
enable = true;
package = pkgs.neovim-nightly;
# read in the vim config from the filesystem
# this enables syntax highlighting when editing those
extraConfig = builtins.concatStringsSep "\n" [
(lib.strings.fileContents ./base.vim)
(lib.strings.fileContents ./plugins.vim)
(lib.strings.fileContents ./lsp.vim)
# this allows you to add lua config files
''
lua << EOF
${lib.strings.fileContents ./config.lua}
${lib.strings.fileContents ./lsp.lua}
EOF
''
];
# install needed binaries here
extraPackages = with pkgs; [
# used to compile tree-sitter grammar
tree-sitter
# installs different language servers for neovim-lsp
# have a look at the link below to figure out the ones for your languages
# https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md
nodePackages.typescript nodePackages.typescript-language-server
gopls
nodePackages.pyright
rust-analyzer
];
plugins = with pkgs.vimPlugins; [
# you can use plugins from the pkgs
vim-which-key
# or you can use our function to directly fetch plugins from git
(plugin "neovim/nvim-lspconfig")
(plugin "hrsh7th/nvim-compe") # completion
(plugin "Raimondi/delimitMate") # auto bracket
# this installs the plugin from 'lua' branch
(pluginGit "lua" "lukas-reineke/indent-blankline.nvim")
# syntax highlighting
(plugin "nvim-treesitter/nvim-treesitter")
(plugin "p00f/nvim-ts-rainbow") # bracket highlighting
];
};
}
Let me know what you think in the comments below! I am open to new enhancements :)