{ pkgs, config, lib, inputs, ... }: with lib; let cfg = config.xyno.helix; in { options.xyno.helix.enable = mkOption { default = false; }; options.xyno.helix.withLargeLSPs = mkOption { default = false; }; config = mkIf cfg.enable { home.packages = with pkgs; [ nixpkgs-fmt # omnisharp-roslyn ## ts # nodePackages_latest.prettier dprint markdown-oxide # codebook ## python # ruff-lsp # nodePackages_latest.pyright # inputs.csharp-language-server.packages.${pkgs.system}.csharp-language-server ] ++ (optionals cfg.withLargeLSPs [ nodePackages_latest.typescript-language-server nodePackages_latest.vscode-langservers-extracted typescript # jsonnet-language-server # jsonnet lazygit ltex-ls-plus # languagetool tinymist # typst lsp ]); programs.helix = { # the flake is really slow to download bc it does like 1000 builtins.fetchTree # just switch back to using what's in nixpkgs until stuff gets annoying # package = inputs.helix.packages.${pkgs.system}.default; enable = true; defaultEditor = true; settings = { theme = "gruvbox_dark_hard"; editor = { line-number = "relative"; bufferline = "multiple"; color-modes = true; cursorline = true; auto-format = true; end-of-line-diagnostics = "hint"; inline-diagnostics = { cursor-line = "hint"; }; lsp = { display-messages = true; display-inlay-hints = true; }; popup-border = "popup"; statusline.left = [ "mode" "spinner" "spacer" "version-control" "file-name" "diagnostics" "read-only-indicator" "file-modification-indicator" "spacer" ]; statusline.right = [ "workspace-diagnostics" "register" "position" "selections" "file-encoding" "file-type" ]; idle-timeout = 50; completion-timeout = 100; indent-guides = { render = true; character = "│"; skip-levels = 1; }; soft-wrap = { enable = true; }; whitespace = { render = { space = "none"; tab = "all"; newline = "none"; }; characters = { nbsp = "·"; tab = "→"; }; }; }; keys = { normal = { space."=" = ":fmt"; "C-g" = ":sh tmux popup -d \"#{pane_current_path}\" -xC -yC -w80%% -h80%% -E lazygit"; "C-t" = ":sh tmux split-window -v -l '35%%'"; "C-h" = ":sh tmux select-pane -t '{left-of}'"; "C-l" = ":sh tmux select-pane -t '{right-of}'"; "C-j" = ":sh tmux select-pane -t '{down-of}'"; "C-k" = ":sh tmux select-pane -t '{up-of}'"; # smart tab++ tab = "move_parent_node_end"; S-tab = "move_parent_node_start"; }; insert = { # smart tab ++ S-tab = "move_parent_node_start"; }; select = { # smart tab++ tab = "extend_parent_node_end"; S-tab = "extend_parent_node_start"; }; }; }; languages = { language-server.pyright.config.python.analysis.typeCheckingMode = "basic"; language-server.ruff = { command = "ruff-lsp"; config.settings.args = [ "--ignore" "E501" ]; }; language-server.csharp = { command = "csharp-language-server"; }; language-server.ltex = { command = "ltex-ls-plus"; config = { additionalRules.motherTongue = "de-DE"; additionalRules.enablePickyRules = true; language = [ "en-US" "de-DE" ]; }; }; language-server.tinymist = { command = "tinymist"; }; # language-server.nil = { # command = "nil"; # config.nil.nix = { # maxMemoryMB = 5120; # flake = { # autoEvalInputs = true; # autoArchive = true; # }; # }; # }; language = let applySingleConfig = languages: config: let applied = foldl' ( acc: l: if (any (x: l.name == x) config.languages) then { done = acc.done ++ [ (mkMerge [ l config.conf ]) ]; notFound = filter (x: x != l.name) acc.notFound; } else { done = acc.done ++ [ l ]; notFound = acc.notFound; } ) { done = [ ]; notFound = config.languages; } languages; in applied.done ++ (map (x: { name = x; } // config.conf) applied.notFound); applyConfs = lspConfs: languages: foldl' applySingleConfig languages lspConfs; in applyConfs [ { languages = [ "typescript" "javascript" "jsx" "tsx" ]; conf = { language-servers = [ "typescript-language-server" "eslint" ]; }; } { languages = [ "markdown" "typst" "bibtex" "comment" "latex" "html" ]; conf = { language-servers = [ "ltex" ]; }; } ] [ { name = "__common__"; scope = "source.__common__"; file-types = [ ]; language-servers = [ "ltex" ]; } # { # name = "nix"; # language-servers = [ # "nixd" # ]; # formatter = { # command = "nixpkgs-fmt"; # }; # } { name = "python"; language-servers = [ "pyright" "ruff" ]; } { name = "markdown"; language-servers = [ "markdown-oxide" ]; } { name = "typst"; language-servers = [ "tinymist" ]; } { name = "c-sharp"; language-servers = [ "csharp" ]; formatter = { command = "dotnet"; args = [ "csharpier" ]; }; } ]; }; }; }; }