Helix text editor configuration

#| file: modules/nixos/helix/default.nix
{
  lib,
  config,
  pkgs,
  ...
}:
let
  cfg = config.mjm.helix;
in
{
  options.mjm.helix = {
    <<options>>
  };

  config = lib.mkIf cfg.enable {
    <<config>>
  };

  _class = "nixos";
}

This module configures the Helix text editor for my systems. This is usually what I reach for when editing files in the terminal.

Options

enable = lib.mkEnableOption "Helix editor";

The Helix module needs to be enabled, which is done automatically for desktop systems.

extraPackages = lib.mkOption {
  type = with lib.types; listOf package;
  default = [ ];
};

This option configures packages that are added to the PATH when Helix is run. It's useful for language servers or other tools that need to be run as children of Helix. As will be shown below, this module configures a default list of packages that could be extended by other modules if needed.

Config

environment.systemPackages = [
  (pkgs.helix.override {
    helixConfig = "${./config}";
    inherit (cfg) extraPackages;
  })
];

The main thing this module does is install a wrapper for Helix that sets its path and also its configuration directory. This is not something the helix package in Nixpkgs provides. Instead, this comes from my local overlay:

#| file: packages/helix.nix
{
  lib,
  callPackage,
  sources,
  symlinkJoin,
  linkFarm,
  makeWrapper,

  helixConfig ? null,
  extraPackages ? [ ],
}:

let
  helix = callPackage "${sources.helix}" {
    includeGrammarIf = g: g.name != "perl";
  };
  helixConfigHome = linkFarm "helix-config" {
    helix = helixConfig;
  };
in
symlinkJoin {
  name = "helix-wrapper";
  paths = [ helix ];
  nativeBuildInputs = [ makeWrapper ];
  postBuild = ''
    wrapProgram $out/bin/hx \
      --set XDG_CONFIG_HOME ${helixConfigHome} \
      --suffix PATH : ${lib.makeBinPath extraPackages}
  '';
}

I replace the helix package with my own definition. It starts by building Helix from the upstream sources (or rather, my fork of the upstream sources) rather than using the version in Nixpkgs. It also synthesizes a config directory containing a symlink named "helix" that points to whatever is passed in as helixConfig, which should be a directory containing what would normally live at ~/.config/helix. The original helix package is wrapped so that the command has this config directory set as XDG_CONFIG_HOME, and then it appends the bin directories for the extraPackages to its PATH.

This wrapper produces a largely self-contained version of Helix, which can be run as any user and get the same config.

environment.sessionVariables.EDITOR = "hx";

I want programs that need to launch an editor to use Helix by default, so I set the EDITOR variable.

mjm.helix.extraPackages = with pkgs; [
  elixir-ls
  marksman
  nixd
  nixfmt
  racket
  shellcheck
  shfmt
  vscode-langservers-extracted
  bash-language-server
  prettier
  typescript-language-server
  yaml-language-server
];

This is a handful of tools and language servers I want to be able to use from Helix.

Proxy Information
Original URL
gemini://midna.dev/homelab/modules/nixos/helix/
Status Code
Success (20)
Meta
text/gemini;lang=en-US
Capsule Response Time
218.443317 milliseconds
Gemini-to-HTML Time
0.269406 milliseconds

This content has been proxied by September (UNKNO).