Skip to content

Repository files navigation

SandVim

check

SandVim is a portable, declarative, NVF-based Neovim IDE distributed as a Home Manager module and as ready-to-build preset packages. It is extracted from a production dotfiles configuration but has no host, user, secret, Stylix, or personal dotfiles dependencies.

Preview

SandVim editing C++ and Nix in split buffers with the Gruvbox dark hard palette

C++ and Nix editing with split buffers, Treesitter highlighting, inlay hints, Git status, and language-server integration.

SandVim fzf-lua file finder with a rendered preview

Fast workspace navigation through fzf-lua with file icons and a rendered preview.

SandVim rendering a Markdown delivery plan with callouts, checkboxes, a table, and a code block

Markdown and Obsidian-style authoring with rendered callouts, task lists, tables, fenced code, and language services.

The screenshots use the full preset and the default gruvbox-dark-hard palette. The core theme, editor UI, statusline, bufferline, and finder are shared across all presets; language, debugging, notes, workflow, AI, and Java capabilities vary by preset.

Navigation at a glance

SandVim uses Space as <leader>. These core navigation keys are available in every preset:

Key Action
<leader>e Open Mini.files at the current file
Mini.files l / h Enter a file or directory / move to the parent directory
Mini.files L / q Open a file and close Mini.files / close the explorer
<leader><leader> Find files with fzf-lua
<leader>/ Search workspace text with fzf-lua live grep
<leader>fb / <leader>fr Find open buffers / recent files
<leader>gf Find Git-tracked files
H / L Move to the previous / next buffer
<C-h/j/k/l> Focus the split or tmux pane left/down/up/right

Press <leader> and pause to open WhichKey. See the comprehensive hotkeys reference for all SandVim-defined mappings, preset gates, plugin-local keys, Mini.files operations, and a guide to key enabled integration defaults.

Supported systems

SandVim exports packages for:

  • x86_64-linux
  • aarch64-linux
  • x86_64-darwin (Intel macOS)
  • aarch64-darwin (Apple Silicon macOS)

Native build and runtime checks run in CI on x86_64-linux, x86_64-darwin, and aarch64-darwin. The aarch64-linux outputs receive evaluation coverage because GitHub does not provide a matching hosted runner. Because Nixpkgs unstable 26.11 removed Intel macOS, x86_64-darwin package/check outputs use dedicated Nixpkgs, Home Manager, and NVF compatibility inputs.

Prerequisites

  • Nix with the nix-command and flakes features enabled.
  • A flake-based Home Manager configuration, or the willingness to create one with the included template.
  • Network access to GitHub. SandVim itself has no private inputs and does not require credentials for anonymous consumption.

If Nix is not installed, use the official Nix installation instructions or the installer approved by your organization. On managed work devices, confirm proxy, certificate, and software-approval requirements before installation.

Recent Determinate Nix and NixOS installations normally enable flakes already. Otherwise add the following to the applicable user or system nix.conf and restart the Nix daemon when using multi-user Nix:

experimental-features = nix-command flakes

A separate global Home Manager installation is not required to build the template. Activation can use the Home Manager CLI or the generated activation package.

Try SandVim before installing it

Launch the workplace-oriented minimal preset directly from the published release:

nix run github:sandmhan/sandvim/v0.2.0#sandvimMinimal

The package selector is the literal fragment after #. Change that fragment to choose the configuration intensity; the braces below describe the choice and are not part of the command:

Configuration intensity Package selector Complete launch command
Minimal #sandvimMinimal nix run github:sandmhan/sandvim/v0.2.0#sandvimMinimal
Standard #sandvimStandard nix run github:sandmhan/sandvim/v0.2.0#sandvimStandard
Full #sandvimFull nix run github:sandmhan/sandvim/v0.2.0#sandvimFull

In other words, replace #sandvimMinimal with #sandvimStandard or #sandvimFull; do not write #sandvim{Minimal,Standard,Full} literally.

To open the current directory, pass it to Neovim after --:

nix run github:sandmhan/sandvim/v0.2.0#sandvimMinimal -- .

nix run executes the packaged Neovim wrapper but does not supply the general command-line tools intentionally owned by module consumers. For a more representative trial with Git and search workflows available, use a temporary Nix shell:

nix shell \
  github:sandmhan/sandvim/v0.2.0#sandvimMinimal \
  nixpkgs#git \
  nixpkgs#ripgrep \
  -c nvim .

Alternatively, enter the shell first and launch Neovim later:

nix shell github:sandmhan/sandvim/v0.2.0#sandvimMinimal nixpkgs#git nixpkgs#ripgrep
nvim .

Use the same #sandvimMinimal, #sandvimStandard, or #sandvimFull selector with nix shell to inspect another preset. Those presets have substantially larger closures and enable AI integration; include nixpkgs#codex-acp in the shell if you intend to test that integration. The minimal preset is the recommended workplace trial.

These commands do not activate Home Manager, modify an existing Home Manager configuration, or update its flake.lock. Nix downloads the selected closure into the Nix store, and Neovim may create its normal cache, data, and state files under the user's XDG directories.

Exit Neovim normally with :qa or :qa!, then proceed with the module integration only if the trial is satisfactory.

Bootstrap a standalone Home Manager configuration

Create an empty directory and initialize it from the released template:

mkdir work-home && cd work-home
nix flake init -t github:sandmhan/sandvim/v0.2.0#home-manager

Edit flake.nix and replace username, system, and homeDirectory. Keep an existing user's current home.stateVersion; do not increase it merely because the example uses 24.11.

Machine system Typical homeDirectory Module
Intel Linux x86_64-linux /home/<username> homeManagerModules.default
ARM Linux aarch64-linux /home/<username> homeManagerModules.default
Intel macOS x86_64-darwin /Users/<username> homeManagerModules.intelDarwin
Apple Silicon macOS aarch64-darwin /Users/<username> homeManagerModules.default

For Intel macOS, also replace the template's unstable inputs and default module:

inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-26.05-darwin";
inputs.home-manager.url = "github:nix-community/home-manager/release-26.05";

# In homeManagerConfiguration.modules:
sandvim.homeManagerModules.intelDarwin

The existing follows declarations remain unchanged. This compatibility path is required because newer unstable Nixpkgs and Home Manager releases no longer support x86_64-darwin.

Lock and build before activation:

nix flake lock
nix build --dry-run .#homeConfigurations.<username>.activationPackage --show-trace
nix build .#homeConfigurations.<username>.activationPackage

After reviewing the build, activate it using one of these methods:

# Works directly from the generated activation package.
./result/activate

# Alternatively, when the Home Manager CLI is installed.
home-manager switch --flake .#<username>

Activation changes the user's managed home configuration. It is intentionally separate from the validation commands above.

Add SandVim to an existing Home Manager flake

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    sandvim = {
      url = "github:sandmhan/sandvim/v0.2.0";
      inputs.nixpkgs.follows = "nixpkgs";
      inputs.home-manager.follows = "home-manager";
    };
  };

  outputs = { nixpkgs, home-manager, sandvim, ... }:
    let
      system = "x86_64-linux";
      username = "alice";
    in {
      homeConfigurations.${username} = home-manager.lib.homeManagerConfiguration {
        pkgs = nixpkgs.legacyPackages.${system};
        modules = [
          sandvim.homeManagerModules.default
          {
            home = {
              inherit username;
              homeDirectory = "/home/${username}";
              # Existing users must retain their current state version.
              stateVersion = "24.11";
            };

            programs.sandvim = {
              enable = true;
              preset = "minimal";
              colorScheme = "gruvbox-dark-hard";
              packs = {
                ai = false;
                workflow = true;
                languages = {
                  nix = true;
                  python = true;
                  web = true;
                };
              };
            };
          }
        ];
      };
    };
}

For Home Manager embedded in NixOS or nix-darwin, import SandVim in the applicable user module rather than creating a second standalone Home Manager configuration:

home-manager.users.alice = {
  imports = [ sandvim.homeManagerModules.default ];

  programs.sandvim = {
    enable = true;
    preset = "minimal";
    colorScheme = "gruvbox-dark-hard";
    packs = {
      ai = false;
      workflow = true;
      languages = {
        nix = true;
        python = true;
        web = true;
      };
    };
  };
};

The surrounding system flake must already import home-manager.nixosModules.home-manager on NixOS or home-manager.darwinModules.home-manager on nix-darwin. Intel macOS consumers must use sandvim.homeManagerModules.intelDarwin and the compatible inputs shown in the consumer guide.

After activation, run a first-start health check:

nvim --headless "+checkhealth" "+qa"

Presets

Preset Purpose Feature packs
minimal Small hardened editor foundation Core editor, UI, completion, Treesitter, Git, finder, editing, and workspace hardening
standard Broad polyglot IDE; external default Minimal plus AI, debugging, notes, Tidal, workflow, documentation, Nix, Python, web, infrastructure, systems, and data/mobile
full Complete curated configuration Standard plus Java

Explicit programs.sandvim.packs.* values override preset defaults. For workplace use, start with minimal and enable only approved language/workflow packs. In particular, keep packs.ai = false unless CodeCompanion/Codex ACP is approved for the source code being edited.

Color scheme

Standalone SandVim uses the exact Base16 Gruvbox dark hard palette by default. This matches the palette previously supplied to the source dotfiles' Neovim configuration by Stylix:

  • Background: #1d2021
  • Foreground: #d5c4a1
  • Red: #fb4934
  • Yellow: #fabd2f
  • Green: #b8bb26
  • Blue: #83a598
  • Purple: #d3869b
  • Aqua: #8ec07c

SandVim v0.1.x did not configure a theme itself. Without an external theme module it therefore used Neovim's built-in default dark palette, whose effective Normal colors were #14161b and #e0e2ea in the validated package. The source dotfiles looked different because Stylix injected Gruvbox highlights outside SandVim.

Select a bundled Gruvbox palette with one option:

programs.sandvim.colorScheme = "gruvbox-dark-hard";

Available values are:

Value Background Intended appearance
gruvbox-dark-hard #1d2021 Dark, highest contrast; default and preferred palette
gruvbox-dark-medium #282828 Dark, medium contrast
gruvbox-light-hard #f9f5d7 Light, highest contrast
gruvbox-light-medium #fbf1c7 Light, medium contrast
none Unmanaged Let Stylix or a direct NVF theme configuration own colors

For example:

programs.sandvim = {
  enable = true;
  preset = "minimal";
  colorScheme = "gruvbox-light-medium";
};

When another module should control Neovim's theme, disable SandVim's ownership without disabling the editor:

programs.sandvim.colorScheme = "none";

After selecting none, an advanced consumer may configure programs.nvf.settings.vim.theme directly. Do not enable both SandVim theme ownership and another Neovim theme provider, because whichever configuration loads last can overwrite highlights.

The ready-to-run sandvimMinimal, sandvimStandard, and sandvimFull packages use the default gruvbox-dark-hard palette. Package selectors change feature intensity, not the color scheme; use the Home Manager option to select a different palette.

Direct package use

Consumers that do not need option-level customization can install a preset Neovim wrapper directly. The wrapper contains NVF-managed editor and language tooling, while general command-line dependencies remain consumer-owned:

home.packages = [
  sandvim.packages.${pkgs.system}.sandvimMinimal
  pkgs.git
  pkgs.ripgrep
];

The standard/full wrappers also require codex-acp on PATH to use their enabled AI integration. Importing the Home Manager module is preferred because it installs required general tools and pack-specific Home Manager packages.

Available package attributes are:

  • sandvimMinimal
  • sandvimStandard
  • sandvimFull
  • default (the standard preset)

Public module API

  • programs.sandvim.enable
  • programs.sandvim.preset: minimal, standard, or full
  • programs.sandvim.colorScheme: a bundled Gruvbox palette or none
  • programs.sandvim.packs.{ai,debugging,notes,tidal,workflow}
  • programs.sandvim.packs.languages.{general,documentation,nix,python,web,infrastructure,systems,dataMobile,java}
  • programs.sandvim.notes.{attachmentsFolder,templatesFolder}

The general language option is retained as a deprecated compatibility umbrella. Notes require the documentation pack. homeManagerModules.intelDarwin exposes the same SandVim option API as default while selecting the compatibility NVF module. Intel consumers must also choose compatible Nixpkgs and Home Manager releases as documented in the consumer guide.

Validation

nix flake show --all-systems
nix build .#checks.x86_64-linux.sandvimMinimalConsumer
nix build .#checks.x86_64-linux.sandvimMinimalRuntime
nix build .#checks.x86_64-linux.sandvimThemeOptions
nix build .#checks.x86_64-linux.sandvimThemeRuntime
nix build .#checks.x86_64-linux.sandvimMarkdownRuntime
nix build .#checks.x86_64-linux.sandvimJavaRuntime
nix build .#checks.x86_64-linux.sandvimStartupProfile

External-consumer activation checks are exported for all supported systems and all presets. Runtime checks should only be run on a matching native system.

Profile closure size and startup time without activation:

scripts/profile-nvf.sh minimal --runs 3
scripts/profile-nvf.sh all

See the consumer guide for integration details, the hotkeys reference for the complete SandVim-defined mapping inventory, and the operations and IDE guide for language ownership, security boundaries, and troubleshooting.

Security boundary

SandVim embeds no API credentials. The optional AI pack uses CodeCompanion with Codex ACP and ChatGPT authentication performed outside Neovim. It does not provide pre-send secret redaction or sensitive-path blocking. Review all context before sending it to an external model.

Workspace-local Neovim configuration and modelines are disabled. Secret scanning is explicit through :NvfScanSecrets / <leader>tS and uses a Nix-provided gitleaks wrapper.

License

MIT

About

Portable NVF-based polyglot Neovim IDE for Home Manager

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages