nvf

repository·main·Indexed 23 days ago

https://github.com/notashelf/nvf

A highly modular, configurable, and extensible Neovim configuration managed via Nix. It provides a reproducible and portable environment using the Nix module system, supporting lazyloading, deterministic ordering via Directed Acyclic Graphs (DAGs), and flexible plugin management through NixOS, Home-Manager, or standalone packages.

Tokens
22.6K
Snippets
63
Records
114
Agent score
81%

What's inside nvf

  1. Use the nvf utility library

    main

    The inputs.nvf.lib.nvim namespace provides a collection of utility functions for writing nvf modules. These are organized into sub-namespaces based on their purpose:

    • lib.nvim.dag: Utilities for ordering configuration sections (e.g., entryAfter, entryBefore).
    • lib.nvim.binds: Helpers for constructing keybindings and mappings.
    • lib.nvim.lua: Nix-to-Lua conversion utilities.
    • lib.nvim.languages: Helpers for defining language modules and LSP configurations.
    • lib.nvim.lists: List manipulation utilities.
    • lib.nvim.attrsets: Attribute set manipulation utilities.
  2. Supported platforms for nvf

    main

    nvf actively supports the following platforms:

    • Linux (via standalone Nix, NixOS, or Home-Manager)
    • Darwin (via standalone Nix, NixOS, or Home-Manager)
    • Android (reported support via Home-Manager module or standalone package)
  3. What is nvf

    main
    nvf is a highly modular, configurable, extensible, and easy-to-use Neovim configuration framework designed to be used with [Nix]. It allows you to configure a fully featured Neovim instance using a few lines of Nix, while providing the flexibility to integrate Lua for advanced configurations.
  4. Summary of lazy loading trigger mechanisms

    main

    The lz.n engine supports four trigger mechanisms to determine when a lazy plugin should be loaded. Multiple triggers can be combined on a single plugin entry; the plugin will load as soon as the first trigger fires.

    • cmd: Loads on invocation of specific Ex commands.
    • event: Loads on Neovim autocommand events (supports strings or structured records with event and pattern).
    • keys: Loads on the first press of a defined keybinding (requires a record with a key field).
    • ft: Loads when a buffer with a matching filetype is opened.
  5. How the NVF module interface works

    main

    NVF is a hybrid wrapper that supports both Lua and Nix. While Lua can be inserted surgically via DAGs, the primary configuration method is the Nix-based module system.

    Modules follow a standardized anatomy to manage Neovim plugins. Each plugin module typically provides two main options:

    1. vim.<category>.<plugin>.enable: A boolean that determines if the plugin is enabled and added to Neovim's runtime path. It is false by default.
    2. vim.<category>.<plugin>.setupOpts: An attribute set ({}) that contains the configuration for the plugin. This attribute set is automatically converted into a Lua table and passed to the plugin's setup({}) function in your generated init.lua using the toLuaObject utility.
  6. How lazy loading works in nvf

    main
    Lazy loading in nvf defers plugin initialization until the plugin is actually needed, rather than loading everything at startup. This is achieved via the lz.n backend. Instead of loading all plugins immediately, nvf loads them on demand when triggered by specific commands, events, filetypes, or keymaps. This reduces Neovim startup latency by moving the cost of sourcing Lua/Vimscript and registering autocommands from startup to the first time the feature is used.
  7. Convert Nix attributes to Lua tables with toLuaObject

    main

    The toLuaObject function converts Nix attribute sets into Lua tables.

    Conversion Rules:

    • Nix null $\rightarrow$ Lua nil.
    • Numbers and strings $\rightarrow$ Lua numbers and strings.
    • Nix attribute sets {} $\rightarrow$ Lua dictionaries.
    • Nix lists [] $\rightarrow$ Lua tables.
    • Mixed Tables: To create a Lua table with both positional elements and named keys (e.g., {"foo", bar = "baz"}), use the @N syntax where N is the position.

    Example of Mixed Table:

    { "@1" = "foo"; bar = "baz"; }

    Inline Lua: Use lib.generators.mkLuaInline to embed raw Lua code (like functions) instead of just data. This is useful for plugin options that require a function return value.

    # Mixed table example
    { "@1" = "foo"; bar = "baz"; }
    
    # Inline Lua example
    let
      inherit (lib.generators) mkLuaInline;
    in {
      vim.your-plugin.setupOpts = {
        on_init = mkLuaInline ''
          function()
            print('we can write lua!')
          end
        '';
      };
    }
  8. What the LazyFile event is and when it fires

    main

    The LazyFile event is a synthetic Neovim User autocommand event provided by nvf. It is designed to trigger plugin loading only when a real file is actually being edited, rather than at startup or when interacting with non-file buffers (like dashboards, terminals, or empty scratch buffers).

    LazyFile is an alias for the following three standard Neovim events:

    • BufReadPost: An existing file was read into a buffer.
    • BufNewFile: A new (not yet saved) file was opened.
    • BufWritePre: A buffer is about to be written (ensures unsaved new files are caught before the first save).

    Use this event for plugins that require a file context to function, such as LSP clients, indent guides, Git signs, or diagnostics.

  9. Core concepts of nvf

    main

    nvf is a highly modular and configurable Neovim configuration written in Nix. Key architectural concepts include:

    • Reproducibility: The configuration behaves identically across different platforms because it depends solely on the Nix store.
    • Portability: Works on all platforms without requiring global binaries.
    • Customizability: Uses the Nix module system. It avoids heavy defaults and allows you to bring your own Lua configuration or use Nix for everything.
    • Lazyloading: Supports lazyloading for both internal and external plugins.
    • Deterministic Ordering: Uses Directed Acyclic Graphs (DAGs) to allow users to order configuration bits deterministically.
    • Extensibility: Avoids vendor lock-in by allowing you to add new modules, plugins (from inputs, npins, nixpkgs, etc.), or custom modules easily.
  10. Understand the `vim.luaConfigRC` top-level DAG structure

    main
    In nvf, configuration is organized into a Directed Acyclic Graph (DAG) called vim.luaConfigRC. This structure allows you to add code that depends on other parts of the configuration by targeting specific entry points. The DAG follows a specific execution order, ensuring that dependencies like globals or themes are set up before plugins or mappings.
  11. How the vim.lsp.servers submodule works

    main

    The vim.lsp.servers submodule in nvf mirrors the Neovim vim.lsp.config Lua API. It serves two primary purposes:

    1. Modifying existing definitions: Overriding settings for LSPs already provided by nvf language modules (e.g., changing the cmd for a Python LSP).
    2. Registering new servers: Adding entirely new LSP definitions that are not present in the default language modules.

    This API allows for high flexibility in how Language Server Protocol (LSP) clients are configured and discovered within your Neovim environment.