GramEditor/gram
39
986
Fork
You've already forked gram
88

Nix package #29

Closed
opened 2026年03月04日 19:05:46 +01:00 by cyrneko · 17 comments

hiya! less so a request and moreso an issue to track this for when (or rather if) I contribute this in the future


a nix package, i.e a flake.nix + package definition for this would be quite nice, as it'd let users of nixOS just pull in this editor easily without having to package it themselves or run it against nix-ld (as dynamically linked binaries don't run by default.)

hiya! less so a request and moreso an issue to track this for when (or rather *if*) I contribute this in the future --- a nix package, i.e a `flake.nix` + package definition for this would be quite nice, as it'd let users of nixOS just pull in this editor easily without having to package it themselves or run it against `nix-ld` (as dynamically linked binaries don't run by default.)
Author
Copy link

oh, I saw that apparently Zed has a flake.nix, that could perhaps be adapted but it looks like they completely overcomplicated it.

oh, I saw that apparently Zed has a flake.nix, that *could* perhaps be adapted but it looks like they completely overcomplicated it.
Owner
Copy link

A flake.nix would be great yes, would be happy to see that 👍

A `flake.nix` would be great yes, would be happy to see that 👍

hmm, I feel this should rather be a Nix package published at nixpkgs ( https://search.nixos.org/packages )

Never built a Nix package, but working with Nix Flakes for nearly a year already, cannot promise anything yet but I'll give this a shot to see where it's gonna take me — hopefully we'll manage to publish gram as a Nix package eventually :)

hmm, I feel this should rather be a Nix package published at nixpkgs ( https://search.nixos.org/packages ) Never built a Nix package, but working with Nix Flakes for nearly a year already, cannot promise anything yet but I'll give this a shot to see where it's gonna take me — hopefully we'll manage to publish **gram** as a Nix package eventually :)
Owner
Copy link

There is a PR with in-progress work on Nix packaging already: #54

The title says flake but I think it’s for NixOS too.

There is a PR with in-progress work on Nix packaging already: #54 The title says flake but I think it’s for NixOS too.

yup, noticed the ref in the ticket. AFAIK a Nix Flake is different from a Nix Package in terms on how it's being served to clients.

  1. Nix Flake is consumed from the flake.nix as a dependency and then gets passed across a users flake in the outputs; this practice I've also seen for instance at nix-sops1 because they require baking the functionality into a Go binary
  2. Nix Package I feel has more flexibility because one can either install it across the entire system or via Home Manager2

In addition, I think having it as a Nix Package would also allow us benefit from having it available as a Home Manager offering with the ability to set certain fields, like you do for instance for VSCode3 (ie. setting certain configuration fields like theme, installing certain zed extensions and many more)

From this I can draw a small roadmap:

  1. have gram available in nixpkgs as a Nix Package
  2. have gram available in Home Manager programs

I've joined some Nix Discord communities and will ask the folks there about the best approach here to package this Rust app :)

Conceptually, to help grasp the difference of configuration for installing gram via Nix, here's how it would look like for each case.

Nix Flake

{
 description = "My personal flake";
 inputs = {
 nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
 nix-darwin.url = "github:LnL7/nix-darwin";
 nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
 gram-nix = {
 url = "codeberg:GramEditor/gram";
 inputs.nixpkgs.follows = "nixpkgs";
 };
 };
 outputs = { self, nix-darwin, nixpkgs, gram-nix }:
 let
 systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ];
 forAllSystems = nixpkgs.lib.genAttrs systems;
 darwinConfigurations = {
 "hostname" = nix-darwin.lib.darwinSystem {
 modules = [ ];
 };
 };
 nixosConfigurations = {
 "nixos" = nixpkgs.lib.nixosSystem {
 system = "x86_64-linux";
 modules = [
 home-manager.nixosModules.home-manager
 {
 home-manager.useGlobalPkgs = true;
 home-manager.useUserPackages = true;
 home-manager.extraSpecialArgs = { inherit gram-nix; };
 }
 ];
 specialArgs = { inherit gram-nix; };
 };
 };
 homeConfigurations = {
 "dminca" = home-manager.lib.homeManagerConfiguration {
 pkgs = import nixpkgs { system = "aarch64-darwin"; };
 modules = [
 sops-nix.homeManagerModules.sops
 ./hosts/common
 ./hosts/ZionProxy
 ];
 };
 "username" = home-manager.lib.homeManagerConfiguration {
 pkgs = import nixpkgs { system = "aarch64-darwin"; };
 modules = [
 gram-nix.homeManagerModules.gram
 ];
 };
 };
 in
 {
 inherit darwinConfigurations nixosConfigurations homeConfigurations;
 apps = forAllSystems (system: 
 let
 pkgs = import nixpkgs { inherit system; };
 in
 {
 default = {
 type = "app";
 program = toString (pkgs.writeShellScript "apply-config" ''
 set -e
 HOSTNAME=$(${pkgs.lib.getExe' pkgs.nettools "hostname"})
 if [[ "$OSTYPE" == "darwin"* ]]; then
 echo "🍎 Applying configuration for macOS host: $HOSTNAME"
${pkgs.lib.getExe pkgs.nh} darwin switch .
${pkgs.lib.getExe pkgs.nh} home switch .
 else
 echo "🐧 Applying configuration for NixOS host: $HOSTNAME"
${pkgs.lib.getExe pkgs.nh} os switch .
 fi
 '');
 };
 });
 };
}

Nix Package

{
 pkgs,
 ...
}:
{
 home.stateVersion = "23.11";
 home.packages = with pkgs; [
 gram
 ];
 programs.home-manager.enable = true;
}

Home Manager Package

{
 pkgs,
 lib,
 ...
}:
{
 programs.gram = {
 enable = true;
 package = lib.mkDefault pkgs.gram;
 profiles.default = {
 enableUpdateCheck = false;
 enableExtensionUpdateCheck = false;
 extensions = with pkgs.zed-extensions; [
 zed-jsonnet
 zed-yaml
 ];
 keybindings = [
 {
 key = "ctrl+shift+q";
 command = "workbench.action.toggleMaximizedPanel";
 }
 ];
 userSettings = {
 "git_panel.tree_view" = false;
 "minimap.show" = "auto";
 theme = {
 mode = "dark";
 light = "Rosé Pine Dawn";
 dark = "Catppuccin Mocha";
 };
 vim_mode = true;
 base_keymap = "VSCode";
 ui_font_size = 16;
 buffer_font_size = 15;
 lsp = {
 jsonnet-language-server = {
 settings = {
 log_level = "info";
 resolve_paths_with_tanka = true;
 }
 }
 }
 }
}
yup, noticed the ref in the ticket. AFAIK a _Nix Flake_ is different from a _Nix Package_ in terms on how it's being served to clients. 1. **Nix Flake** is consumed from the `flake.nix` as a dependency and then gets passed across a users flake in the `outputs`; this practice I've also seen for instance at `nix-sops`[^1] because they require baking the functionality into a Go binary 2. **Nix Package** I feel has more flexibility because one can either install it _across the entire system_ or via _Home Manager_[^2] In addition, I think having it as a _Nix Package_ would also allow us benefit from having it available as a _Home Manager_ offering with the ability to set certain fields, like you do for instance for VSCode[^3] (ie. setting certain configuration fields like theme, installing certain zed extensions and many more) From this I can draw a small roadmap: 1. have **gram** available in nixpkgs as a _Nix Package_ 2. have **gram** available in _Home Manager programs_ I've joined some Nix Discord communities and will ask the folks there about the best approach here to package this Rust app :) Conceptually, to help grasp the difference of configuration for installing **gram** via Nix, here's how it would look like for each case. ## Nix Flake <details> ```nix { description = "My personal flake"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; nix-darwin.url = "github:LnL7/nix-darwin"; nix-darwin.inputs.nixpkgs.follows = "nixpkgs"; gram-nix = { url = "codeberg:GramEditor/gram"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, nix-darwin, nixpkgs, gram-nix }: let systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ]; forAllSystems = nixpkgs.lib.genAttrs systems; darwinConfigurations = { "hostname" = nix-darwin.lib.darwinSystem { modules = [ ]; }; }; nixosConfigurations = { "nixos" = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ home-manager.nixosModules.home-manager { home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; home-manager.extraSpecialArgs = { inherit gram-nix; }; } ]; specialArgs = { inherit gram-nix; }; }; }; homeConfigurations = { "dminca" = home-manager.lib.homeManagerConfiguration { pkgs = import nixpkgs { system = "aarch64-darwin"; }; modules = [ sops-nix.homeManagerModules.sops ./hosts/common ./hosts/ZionProxy ]; }; "username" = home-manager.lib.homeManagerConfiguration { pkgs = import nixpkgs { system = "aarch64-darwin"; }; modules = [ gram-nix.homeManagerModules.gram ]; }; }; in { inherit darwinConfigurations nixosConfigurations homeConfigurations; apps = forAllSystems (system: let pkgs = import nixpkgs { inherit system; }; in { default = { type = "app"; program = toString (pkgs.writeShellScript "apply-config" '' set -e HOSTNAME=$(${pkgs.lib.getExe' pkgs.nettools "hostname"}) if [[ "$OSTYPE" == "darwin"* ]]; then echo "🍎 Applying configuration for macOS host: $HOSTNAME" ${pkgs.lib.getExe pkgs.nh} darwin switch . ${pkgs.lib.getExe pkgs.nh} home switch . else echo "🐧 Applying configuration for NixOS host: $HOSTNAME" ${pkgs.lib.getExe pkgs.nh} os switch . fi ''); }; }); }; } ``` </details> ## Nix Package <details> ```nix { pkgs, ... }: { home.stateVersion = "23.11"; home.packages = with pkgs; [ gram ]; programs.home-manager.enable = true; } ``` </details> ## Home Manager Package <details> ```nix { pkgs, lib, ... }: { programs.gram = { enable = true; package = lib.mkDefault pkgs.gram; profiles.default = { enableUpdateCheck = false; enableExtensionUpdateCheck = false; extensions = with pkgs.zed-extensions; [ zed-jsonnet zed-yaml ]; keybindings = [ { key = "ctrl+shift+q"; command = "workbench.action.toggleMaximizedPanel"; } ]; userSettings = { "git_panel.tree_view" = false; "minimap.show" = "auto"; theme = { mode = "dark"; light = "Rosé Pine Dawn"; dark = "Catppuccin Mocha"; }; vim_mode = true; base_keymap = "VSCode"; ui_font_size = 16; buffer_font_size = 15; lsp = { jsonnet-language-server = { settings = { log_level = "info"; resolve_paths_with_tanka = true; } } } } } ``` </details> [^1]: https://github.com/Mic92/sops-nix [^2]: https://github.com/nix-community/home-manager [^3]: https://home-manager-options.extranix.com/?query=programs.vscode&release=release-25.11

This sounds like a solid plan and a more long-term solution. It will also give more visibility to the package given it will be searchable via search.nixos.org.
However, for the short-term, and given work is already in progress, I believe there is still value in completing the creation of the flake. It might let some of the Nix people orbiting the project to start having a play with it.

This sounds like a solid plan and a more long-term solution. It will also give more visibility to the package given it will be searchable via [search.nixos.org](https://search.nixos.org/). However, for the short-term, and given work is already in progress, I believe there is still value in completing the creation of the flake. It might let some of the Nix people orbiting the project to start having a play with it.

certainly! there’s a huge benefit on having the flake available as well :)

Just stating out the available options here.

Having the flake ready will ease the development imo because you’d drop in a devShell and hack right into it, no to mention testing

certainly! there’s a huge benefit on having the flake available as well :) Just stating out the available options here. Having the flake ready will ease the development imo because you’d drop in a devShell and hack right into it, no to mention testing
Author
Copy link

@krig wrote in #29 (comment):

There is a PR with in-progress work on Nix packaging already: #54

The title says flake but I think it’s for NixOS too.

A nix flake can define anything, from a package to a development environment or something else. The flake PR takes from upstream Zed and tries to adjust it to match Gram's needs.

It exposes both a package (under nix/build.nix) and a development shell in form of nix/shell.nix.

This can be used on nixOS given that the nixOS configuration in question has Flakes enabled. It does not however mean that it's in the Nixpkgs repository maintained by nixOS themselves.

@krig wrote in https://codeberg.org/GramEditor/gram/issues/29#issuecomment-12005487: > There is a PR with in-progress work on Nix packaging already: #54 > > The title says flake but I think it’s for NixOS too. A nix flake can define anything, from a package to a development environment or something else. The flake PR takes from upstream Zed and tries to adjust it to match Gram's needs. It exposes both a package (under `nix/build.nix`) and a development shell in form of `nix/shell.nix`. This can be used on nixOS given that the nixOS configuration in question has Flakes enabled. It does *not* however mean that it's in the Nixpkgs repository maintained by nixOS themselves.
Owner
Copy link

Got it, thanks :)

Got it, thanks :)

The current flake PR here uses 3rd party build library and I've never seen a package in nixpkgs ever uses these kind of libraries, I doubt if it is even allowed in nixpkgs. It might be required to rewrite it with nixpkgs-native toolchain (e.g. rustPlatform.buildRustPackage). After all, you can import this flake like how you import nur if you're not using flake.

The current flake PR here uses [3rd party build library](https://github.com/ipetkov/crane) and I've never seen a package in nixpkgs ever uses these kind of libraries, I doubt if it is even allowed in nixpkgs. It might be required to rewrite it with nixpkgs-native toolchain (e.g. rustPlatform.buildRustPackage). After all, you can import this flake like how you import nur if you're not using flake.

Crane would not be allowed in nixpkgs, that is correct. FWIW, adapting the existing zed-editor package in nixpkgs to Gram is trivial and I have done so locally. I'm maintaining zed-editor in nixpkgs but if I do switch to Gram I may be willing to maintain a Gram package instead.

Crane would not be allowed in nixpkgs, that is correct. FWIW, adapting the existing zed-editor package in nixpkgs to Gram is trivial and I have done so locally. I'm maintaining zed-editor in nixpkgs but if I do switch to Gram I may be willing to maintain a Gram package instead.

The nixpkgs PR is ready, although I'm currently still trying to find out why it only works on Wayland and not on X11:
https://github.com/NixOS/nixpkgs/pull/508631

The nixpkgs PR is ready, although I'm currently still trying to find out why it only works on Wayland and not on X11: https://github.com/NixOS/nixpkgs/pull/508631
Owner
Copy link

Since there is a WIP PR open for some kind of Nix support I am going to close this. Anyone who wants to continue that work or do something different but nix-adjacent is welcome to open a new PR when ready.

Since there is a WIP PR open for some kind of Nix support I am going to close this. Anyone who wants to continue that work or do something different but nix-adjacent is welcome to open a new PR when ready.

Gram will be available as gram on nixos-26.05 and nixos-unstable once Hydra has finished building it sometime this week. The package also supports macOS / darwin (for which you should use nixpkgs-unstable or nixpkgs-26.05-darwin).

The gram remote server can be accessed through the gram.remote_server output, which makes it convenient to install on a NixOS remote target. There currently is no Gram page on the NixOS wiki, but until then you can refer to https://wiki.nixos.org/wiki/Zed#Remote_server which works similiarly.

Edit: There now is a wiki page at https://wiki.nixos.org/wiki/Gram but it does not have a section about the remote server setup yet.

Gram will be available as `gram` on `nixos-26.05` and `nixos-unstable` once Hydra has finished building it sometime this week. The package also supports macOS / darwin (for which you should use `nixpkgs-unstable` or `nixpkgs-26.05-darwin`). The gram remote server can be accessed through the `gram.remote_server` output, which makes it convenient to install on a NixOS remote target. There currently is no Gram page on the NixOS wiki, but until then you can refer to <https://wiki.nixos.org/wiki/Zed#Remote_server> which works similiarly. Edit: There now is a wiki page at <https://wiki.nixos.org/wiki/Gram> but it does not have a section about the remote server setup yet.
Owner
Copy link

Cool!

Cool!

Jumping in on this issue, trying to figure out a way to declaratively add extensions/themes.
Curious if any of you have a method you've been using?

Jumping in on this issue, trying to figure out a way to declaratively add extensions/themes. Curious if any of you have a method you've been using?

I've been experimenting with this last week, and while it's still early stage, I already got the gdscript extension to work, including language server and grammar. It's a bit hacky right now, but this is the package definition:

{
 rustPlatform,
 fetchFromGitHub,
 wasiPkgs,
}:
let
 tree-sitter-gdscript = wasiPkgs.tree-sitter.buildGrammar {
 language = "gdscript";
 version = "0b9f60ebaa1c31f5153dd3a3b283ca0725734378";
 src = fetchFromGitHub {
 owner = "PrestonKnopp";
 repo = "tree-sitter-gdscript";
 rev = "0b9f60ebaa1c31f5153dd3a3b283ca0725734378";
 hash = "sha256-AqKF6nJcWlt9+xrKKImY71UF5KGdF1eVf0pa6WCUVac=";
 };
 };
in
rustPlatform.buildRustPackage (finalAttrs: {
 pname = "gdscript-extension";
 version = "0.9.0";
 src = fetchFromGitHub {
 owner = "GDQuest";
 repo = "zed-gdscript";
 tag = finalAttrs.version;
 hash = "sha256-AK3vcDoIWxRky7sXbXTtjy5whNDA1+rim6O8lyiMxlg=";
 };
 # Upstream does not include a lockfile in their repository, so we must add one
 postPatch = ''
 cp ${./gdscript.lock} Cargo.lock
 '';
 cargoLock.lockFile = ./gdscript.lock;
 cargoBuildFlags = [ "--target=wasm32-wasip2" ];
 installPhase = ''
 mkdir -p $out
 mv target/wasm32-wasip2/release/zed_gdscript.wasm $out/extension.wasm
 mv extension.toml $out/
 mv languages $out/
 mv debug_adapter_schemas $out/
 mkdir -p $out/grammars
 ln -s ${tree-sitter-gdscript}/parser.wasm $out/grammars/gdscript.wasm
 # Note that this one will fail to load at runtime unlike the above as it uses a
 # different commit rev than required by the extension.
 ln -s ${wasiPkgs.tree-sitter-grammars.tree-sitter-godot-resource}/parser.wasm $out/grammars/godot_resource.wasm
 '';
})

where

 pkgs = import nixpkgs {
 inherit system;
 overlays = [ rust-overlay.overlays.default ];
 };
 wasiPkgs = import nixpkgs {
 inherit system;
 crossSystem = {
 config = "wasm32-wasi";
 rust.rustcTarget = "wasm32-wasip2";
 useLLVM = true;
 };
 };
 toolchain = pkgs.rust-bin.stable.latest.default.override {
 targets = [ "wasm32-wasip2" ];
 };
 rustPlatform = pkgs.makeRustPlatform {
 cargo = toolchain;
 rustc = toolchain;
 };

(note that I have been unable to fully use nixpkgs' own cross compilation for this and currently rely on the bundled wasm target of rust-overlay, but there is a PR that might make the rust-overlay dependency obsolete)

The resulting derivation output can then be symlinked into ~/.local/share/gram/extensions/installed (I think it was installed, I'm not not at my desktop right now) and Gram loads it correctly.

It's important to use the same commit revs of tree sitter grammars as declared in the extension.toml instead of nixpkgs' own versions, otherwise the tree sitter scheme declarations included in the extension may be incompatible and the syntax highlighting fails to load.

I've been experimenting with this last week, and while it's still early stage, I already got the [gdscript extension](https://github.com/GDQuest/zed-gdscript/tree/main) to work, including language server and grammar. It's a bit hacky right now, but this is the package definition: ```nix { rustPlatform, fetchFromGitHub, wasiPkgs, }: let tree-sitter-gdscript = wasiPkgs.tree-sitter.buildGrammar { language = "gdscript"; version = "0b9f60ebaa1c31f5153dd3a3b283ca0725734378"; src = fetchFromGitHub { owner = "PrestonKnopp"; repo = "tree-sitter-gdscript"; rev = "0b9f60ebaa1c31f5153dd3a3b283ca0725734378"; hash = "sha256-AqKF6nJcWlt9+xrKKImY71UF5KGdF1eVf0pa6WCUVac="; }; }; in rustPlatform.buildRustPackage (finalAttrs: { pname = "gdscript-extension"; version = "0.9.0"; src = fetchFromGitHub { owner = "GDQuest"; repo = "zed-gdscript"; tag = finalAttrs.version; hash = "sha256-AK3vcDoIWxRky7sXbXTtjy5whNDA1+rim6O8lyiMxlg="; }; # Upstream does not include a lockfile in their repository, so we must add one postPatch = '' cp ${./gdscript.lock} Cargo.lock ''; cargoLock.lockFile = ./gdscript.lock; cargoBuildFlags = [ "--target=wasm32-wasip2" ]; installPhase = '' mkdir -p $out mv target/wasm32-wasip2/release/zed_gdscript.wasm $out/extension.wasm mv extension.toml $out/ mv languages $out/ mv debug_adapter_schemas $out/ mkdir -p $out/grammars ln -s ${tree-sitter-gdscript}/parser.wasm $out/grammars/gdscript.wasm # Note that this one will fail to load at runtime unlike the above as it uses a # different commit rev than required by the extension. ln -s ${wasiPkgs.tree-sitter-grammars.tree-sitter-godot-resource}/parser.wasm $out/grammars/godot_resource.wasm ''; }) ``` where ```nix pkgs = import nixpkgs { inherit system; overlays = [ rust-overlay.overlays.default ]; }; wasiPkgs = import nixpkgs { inherit system; crossSystem = { config = "wasm32-wasi"; rust.rustcTarget = "wasm32-wasip2"; useLLVM = true; }; }; toolchain = pkgs.rust-bin.stable.latest.default.override { targets = [ "wasm32-wasip2" ]; }; rustPlatform = pkgs.makeRustPlatform { cargo = toolchain; rustc = toolchain; }; ``` (note that I have been unable to fully use nixpkgs' own cross compilation for this and currently rely on the bundled wasm target of rust-overlay, but [there is a PR](https://github.com/NixOS/nixpkgs/pull/537433) that might make the rust-overlay dependency obsolete) The resulting derivation output can then be symlinked into `~/.local/share/gram/extensions/installed` (I think it was `installed`, I'm not not at my desktop right now) and Gram loads it correctly. It's important to use the same commit revs of tree sitter grammars as declared in the [`extension.toml`](https://github.com/GDQuest/zed-gdscript/blob/main/extension.toml) instead of nixpkgs' own versions, otherwise the tree sitter scheme declarations included in the extension may be incompatible and the syntax highlighting fails to load.
Sign in to join this conversation.
No Branch/Tag specified
main
test/wgpu-on-mac
test-ci/failing-test-mac
test/failing-test-mac
test/build-on-22-04
test/wgpu-present-mode-mailbox
v2.1
test/altgr-fix-again
test/2.0.0-rc1
test/linux-build
test/objc2
v1.2.1
3.0.1
3.0.0
2.2.0
2.1.2
2.1.1
2.1.0
2.0.0
1.2.1
1.2.0
1.1.0
1.0.0
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
7 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
GramEditor/gram#29
Reference in a new issue
GramEditor/gram
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?