{ config, ... }: let account = config.facts.account; in { flake.modules.homeManager.helix = { lib, osConfig, pkgs, ... }: let indent = { tab-width = 2; unit = " "; }; oxfmt = { name = "oxfmt"; only-features = [ "format" ]; }; oxlint = { name = "oxlint"; only-features = [ "code-action" "diagnostics" ]; }; webLanguageServers = [ oxfmt "vtsls" oxlint "tailwindcss-ls" ]; markupLanguageServers = primary: [ oxfmt primary "tailwindcss-ls" "emmet-ls" ]; ruffFormatter = pkgs.writeShellApplication { name = "helix-ruff-format"; runtimeInputs = [ pkgs.ruff ]; text = '' if (( $# != 1 )); then echo "usage: helix-ruff-format " >&2 exit 2 fi filename=$1 ruff check \ --fix \ --force-exclude \ --exit-zero \ --no-cache \ --stdin-filename "$filename" \ - \ | ruff format \ --force-exclude \ --stdin-filename "$filename" \ - \ | ruff check \ --fix \ --force-exclude \ --select=I001 \ --exit-zero \ --no-cache \ --stdin-filename "$filename" \ - ''; }; in { programs.helix = { enable = true; extraPackages = with pkgs; [ ripgrep fd wl-clipboard stylua taplo yamlfmt lua-language-server nixd nixfmt dafny vscode-langservers-extracted tailwindcss-language-server rust-analyzer rustfmt astro-language-server tinymist typstyle ty ruff vtsls pkgs.oxlint pkgs.oxfmt emmet-language-server svelte-language-server ]; settings = { theme = "lux-kanagawa"; editor = { scrolloff = 10; default-yank-register = "+"; cursorline = true; completion-timeout = 5; color-modes = true; popup-border = "all"; file-picker.hidden = false; indent-guides.render = true; inline-diagnostics.cursor-line = "hint"; lsp.display-inlay-hints = true; soft-wrap.enable = true; statusline = { left = [ "mode" "spinner" "version-control" "file-name" "read-only-indicator" "file-modification-indicator" ]; right = [ "diagnostics" "selections" "position-percentage" "position" "file-type" ]; separator = ""; mode = { normal = "NORMAL"; insert = "INSERT"; select = "SELECT"; }; diagnostics = [ "error" "warning" "info" "hint" ]; workspace-diagnostics = [ "error" "warning" "info" "hint" ]; }; whitespace = { render = { tab = "all"; nbsp = "all"; nnbsp = "all"; }; characters = { tab = "»"; nbsp = "␣"; }; }; }; keys = { insert."C-g" = "signature_help"; normal = { esc = [ "collapse_selection" "keep_primary_selection" ]; "C-h" = "jump_view_left"; "C-j" = "jump_view_down"; "C-k" = "jump_view_up"; "C-l" = "jump_view_right"; "[".h = "goto_prev_change"; "]".h = "goto_next_change"; g.I = "goto_implementation"; space = { space = "buffer_picker"; f = ":format"; q = "diagnostics_picker"; "/" = "search"; b.d = ":buffer-close"; c.a = "code_action"; d.s = "symbol_picker"; h.r = ":reset-diff-change"; r.n = "rename_symbol"; t.h = ":toggle lsp.display-inlay-hints"; s = { f = "file_picker"; g = "global_search"; d = "diagnostics_picker"; r = "last_picker"; "/" = "global_search"; }; }; }; }; }; themes.lux-kanagawa = { inherits = "kanagawa"; "ui.gutter" = { fg = "sumiInk6"; }; }; languages = { language-server = { dafny = { command = "dafny"; args = [ "server" ]; }; emmet-ls = { command = "emmet-language-server"; args = [ "--stdio" ]; }; lua-language-server = { config.Lua = { runtime.version = "LuaJIT"; signatureHelp.enable = true; diagnostics.globals = [ "vim" ]; telemetry.enable = false; completion.callSnippet = "Replace"; hint.enable = true; }; }; nixd = { config.nixd = { nixpkgs.expr = "import ${pkgs.path} {}"; options = { nixos.expr = ''(builtins.getFlake "path://${account.nixosConfigurationPath}").nixosConfigurations.${osConfig.facts.machine.name}.options''; home-manager.expr = ''(builtins.getFlake "path://${account.nixosConfigurationPath}").nixosConfigurations.${osConfig.facts.machine.name}.options.home-manager.users.type.getSubOptions []''; }; formatting.command = [ "nixfmt" ]; }; }; oxfmt = { command = "oxfmt"; args = [ "--lsp" ]; required-root-patterns = [ ".oxfmtrc.json" ".oxfmtrc.jsonc" "oxfmt.config.ts" "package.json" "vite.config.ts" ]; }; oxlint = { command = "oxlint"; args = [ "--lsp" ]; required-root-patterns = [ ".oxlintrc.json" ".oxlintrc.jsonc" "oxlint.config.ts" "package.json" "vite.config.ts" ]; }; tinymist = { config.formatterMode = "typstyle"; }; vtsls = { command = "vtsls"; args = [ "--stdio" ]; config.vtsls.autoUseWorkspaceTsdk = true; }; }; language = [ { name = "lua"; auto-format = true; formatter = { command = "stylua"; args = [ "--indent-type" "Spaces" "--indent-width" "2" "--search-parent-directories" "--respect-ignores" "--stdin-filepath" "%{buffer_name}" "-" ]; }; } { name = "nix"; auto-format = true; language-servers = [ "nixd" ]; } { name = "dafny"; scope = "source.dafny"; injection-regex = "dafny"; file-types = [ "dfy" "dafny" ]; roots = [ ".git" ]; comment-token = "//"; block-comment-tokens = { start = "/*"; end = "*/"; }; inherit indent; auto-format = true; language-servers = [ "dafny" ]; } { name = "json"; language-servers = [ oxfmt "vscode-json-language-server" ]; } { name = "jsonc"; language-servers = [ oxfmt "vscode-json-language-server" ]; } { name = "javascript"; auto-format = true; language-servers = webLanguageServers; } { name = "jsx"; auto-format = true; language-servers = webLanguageServers ++ [ "emmet-ls" ]; } { name = "typescript"; auto-format = true; language-servers = webLanguageServers; } { name = "tsx"; auto-format = true; language-servers = webLanguageServers ++ [ "emmet-ls" ]; } { name = "css"; language-servers = markupLanguageServers "vscode-css-language-server"; } { name = "scss"; language-servers = markupLanguageServers "vscode-css-language-server"; } { name = "less"; scope = "source.css.less"; injection-regex = "less"; file-types = [ "less" ]; grammar = "css"; block-comment-tokens = { start = "/*"; end = "*/"; }; inherit indent; auto-format = true; language-servers = markupLanguageServers "vscode-css-language-server"; } { name = "html"; language-servers = markupLanguageServers "vscode-html-language-server"; } { name = "rust"; inherit indent; } { name = "python"; inherit indent; auto-format = true; language-servers = [ "ty" "ruff" ]; formatter = { command = lib.getExe ruffFormatter; args = [ "%{buffer_name}" ]; }; } { name = "astro"; auto-format = true; language-servers = [ "astro-ls" oxlint "tailwindcss-ls" "emmet-ls" ]; } { name = "svelte"; auto-format = true; language-servers = [ oxfmt "svelteserver" oxlint "tailwindcss-ls" "emmet-ls" ]; } { name = "typst"; auto-format = true; } { name = "toml"; auto-format = true; language-servers = [ "taplo" ]; formatter = { command = "taplo"; args = [ "format" "--stdin-filepath" "%{buffer_name}" "-" ]; }; } { name = "yaml"; auto-format = true; language-servers = [ ]; formatter = { command = "yamlfmt"; args = [ "-" ]; }; } ]; }; }; }; }