The KISS-based configuration that maximizes the use of Neovim's built-in functionality.
Nix overlay/wrapper for configuring package content
Did he write another way to configure Neovim with nix?
No, I don't like all the things people are doing with Neovim using Nix. In my opinion it just makes your user experience more complicated and uncomfortable. Try to answer the following questions:
- What's the point of keeping your configuration in immutable store and losing the ability to make quick changes?
- We already have a first class supported language in Neovim to write our configuration with all that lsp stuff, syntax highlighting, etc. So why give it up?
- Any plugin, has instructions on how to install it easily by copying a snippet from the README. Is it really that much harder than enabling the option in Nix?
- Neovim already has a very cool plugin manager with lazy loading, lock file and bytecode compilation. As far as I know the latter is not available in any Nix solution. So, what benefits will you get from Nix?
But I also want to have an easily portable Neovim configuration. So that on any machine that has Nix installed, I can quickly get into my development environment. That's why I wrote this. My overlay allows you to define a Neovim package with a number of dependencies, which also contains a small script to bootstrap your Neovim configuration from git repo at startup.
Unlike the solutions I know:
- The NixOS module in nixpkgs
- The module in Home Manager
- nixvim
- neovim-flake
My overlay does not involve configuring Neovim with Nix. Instead, it enables you
to wrap the standard neovim-unwrapped
package using the standard wrapper
provided in nixpkgs. This allows you to configure the following aspects:
- Add packages to
$PATH
, specifically for Neovim. Add Tree-sitter parsers via package rebuild or:h 'rtp'
option.- Add additional Lua code to
pre-init.lua
. - Add additional arguments to makeWrapper.
EDIT: Previously I also passed nvim-treesitter-parsers
from nixpkgs, but this
was a bad idea because the queries files from nvim-treesitter
, which will be
managed by the nvim plugin manager, like lazy.nvim
, and the parsers from
nixpkgs may not be compatible.
This is a Lua file that is executed with the command
--cmd "luafile pre-init.lua"
, which means that it is executed before any vimrc
is processed. It consists of:
vim.g.is_nix_package = 1
. This can be used to change the configuration based on whether Neovim is a package from this overlay.- If
repo
is not null, it also contains a snippet that checks and clones the repository from the specified URL. See therepo
argument below. - Any additional Lua code you specify with
additionalPreInit
.
Arguments that are simply passed to neovimUtils.makeNeovimConfig
.
Source:
extraName
, string, default:""
. The suffix to be added to the name attribute in the derivation.viAlias
, bool, default:false
. Similar to theprograms.neovim.viAlias
option in NixOS.vimAlias
, bool, default:false
. Similar to theprograms.neovim.vimAlias
option in NixOS.withPython3
, bool, default:false
. Similar to theprograms.neovim.withPython3
option in NixOS.withNodeJs
, bool, default:false
. Similar to theprograms.neovim.withNodeJs
option in NixOS.withRuby
, bool, default:false
. Similar to theprograms.neovim.withRuby
option in NixOS.withPerl
, bool, default:false
. Similar to the above options enable the Perl provider. But this is still an experimental option, be careful.extraPython3Packages
, default:_: [ ]
. A function that you normally pass inpython.withPackages
, but which is passed to the python provider Neovim.extraLuaPackages
, default:_: [ ]
. Similar to the above.
Additional arguments, that implemented inside wrapper.nix
:
repo
, string or null, default:null
. On startup, Nvim will check if the specified repository is a user configuration, and load it if it is not. If some configuration already exists but is not the specified repository, it will be renamed with the prefix "_backup_{current date}". Thegit remote get-url origin
command is used for verification.additionalPreInit
, string, default:""
. Any Lua code you want to add topre-init.lua
. Be careful, it will be executed every time you open Neovim.additionalWrapperArgs
, list of string, default:[ ]
. As mentioned above, using this option you can add arguments to makeWrapper.extraBinPath
, list of package, default:[ ]
. Packages to be added to$PATH
.
# flake.nix
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
# Add input
nvim.url = "github:name-snrl/nvim";
};
outputs = { self, nixpkgs, ... }@inputs: {
nixosConfigurations.<hostname> = nixpkgs.lib.nixosSystem {
modules = [ ./configuration.nix ];
# pass inputs to config
specialArgs = { inherit inputs; };
};
};
}
# configuration.nix
{ pkgs, inputs, ... }: {
nixpkgs.overlays = [
# Add my overlay. It uses final.callPackage, so it doesn't matter the
# sequence in which it is added, it will always use neovim-unwrapped from
# the final package set.
inputs.snrl-cfg.overlays.default
# configure your own package
(final: prev: {
my-nvim = final.nvim.override {
viAlias = true;
vimAlias = true;
repo = "https://github.com/<user-name>/<repo>";
extraBinPath = with final; [
curl
fd
ripgrep
];
};
})
];
# add it to environment.systemPackages or wherever you want
environment.systemPackages = with pkgs; [
my-nvim
];
}
{ pkgs, ... }: {
nixpkgs.overlays = [
(final: prev: {
my-nvim =
let
nvim-overlay = builtins.fetchTarball {
url = "https://github.com/name-snrl/nvim/archive/from-scratch.tar.gz";
};
in
final.callPackage "${nvim-overlay}/wrapper.nix" {
# your overrides here
};
})
];
# add it to environment.systemPackages or wherever you want
environment.systemPackages = with pkgs; [
my-nvim
];
}
This is creating a small bash script around the package to create its own
environment. As you may have noticed, nixpkgs has many packages with the suffix
-unwrapped
, which means that it is a standardly built package with standard
output. But sometimes a wrapper is created for a package to work properly in
NixOS or to customize it through a module, so wrapped packages are hidden under
their normal names. What does a wrapper look like? Execute:
nvim "$(realpath "$(which nvim)")"
No, unless the rebuildWithTSParsers
option is enabled. By default, this just
builds a thin bash wrapper around the neovim-unwrapped
package.
By default, the overlay uses your system's neovim-unwrapped
package from the
final
argument, which means that if you use
neovim-nightly, which
overrides the neovim-unwrapped
package, you don't need to do anything. Or you
can specify the package manually via override:
final: prev: {
my-nvim = final.nvim.override { neovim-unwrapped = prev.neovim-i-want-wrap; }
}
- git integration
- nvim-treesitter
- appearance
- colorscheme nightfox.nvim
- misc
- git integration
-
tpope/vim-fugitive
- selecting commits for fixup
- commands
- stage/unstage files
- conflicts
- blame
- stash
-
lewis6991/gitsigns.nvim
- stage/unstage in file
-
telescope
- quickfix for
:G mergetool
- branch/commit switching.
git_commit
/git_bcommit
- quickfix for
- easy way to resolve merger conflicts. WIP
vim-fugitive
- a tool to manage working trees, maybe
telescope
is all we need, justThePrimeagen/git-worktree.nvim
!!!!!!! - easy way to clone a repo to /tmp followed by timeline-based exploration
- clone with
vim-fugitive
, create a mapping:G clone {clipboard} /tmp/tmpdir | cd /tmp/tmpdir
- explore with:
telescope
:git_commit
/git_bcommit
,git_bcommits
with-L
,git_files
vim-fugitive
::G blame
, maybe:Gclog
/:Gllog
- clone with
-
octo.nvim
/tpope/vim-rhubarb
- branch/commit switching,
telescope
. WIPtelescope
- making fixups,
telescope
. WIPtelescope
- stash management,
telescope
. WIPtelescope
andvim-fugitive
- pop with
telescope
- stash with
vim-fugitive
, maybe additional mappings?
- pop with
-
- file navigation
-
telescope
- git file same for grep
- all files except .git/ same for grep
- help files
- man files
-
harpoon
-
- text navigation
-
flash.nvim
- jump anywhere in the window
- enhanced f/F/t/T
- select ts-object
-
vim-matchup
/monkoose/matchparen.nvim
/theHamsta/nvim-treesitter-pairs
, but do we realy need this? - project-wide replace with one of:
nvimdev/lspsaga
renamenvim-pack/nvim-spectre
-
- text processing
-
kylechui/nvim-surround
-
numToStr/Comment.nvim
-
- autopairs
windwp/nvim-autopairs
nvimdev/dyninput.nvim
altermo/ultimate-autopair.nvim
echasnovski/mini.pairs
- or something else from https://github.com/yutkat/my-neovim-pluginlist/blob/main/auto-insert.md#insert-pairs
- autopairs for lua tables and nix attrsets/lists/multi-strings, which will append a comma (lua) or semicolon (nix) to the pairing
- pairs for markdown `/**/_
- a new line within a pair
- default pairs
-
tree-sitter
- highlighting using
vim.treesitter.start()
, looks like we don't need nvim-treesitter anymore. we still neednvim-treesitter
because it contains queries for highlighting and everything else. - indentation? yeah, it looks better than writing in vimL..
- code navigation through
telescope
- highlighting using
- code context and breadcrumbs/outline can use
gO
mapping for oppening outline buffer, it makes same by default:SmiteshP/nvim-navic
andSmiteshP/nvim-navbuddy
(only LSP). want the same but through treesitternvimdev/lspsaga
outlinestevearc/aerial.nvim
hedyhli/outline.nvim
Bekaboo/dropbar.nvim
-
LSP
-
nvimdev/lspsaga
-
folke/trouble.nvim
-
j-hui/fidget.nvim
-
nvim-cmp
not sure we need this because Neovim now has an APIvim.snippet
.
-
- languages
- lua
- indentation
- formatting
- lsp,
neodev.nvim
, but we also use Neovim for writing mpv plugins - diagnostics
- nix
- indentation, Neovim does not provide good indentation rules for nix
- formatting
- lsp
- diagnostics
- markdown
- indentation
- formatting
- lsp
- diagnostics
- preview
- bash
- indentation
- formatting
- lsp
- diagnostics
- starlark
- indentation
- formatting
- lsp
- diagnostics
- scala
- indentation, Neovim does not provide good indentation rules for scala
- formatting
- lsp
- diagnostics
- starlark
- indentation
- formatting
- lsp
- hovers with bzl lsp
- goto-definition with
alexander-born/bazel.nvim
- diagnostics
- lua
- appearance
-
EdenEast/nightfox.nvim
-
lukas-reineke/indent-blankline.nvim
- add an image of the look
-
- misc
-
folke/todo-comments.nvim
? -
uga-rosa/translate.nvim
-
brenoprata10/nvim-highlight-colors
-
tpope/vim-repeat
-
-
DAP
- AI coding assistant
- doc
- snippets
- tests