main
  1{inputs, ...}: {
  2  flake-file.inputs.helix-plugins-nix = {
  3    url = "https://codeberg.org/maxschipper/helix-plugins-nix/archive/main.tar.gz";
  4    inputs.nixpkgs.follows = "nixpkgs";
  5  };
  6
  7  den.aspects.dev.editor.helix = {
  8    cacheHome = {config, ...}: {
  9      directories = [
 10        "${config.xdg.data.directory}/helix" # Workspace trust data
 11      ];
 12    };
 13
 14    nixos = {
 15      nixpkgs.overlays = [inputs.helix-plugins-nix.overlays.default];
 16    };
 17
 18    hjem = {
 19      config,
 20      pkgs,
 21      lib,
 22      ...
 23    }: {
 24      imports = [./_module.nix];
 25
 26      packages = [
 27        pkgs.steel
 28        pkgs.schemat
 29      ];
 30
 31      environment.sessionVariables = {
 32        EDITOR = "hx";
 33        VISUAL = "hx";
 34        STEEL_HOME = "${config.xdg.data.directory}/steel";
 35      };
 36
 37      programs.helix = {
 38        enable = true;
 39        package = pkgs.nur.repos.hpcesia.steelix.override {
 40          steelix-unwrapped =
 41            (pkgs.callPackage "${inputs.nur-hpcesia}/pkgs/steelix/unwrapped.nix" {}).overrideAttrs
 42            (_: prev: {
 43              patches =
 44                prev.patches
 45                ++ [
 46                  # Breadcrumb navigation bar.
 47                  # https://github.com/helix-editor/helix/pull/15573
 48                  ./patches/15573-breadcrumb.patch
 49                  # Search position statusline element and `search.max-matches`.
 50                  # Rebased on top of the breadcrumb patch.
 51                  # https://github.com/helix-editor/helix/pull/11700
 52                  ./patches/11700-search-position.patch
 53                  # Click a bufferline entry to switch buffers.
 54                  # Rebased on top of the breadcrumb patch.
 55                  # https://github.com/helix-editor/helix/pull/12173
 56                  ./patches/12173-clickable-bufferline.patch
 57                  # Disambiguate same-named buffers by prepending path components.
 58                  # Rebased on top of the breadcrumb and clickable-bufferline patches.
 59                  # https://github.com/helix-editor/helix/pull/13113
 60                  ./patches/13113-unique-buffer-names.patch
 61                  # Prompt history search by typed input.
 62                  # https://github.com/helix-editor/helix/pull/15266
 63                  ./patches/15266-prompt-history-search.patch
 64                ];
 65            });
 66        };
 67        settings = {
 68          editor = {
 69            cursorline = true;
 70            bufferline = "multiple";
 71            statusline = {
 72              left = [
 73                "mode"
 74                "spinner"
 75                "file-name"
 76                "read-only-indicator"
 77                "file-modification-indicator"
 78              ];
 79              center = [];
 80              right = [
 81                "diagnostics"
 82                "workspace-diagnostics"
 83                "file-type"
 84                "file-encoding"
 85                "separator"
 86                "search-position"
 87                "position"
 88                "total-line-numbers"
 89              ];
 90            };
 91            line-number = "relative";
 92            indent-guides = {
 93              render = true;
 94              character = "┊";
 95              skip-levels = 1;
 96            };
 97            rulers = [80 120];
 98            cursor-shape = {
 99              normal = "block";
100              insert = "bar";
101              select = "block";
102            };
103            color-modes = true;
104            trim-trailing-whitespace = true;
105            inline-diagnostics.cursor-line = "warning";
106            end-of-line-diagnostics = "error";
107            breadcrumb.enable = true;
108            lsp = {
109              display-inlay-hints = true;
110              inlay-hints-length-limit = 16;
111            };
112            file-picker = {
113              hidden = false;
114            };
115          };
116          keys = let
117            commonKeymap = {
118              "H" = "goto_previous_buffer";
119              "L" = "goto_next_buffer";
120            };
121          in {
122            normal = commonKeymap;
123            select = commonKeymap;
124          };
125        };
126      };
127
128      xdg.config.files."helix/helix.scm" = {
129        source = ./helix.scm;
130        permissions = "0644";
131        type = "copy";
132      };
133      xdg.config.files."helix/init.scm" = {
134        source = ./init.scm;
135        permissions = "0644";
136        type = "copy";
137      };
138
139      xdg.data.files = let
140        helixPluginsNixUtils =
141          (import "${inputs.helix-plugins-nix}/modules/utils.nix")
142          {inherit pkgs lib;};
143
144        allPlugins = helixPluginsNixUtils.flattenPlugins [
145          pkgs.helixPlugins.forest-hx
146          pkgs.helixPlugins.previously-hx
147          pkgs.helixPlugins.wakatime-hx
148        ];
149
150        nativePlugins = helixPluginsNixUtils.getNativePlugins allPlugins;
151        nativeLibDrv = helixPluginsNixUtils.mergeNativeLibs nativePlugins;
152
153        pluginLinks = builtins.listToAttrs (
154          map (drv: {
155            name = "steel/cogs/${drv.cogName}";
156            value = {
157              source = drv;
158              clobber = true;
159            };
160          })
161          allPlugins
162        );
163
164        nativeLibLink = lib.optionalAttrs (nativeLibDrv != null) {
165          "steel/native" = {
166            source = nativeLibDrv;
167            clobber = true;
168          };
169        };
170      in
171        pluginLinks // nativeLibLink;
172    };
173  };
174
175  den.aspects.dev.editor.helix.themes.catppuccin = {
176    hjem.programs.helix.settings.theme = "catppuccin_mocha";
177  };
178}