nix-community / kickstart-nix.nvim

❄️ A dead simple Nix flake template repository for Neovim derivations [maintainer=@mrcjkb]
GNU General Public License v2.0
231 stars 10 forks source link
flakes neovim nix nixos nvim vim


kickstart-nix.nvim

❄️

A dead simple Nix flake template repository
for Neovim

[![Neovim][neovim-shield]][neovim-url] [![Nix][nix-shield]][nix-url] [![Lua][lua-shield]][lua-url] [![GPL2 License][license-shield]][license-url] [![Issues][issues-shield]][issues-url]

:grey_question: Why kickstart-nix.nvim

If Nix and Neovim have one thing in common, it's that many new users don't know where to get started. Most Nix-based Neovim setups assume deep expertise in both realms, abstracting away Neovim's core functionalities as well as the Nix internals used to build a Neovim config. Frameworks and module-based DSLs are opinionated and difficult to diverge from with one's own modifications.

kickstart-nix.nvim is different: It's geared for users of all levels, making the migration of Neovim configurations to Nix straightforward. This project aims to be as simple as possible, while allowing for maximum flexibility.

[!NOTE]

Similar to kickstart.nvim, this repository is meant to be used by you to begin your Nix/Neovim journey; remove the things you don't use and add what you miss.

:milky_way: Philosophy

[^1]: The absence of a Nix module DSL for Neovim configuration is deliberate. If you were to copy the nvim directory to $XDG_CONFIG_HOME, and install the plugins, it would work out of the box.

:star2: Features

:bicyclist: Test drive

If you have Nix installed (with flakes enabled), you can test drive this by running:

nix run "github:nix-community/kickstart-nix.nvim"

:books: Usage

  1. Click on Use this template to start a repo based on this template. Do not fork it.
  2. Add/remove plugins to/from the Neovim overlay.
  3. Add/remove plugin configs to/from the nvim/plugin directory.
  4. Modify as you wish (you will probably want to add a color theme, ...). See: Design.
  5. You can create more than one package using the mkNeovim function by
    • Passing different plugin lists.
    • Adding ignoreConfigRegexes (e.g. = [ "^ftplugin/.*.lua" ]).

[!TIP]

The nix and lua files contain comments explaining what everything does in detail.

:zap: Installation

:snowflake: NixOS (with flakes)

  1. Add your flake to you NixOS flake inputs.
  2. Add the overlay provided by this flake.
nixpkgs.overlays = [
    # replace <kickstart-nix-nvim> with the name you chose
    <kickstart-nix-nvim>.overlays.default
];

You can then add the overlay's output(s) to the systemPackages:

environment.systemPackages = with pkgs; [
    nvim-pkg # The default package added by the overlay
];

[!IMPORTANT]

This flake uses nixpkgs.wrapNeovimUnstable, which has an unstable signature. If you set nixpkgs.follows = "nixpkgs"; when importing this into your flake.nix, it may break. Especially if your nixpkgs input pins a different branch.

:penguin: Non-NixOS

With Nix installed (flakes enabled), from the repo root:

nix profile install .#nvim

:robot: Design

Directory structure:

── flake.nix
── nvim # Neovim configs (lua), equivalent to ~/.config/nvim
── nix # Nix configs

:open_file_folder: Neovim configs

Directory structure:

── nvim
  ├── ftplugin # Sourced when opening a file type
  │  └── <filetype>.lua
  ├── init.lua # Always sourced
  ├── lua # Shared library modules
  │  └── user
  │     └── <lib>.lua
  ├── plugin # Automatically sourced at startup
  │  ├── autocommands.lua
  │  ├── commands.lua
  │  ├── keymaps.lua
  │  ├── plugins.lua # Plugins that require a `setup` call
  │  └── <plugin-config>.lua # Plugin configurations
  └── after # Empty in this template
     ├── plugin # Sourced at the very end of startup (rarely needed)
     └── ftplugin # Sourced when opening a filetype, after sourcing ftplugin scripts

[!IMPORTANT]

  • Configuration variables (e.g. vim.g.<plugin_config>) should go in nvim/init.lua or a module that is required in init.lua.
  • Configurations for plugins that require explicit initialization (e.g. via a call to a setup() function) should go in nvim/plugin/<plugin>.lua or nvim/plugin/plugins.lua.
  • See Initialization order for details.

:open_file_folder: Nix

You can declare Neovim derivations in nix/neovim-overlay.nix.

There are two ways to add plugins:

Directory structure:

── flake.nix
── nix
  ├── mkNeovim.nix # Function for creating the Neovim derivation
  └── neovim-overlay.nix # Overlay that adds Neovim derivation

:mag: Initialization order

This derivation creates an init.lua as follows:

  1. Add nvim/lua to the runtimepath.
  2. Add the content of nvim/init.lua.
  3. Add nvim/* to the runtimepath.
  4. Add nvim/after to the runtimepath.

This means that modules in nvim/lua can be required in init.lua and nvim/*/*.lua.

Modules in nvim/plugin/ are sourced automatically, as if they were plugins. Because they are added to the runtime path at the end of the resulting init.lua, Neovim sources them after loading plugins.

:electric_plug: Pre-configured plugins

This configuration comes with a few plugins pre-configured.

You can add or remove plugins by

:anchor: Syncing updates

If you have used this template and would like to fetch updates that were added later...

Add this template as a remote:

git remote add upstream git@github.com:nix-community/kickstart-nix.nvim.git

Fetch and merge changes:

git fetch upstream
git merge upstream/main --allow-unrelated-histories

:pencil: Editing your config

When your neovim setup is a nix derivation, editing your config demands a different workflow than you are used to without nix. Here is how I usually do it:

[^2]: When adding new files, nix flakes won't pick them up unless they have been committed or staged.

This requires a rebuild of the nvim derivation, but has the advantage that if anything breaks, it's only broken during your test run.

If you want an impure, but faster feedback loop, you can use $XDG_CONFIG_HOME/$NVIM_APPNAME[^3], where $NVIM_APPNAME defaults to nvim if the appName attribute is not set in the mkNeovim function.

[^3]: Assuming Linux. Refer to :h initialization for Darwin.

This has one caveat: The wrapper which nix generates for the derivation calls nvim with -u /nix/store/path/to/generated-init.lua. So it won't source a local init.lua file. To work around this, you can put scripts in the plugin or after/plugin directory.

[!TIP]

If you are starting out, and want to test things without having to stage or commit new files for changes to take effect, you can remove the .git directory and re-initialize it (git init) when you are done.

:link: Alternative / similar projects

[!NOTE]

When comparing with projects in the "non-Nix world", this repository would be more comparable to kickstart.nvim (hence the name), while the philosophies of neovim-flake and NixVim are more in line with a Neovim distribution like LunarVim or LazyVim (though they are far more minimal by default).