diff --git a/devenv/default.nix b/devenv/default.nix index 0ce66700..eaa60df8 100644 --- a/devenv/default.nix +++ b/devenv/default.nix @@ -113,6 +113,9 @@ in { agenix age-plugin-yubikey alejandra + fennel + fennel-ls + fnlfmt hcloud installTestVM just diff --git a/flake.lock b/flake.lock index 3d47b7ee..9b557a44 100644 --- a/flake.lock +++ b/flake.lock @@ -206,6 +206,23 @@ "type": "github" } }, + "fennel-tree-sitter": { + "flake": false, + "locked": { + "lastModified": 1706884626, + "narHash": "sha256-BdhgDS+yJ/DUYJknVksLSNHvei+MOkqVW7gp6AffKhU=", + "owner": "TravonteD", + "repo": "tree-sitter-fennel", + "rev": "15e4f8c417281768db17080c4447297f8ff5343a", + "type": "github" + }, + "original": { + "owner": "TravonteD", + "ref": "1.1.0", + "repo": "tree-sitter-fennel", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -430,6 +447,35 @@ "type": "github" } }, + "helix-editor": { + "inputs": { + "crane": [ + "crane" + ], + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": [ + "rust-overlay" + ] + }, + "locked": { + "lastModified": 1725976743, + "narHash": "sha256-pLQQbiC9uO4lF58fAnlcDxlbsBB1XFWswsU1oZOIVqU=", + "owner": "helix-editor", + "repo": "helix", + "rev": "237cbe4bca46eed52efed39ed75eb44aaccbdde3", + "type": "github" + }, + "original": { + "owner": "helix-editor", + "repo": "helix", + "type": "github" + } + }, "hetzner-csi-driver": { "flake": false, "locked": { @@ -992,10 +1038,12 @@ "devenv": "devenv", "disko": "disko", "fenix": "fenix", + "fennel-tree-sitter": "fennel-tree-sitter", "flake-compat": "flake-compat", "flake-parts": "flake-parts_2", "flake-utils": "flake-utils_2", "fluxcd-install": "fluxcd-install", + "helix-editor": "helix-editor", "hetzner-csi-driver": "hetzner-csi-driver", "home-manager": "home-manager", "impermanence": "impermanence", diff --git a/flake.nix b/flake.nix index eb5fa127..6d753569 100644 --- a/flake.nix +++ b/flake.nix @@ -4,18 +4,19 @@ nixConfig = { extra-experimental-features = "nix-command flakes"; extra-substituters = [ - "https://nix-community.cachix.org" - "https://insane.cachix.org" + "https://cache.flox.dev" "https://cachix.cachix.org" "https://hyprland.cachix.org" - "https://cache.flox.dev" + "https://insane.cachix.org" + "https://nix-community.cachix.org" ]; + extra-trusted-public-keys = [ - "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - "insane.cachix.org-1:cLCCoYQKkmEb/M88UIssfg2FiSDUL4PUjYj9tdo4P8o=" "cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM=" - "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" "flox-cache-public-1:7F4OyH7ZCnFhcze3fJdfyXYLQw/aV7GEed86nQ7IsOs=" + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + "insane.cachix.org-1:cLCCoYQKkmEb/M88UIssfg2FiSDUL4PUjYj9tdo4P8o=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; }; @@ -45,6 +46,8 @@ devenv.url = "github:cachix/devenv"; disko.inputs.nixpkgs.follows = "nixpkgs"; disko.url = "github:nix-community/disko"; + fennel-tree-sitter.flake = false; + fennel-tree-sitter.url = "github:TravonteD/tree-sitter-fennel/1.1.0"; fenix.inputs.nixpkgs.follows = "nixpkgs"; fenix.url = "github:nix-community/fenix"; flake-compat.flake = false; @@ -53,6 +56,11 @@ flake-utils.inputs.systems.follows = "systems"; fluxcd-install.flake = false; fluxcd-install.url = "https://github.com/fluxcd/flux2/releases/download/v2.3.0/install.yaml"; # gh-release-update + helix-editor.url = "github:helix-editor/helix"; + helix-editor.inputs.nixpkgs.follows = "nixpkgs"; + helix-editor.inputs.flake-utils.follows = "flake-utils"; + helix-editor.inputs.rust-overlay.follows = "rust-overlay"; + helix-editor.inputs.crane.follows = "crane"; hetzner-csi-driver.flake = false; hetzner-csi-driver.url = "https://raw.githubusercontent.com/hetznercloud/csi-driver/v2.9.0/deploy/kubernetes/hcloud-csi.yml"; # gh-release-update home-manager.inputs.nixpkgs.follows = "nixpkgs"; diff --git a/flake/packages.nix b/flake/packages.nix index f996ef2e..0eef5de4 100644 --- a/flake/packages.nix +++ b/flake/packages.nix @@ -122,6 +122,57 @@ boot.kernelPackages = lib.mkForce pkgs.linuxPackages_latest; } ]; + helix-latest = inputs.helix-editor.packages.${system}.default.override { + grammarOverlays = [ + (final: prev: { + fennel = pkgs.stdenv.mkDerivation { + pname = "helix-tree-sitter-fennel"; + version = inputs.fennel-tree-sitter.rev; + src = inputs.fennel-tree-sitter; + sourceRoot = "source"; + dontConfigure = true; + FLAGS = [ + "-Isrc" + "-g" + "-O3" + "-fPIC" + "-fno-exceptions" + "-Wl,-z,relro,-z,now" + ]; + NAME = "fennel"; + buildPhase = '' + runHook preBuild + + if [[ -e src/scanner.cc ]]; then + $CXX -c src/scanner.cc -o scanner.o $FLAGS + elif [[ -e src/scanner.c ]]; then + $CC -c src/scanner.c -o scanner.o $FLAGS + fi + + $CC -c src/parser.c -o parser.o $FLAGS + $CXX -shared -o $NAME.so *.o + + ls -al + + runHook postBuild + ''; + installPhase = '' + runHook preInstall + mkdir $out + mv $NAME.so $out/ + runHook postInstall + ''; + + # Strip failed on darwin: strip: error: symbols referenced by indirect symbol table entries that can't be stripped + fixupPhase = lib.optionalString pkgs.stdenv.isLinux '' + runHook preFixup + $STRIP $out/$NAME.so + runHook postFixup + ''; + }; + }) + ]; + }; zjstatus = inputs.zjstatus.packages.${system}.default; zwift = inputs.zwift.packages.${system}.default; persway = inputs.persway.packages.${system}.default; diff --git a/users/profiles/helix.nix b/users/profiles/helix.nix index d20a2898..289c8bcf 100644 --- a/users/profiles/helix.nix +++ b/users/profiles/helix.nix @@ -15,10 +15,88 @@ OPENROUTER_API_KEY="$(cat /run/agenix/openrouter-lsp-ai)" export OPENROUTER_API_KEY fi - exec ${pkgs.helix}/bin/hx "''$@" + exec ${pkgs.helix-latest}/bin/hx "''$@" ''; }; in { + xdg.configFile."helix/runtime/queries/fennel/highlights.scm".source = pkgs.writeText "fennel-highlights.scm" '' + (comment) @comment + + [ "(" ")" "{" "}" "[" "]" ] @punctuation.bracket + + [ ":" ":until" "&" "&as" "?" ] @punctuation.special + + (nil) @constant.builtin + (vararg) @punctuation.special + + (boolean) @constant.builtin.boolean + (number) @constant.numeric + + (string) @string + (escape_sequence) @constant.character.escape + + + ((symbol) @variable.builtin + (#match? @variable.builtin "^[$]")) + + (binding) @symbol + + [ "fn" "lambda" "hashfn" "#" ] @keyword.function + + (fn name: [ + (symbol) @function + (multi_symbol (symbol) @function .) + ]) + + (lambda name: [ + (symbol) @function + (multi_symbol (symbol) @function .) + ]) + + (multi_symbol + "." @punctuation.delimiter + (symbol) @variable.other.member) + + (multi_symbol_method + ":" @punctuation.delimiter + (symbol) @function.method .) + + [ "for" "each" ] @keyword.control.repeat + ((symbol) @keyword.control.repeat + (#eq? @keyword.control.repeat + "while")) + + [ "match" ] @keyword.control.conditional + ((symbol) @keyword.control.conditional + (#match? @keyword.control.conditional "^(if|when)$")) + + [ "global" "local" "let" "set" "var" "where" "or" ] @keyword + ((symbol) @keyword + (#match? @keyword + "^(comment|do|doc|eval-compiler|lua|macros|quote|tset|values)$")) + + ((symbol) @keyword.control.import + (#match? @keyword.control.import + "^(require|require-macros|import-macros|include)$")) + + [ "collect" "icollect" "accumulate" ] @function.macro + ((symbol) @function.macro + (#match? @function.macro + "^(->|->>|-\\?>|-\\?>>|\\?\\.|doto|macro|macrodebug|partial|pick-args|pick-values|with-open)$")) + + ; Lua builtins + ((symbol) @constant.builtin + (#match? @constant.builtin + "^(arg|_ENV|_G|_VERSION)$")) + + ((symbol) @function.builtin + (#match? @function.builtin + "^(assert|collectgarbage|dofile|error|getmetatable|ipairs|load|loadfile|loadstring|module|next|pairs|pcall|print|rawequal|rawget|rawlen|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|warn|xpcall)$")) + + (list . (symbol) @function) + (list . (multi_symbol (symbol) @function .)) + (symbol) @variable + ''; programs.helix = { enable = true; package = helix-ai; @@ -80,6 +158,9 @@ in { }; languages = { language-server = { + fennel-ls = { + command = "fennel-ls"; + }; lsp-ai = { command = "lsp-ai"; config.memory.file_store = {}; @@ -357,6 +438,26 @@ in { name = "yaml"; language-servers = ["yaml-language-server" "lsp-ai"]; } + { + name = "fennel"; + scope = "source.fnl"; + injection-regex = "(fennel|fnl)"; + file-types = ["fnl"]; + shebangs = ["fennel"]; + roots = []; + comment-token = ";"; + indent = { + tab-width = 2; + unit = " "; + }; + formatter = { + command = "fnlfmt"; + args = ["-"]; + }; + language-servers = ["fennel-ls" "lsp-ai"]; + grammar = "fennel"; + auto-format = true; + } { name = "lua"; formatter = {