{ pkgs, pkgs-unstable, ... }: let lsps = let mkLsp = pkg: path: {inherit pkg path;}; in { bash-language-server = mkLsp pkgs.bash-language-server "/bin/bash-language-server"; clangd = mkLsp pkgs.clang-tools "/bin/clangd"; haskell-language-server = mkLsp pkgs.haskell-language-server "/bin/haskell-language-server-wrapper"; # TODO: once upgraded past Nix-24.07 this line won't be necessary (I think) # helix will support nixd by default # SOURCE: https://github.com/nix-community/nixd/blob/main/nixd/docs/editor-setup.md#Helix nixd = mkLsp pkgs.nixd "/bin/nixd"; OmniSharp = mkLsp pkgs.omnisharp-roslyn "/bin/OmniSharp"; rust-analyzer = mkLsp pkgs.rust-analyzer "/bin/rust-analyzer"; ty = mkLsp pkgs.ty "/bin/ty"; }; in { environment.systemPackages = lsps |> map (lsp: lsp.pkg); # REF: https://docs.helix-editor.com/editor.html programs.helix = { enable = true; settings = { theme = "dracula"; editor = { line-number = "absolute"; popup-border = "all"; scroll-lines = 3; color-modes = true; # colour the mode indicator depending on mode shell = ["zsh" "-c"]; auto-format = true; auto-completion = true; # enable popup for autocomplete completion-timeout = 250; # time before completions display preview-completion-insert = true; completion-trigger-len = 2; # min word length to trigger completions completion-replace = true; # completions replace entire word indent-heuristic = "tree-sitter"; # how indentation is computed # TODO: make this configurable (enabled on myputer, disabled on lolcathost) middle-click-paste = true; insert-final-newline = true; # append newline to file on write gutters = [ "diagnostics" "spacer" "line-numbers" "spacer" "diff" ]; whitespace = { render = { space = "none"; # "all" tab = "none"; #"all" nbsp = "none"; nnbsp = "none"; newline = "none"; }; characters = { space = "·"; nbsp = "⍽"; nnbsp = "␣"; tab = "→"; newline = "⤶"; tabpad = "·"; # Tabs will look like "→···" (depending on tab width) }; }; indent-guides = { render = true; character = "▏"; # "|" skip-levels = 1; }; lsp = { enable = true; auto-signature-help = true; # hints for function parameters display-inlay-hints = true; # inline hints snippets = true; }; cursor-shape = { normal = "block"; insert = "bar"; select = "block"; }; file-picker = { hidden = true; # show hidden files follow-symlinks = true; deduplicate-links = true; git-ignore = false; # dont read .gitignore files ignore = true; # use .ignore for helix instead of .gitignore }; statusline = { left = [ "mode" "spacer" "version-control" "spinner" ]; center = [ "file-name" "read-only-indicator" "file-modification-indicator" ]; right = [ "position" "total-line-numbers" "file-encoding" "file-line-ending" "file-type" ]; separator = "|"; mode.normal = "NORMAL"; mode.insert = "INSERT"; mode.select = "SELECT"; }; }; }; languages = { language = [ { name = "nix"; indent = { tab-width = 2; unit = " "; }; block-comment-tokens = { start = "/*"; end = "*/"; }; auto-format = true; formatter.command = "${pkgs.alejandra}/bin/alejandra"; language-servers = ["nixd"]; } { name = "python"; indent = { tab-width = 4; unit = " "; }; auto-format = false; # my python is beautiful ^_^ rulers = [80]; language-servers = ["ty"]; } { name = "c"; file-types = ["c" "h"]; # use .hpp for C++ auto-format = true; formatter.command = "${pkgs.clang-tools}/bin/clang-format"; language-servers = ["clangd"]; } { name = "haskell"; auto-format = true; formatter.command = "${pkgs.ormolu}/bin/ormolu"; language-servers = ["haskell-language-server"]; } { name = "rust"; indent = { tab-width = 2; unit = " "; }; auto-format = true; formatter.command = "${pkgs.rustfmt}/bin/rustfmt"; language-servers = ["rust-analyzer"]; } { name = "c-sharp"; source = "source.cs"; file-types = ["cs"]; indent = { tab-width = 4; unit = " "; }; block-comment-tokens = { start = "/*"; end = "*/"; }; # auto-format = false; # formatter.command = "${pkgs.omnisharp-roslyn}/bin/OmniSharp"; # language-servers = ["OmniSharp"]; } ]; language-server = lsps |> builtins.mapAttrs (_: lsp: "${lsp.pkg}${lsp.path}"); }; }; }