From 936fb7b22f2ed856fd7e858b5973c6ea9942b9ec Mon Sep 17 00:00:00 2001 From: Greg Pfeil Date: Mon, 1 Jul 2024 09:25:32 -0600 Subject: [PATCH 1/3] Add the VScode extension for Unison --- flake.nix | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/flake.nix b/flake.nix index 9c0e869..330d3e4 100644 --- a/flake.nix +++ b/flake.nix @@ -39,6 +39,13 @@ name = "vim-unison"; src = unison + "/editor-support/vim"; }; + + vscode-extension = pkgs.vscode-utils.extensionFromVscodeMarketplace { + name = "unison"; + publisher = "unison-lang"; + version = "1.2.0"; + sha256 = "ulm3a1xJxtk+SIQP1sByEqgajd1a4P3oEfVgxoF5GcQ="; + }; }; in flake-utils.lib.eachSystem systems @@ -72,6 +79,9 @@ unison-ucm = localPkgs.ucm; vimPlugins = prev.vimPlugins // self.overlays.vim final prev; + + vscode-extensions = + prev.vscode-extensions // self.overlays.vscode final prev; }; emacs = final: prev: efinal: eprev: { @@ -92,6 +102,10 @@ }; vim = final: prev: {inherit (localPackages final) vim-unison;}; + + vscode = final: prev: { + unison-lang.unison = (localPackages final).vscode-extension; + }; }; ## Deprecated @@ -179,6 +193,12 @@ enable = true; plugins = with pkgs.vimPlugins; [vim-unison]; }; + vscode = { + enable = true; + extensions = with pkgs.vscode-extensions; [unison-lang.unison]; + package = pkgs.vscodium; # To avoid needing unfree packages. + userSettings."unison.lspPort" = 1234; + }; }; }) ]; From 761223d683ab490176abf6ff2784618241a3e918 Mon Sep 17 00:00:00 2001 From: Greg Pfeil Date: Tue, 18 Feb 2025 11:36:35 -0700 Subject: [PATCH 2/3] Extract the Home Manager config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was getting too long to keep in the flake, and it works better as an example on its own. I also documented the HM config a bit, and made some changes that made more sense once it was extracted: - added a tree-sitter grammar derivation to packages; - moved `self.lib.tree-sitter-grammars` to `self.overlays.tree-sitter`; - overlaid the Unison tree-sitter grammar on the `nvim-treesitter` Vim plugin; - added our overlay to Nixpkgs in the HM config, rather than `import nixpkgs …`; - split up the Home Manager sections to make the distinct configs more obvious; - made the Emacs’ config _slightly_ less annoying; - removed `programs.emacs.package` (Emacs 29 is the default now); - added `programs.neovim` to the HM config; and - updated `home.stateVersion`. [^1]: I was hoping to get rid of the former, since there is now a derivation for the grammar, but it seems `pkgs.tree-sitter` wants to make all its derivations itself. --- flake.nix | 132 ++++++++++++++++++++++----------------------------- nix/home.nix | 90 +++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 75 deletions(-) create mode 100644 nix/home.nix diff --git a/flake.nix b/flake.nix index 330d3e4..6ac5ef3 100644 --- a/flake.nix +++ b/flake.nix @@ -35,6 +35,12 @@ in { ucm = pkgs.callPackage ./nix/ucm.nix {inherit darwin-security-hack;}; + tree-sitter-grammar = pkgs.tree-sitter.buildGrammar { + language = "unison"; + version = tree-sitter-unison-github.rev; + src = pkgs.fetchFromGitHub tree-sitter-unison-github; + }; + vim-unison = pkgs.vimUtils.buildVimPlugin { name = "vim-unison"; src = unison + "/editor-support/vim"; @@ -72,13 +78,14 @@ (self.overlays.emacs final prev); tree-sitter = prev.tree-sitter.override { - extraGrammars = self.lib.tree-sitter-grammars final; + extraGrammars = self.overlays.tree-sitter final prev; }; ## Renamed to replace the `unison-ucm` included in Nixpkgs. unison-ucm = localPkgs.ucm; - vimPlugins = prev.vimPlugins // self.overlays.vim final prev; + vimPlugins = + prev.vimPlugins // self.overlays.vim final prev prev.vimPlugins; vscode-extensions = prev.vscode-extensions // self.overlays.vscode final prev; @@ -101,7 +108,40 @@ }; }; - vim = final: prev: {inherit (localPackages final) vim-unison;}; + ## This is automatically added to the available `tree-sitter` grammars + ## in the default overlay. However, `extraGrammars` doesn’t compose, so + ## if another overlay also provides a grammar, one will overwrite the + ## other. The way around that is to explicitly combine the grammars in a + ## final overlay, + ## + ## final: prev: { + ## tree-sitter = prev.tree-sitter.override { + ## extraGrammars = + ## unison.overlays.tree-sitter final prev + ## // ; + ## }; + ## } + ## + ## NB: tree-sitter doesn’t seem to be able to take grammar derivations, + ## so we give it the source. + tree-sitter = final: prev: { + tree-sitter-unison.src = + final.fetchFromGitHub tree-sitter-unison-github; + }; + + vim = final: prev: vpkgs: let + localPkgs = localPackages final; + in { + inherit (localPkgs) vim-unison; + + nvim-treesitter = vpkgs.nvim-treesitter.overrideAttrs (old: { + builtGrammars = + old.builtGrammars + // { + unison = localPkgs.tree-sitter-grammar; + }; + }); + }; vscode = final: prev: { unison-lang.unison = (localPackages final).vscode-extension; @@ -124,84 +164,26 @@ buildUnisonFromTranscript = buildUnisonFromTranscript pkgs; }; - ## This is automatically added to the available `tree-sitter` grammars - ## in the default overlay. However, `extraGrammars` doesn’t compose, so - ## if another overlay also provides a grammar, one will overwrite the - ## other. The way around that is to explicitly combine the grammars in a - ## final overlay, + ## Emacs’s `treesit` package wants to pull grammars from Git repos, so + ## this provides the Emacs Lisp form to pull the same grammer packaged + ## in this flake. ## - ## final: prev: { - ## tree-sitter = prev.tree-sitter.override { - ## extraGrammars = - ## unison-nix.lib.tree-sitter-grammars final - ## // ; - ## }; - ## } - tree-sitter-grammars = pkgs: { - tree-sitter-unison.src = - pkgs.fetchFromGitHub tree-sitter-unison-github; - }; + ## See ./nix/home.nix for example usage. + ## + ## TODO: Convince Emacs to use the packaged grammar. + emacsTreesitLanguageSource = '' + (unison + "git@github.com:${tree-sitter-unison-github.owner}/${tree-sitter-unison-github.repo}.git" + "${tree-sitter-unison-github.rev}") + ''; }; homeConfigurations = builtins.listToAttrs (map (system: { name = "${system}-example"; value = home-manager.lib.homeManagerConfiguration { - pkgs = import nixpkgs { - inherit system; - overlays = [self.overlays.default]; - }; - modules = [ - ({pkgs, ...}: { - home = { - packages = [ - (pkgs.tree-sitter.withPlugins (tpkgs: [ - tpkgs.tree-sitter-unison - ])) - pkgs.unison-ucm - ]; - stateVersion = "23.11"; - username = "example"; - homeDirectory = "/home/example"; - }; - programs = { - emacs = { - enable = true; - extraConfig = '' - (use-package eglot - :config - (add-to-list - 'eglot-server-programs - '((unison-ts-mode unisonlang-mode) "127.0.0.1" 5757))) - ;; TODO: This should be made available via - ;; `pkgs.tree-sitter.withPlugins` above, but they - ;; currently don’t align, so you need this, then run - ;; `M-x treesit-install-language-grammar` and select - ;; “unison”. - (use-package treesit - :config - (add-to-list - 'treesit-language-source-alist - '(unison - "git@github.com:${tree-sitter-unison-github.owner}/${tree-sitter-unison-github.repo}.git" - "${tree-sitter-unison-github.rev}"))) - (use-package unison-ts-mode) - ''; - extraPackages = epkgs: [epkgs.unison-ts-mode]; - package = pkgs.emacs29; - }; - vim = { - enable = true; - plugins = with pkgs.vimPlugins; [vim-unison]; - }; - vscode = { - enable = true; - extensions = with pkgs.vscode-extensions; [unison-lang.unison]; - package = pkgs.vscodium; # To avoid needing unfree packages. - userSettings."unison.lspPort" = 1234; - }; - }; - }) - ]; + extraSpecialArgs.unison = self; + modules = [./nix/home.nix]; + pkgs = nixpkgs.legacyPackages.${system}; }; }) ["aarch64-darwin" "x86_64-darwin" "x86_64-linux"]); }; diff --git a/nix/home.nix b/nix/home.nix new file mode 100644 index 0000000..561e439 --- /dev/null +++ b/nix/home.nix @@ -0,0 +1,90 @@ +### An example Home Manager configuration with Unison set up as many ways as +### possible. +### +### Search for “→” to see the important bits. +{ + pkgs, + ## → This argument is made available to the configuration via the + ## `extraSpecialArgs` field in the flake’s `homeConfigurations` output. + unison, + ... +}: { + nixpkgs.overlays = [ + ## → Make all of the Unison-enriched derivations available. + unison.overlays.default + ]; + + home.packages = [ + ## → Install tree-sitter with the Unison grammar. + (pkgs.tree-sitter.withPlugins (tpkgs: [ + tpkgs.tree-sitter-unison + ])) + + ## → Install the Unison Codebase Manager itself. + pkgs.unison-ucm + ]; + + programs.emacs = { + enable = true; + extraConfig = '' + ;; → Set up LSP for Unison. + (use-package eglot + :config + (add-to-list + 'eglot-server-programs + '((unison-ts-mode unisonlang-mode) "127.0.0.1" 5757))) + + ;; → Enable the Emacs treesit package with the Unison grammar. + (use-package treesit + :config + ;; TODO: This should be made available via + ;; `pkgs.tree-sitter.withPlugins` above, but they currently don’t + ;; align, so you need this. + (add-to-list + 'treesit-language-source-alist + '${unison.lib.emacsTreesitLanguageSource}) + (treesit-install-language-grammar 'unison)) + + ;; → Enable the Unison Emacs mode. + (use-package unison-ts-mode) + ''; + extraPackages = epkgs: [ + ## → Install the Unison Emacs mode. + epkgs.unison-ts-mode + ]; + }; + + programs.neovim = { + enable = true; + plugins = with pkgs.vimPlugins; [ + ## → Install the Neovim treesitter plugin with the Unison grammar. + (nvim-treesitter.withPlugins (tspkgs: [tspkgs.unison])) + ]; + }; + + programs.vim = { + enable = true; + plugins = with pkgs.vimPlugins; [ + ## → Install the Vim Unison plugin. + vim-unison + ]; + }; + + programs.vscode = { + enable = true; + extensions = with pkgs.vscode-extensions; [ + ## → Install the VS Code Unison extension. + unison-lang.unison + ]; + package = pkgs.vscodium; # To avoid needing unfree packages. + ## → Configure the VS Code Unison extension. + userSettings."unison.lspPort" = 1234; + }; + + ## Unimportant configuration needed by Home Manager. + home = { + stateVersion = "24.11"; + username = "example"; + homeDirectory = "/home/example"; + }; +} From 08fbb0960840bfa0a5edae4a9424aae829019718 Mon Sep 17 00:00:00 2001 From: Greg Pfeil Date: Tue, 18 Feb 2025 12:15:56 -0700 Subject: [PATCH 3/3] Add a GitHub job to build the `homeConfiguration` --- .github/workflows/test.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 634c094..0de2b10 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,3 +19,17 @@ jobs: - run: | nix-build default.nix -A unison-ucm PATH='' ./result/bin/ucm --version + test_homeConfiguration: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2 + - uses: nixbuild/nix-quick-install-action@25aff27c252e0c8cdda3264805f7b6bcd92c8718 # # v29 + - uses: nix-community/cache-nix-action@8351fb9f51c580c96c509987ebb99e38aed956ce # 5.2.1 + with: + # restore and save a cache using this key + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix') }} + # if there's no cache hit, restore a cache by this prefix + restore-prefixes-first-match: nix-${{ runner.os }}- + - run: | + nix run github:nix-community/home-manager -- build --flake .#x86_64-linux-example + PATH='' ./result/home-path/bin/ucm --version