Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the VS Code extension for Unison #114

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
140 changes: 71 additions & 69 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,23 @@
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";
};

vscode-extension = pkgs.vscode-utils.extensionFromVscodeMarketplace {
name = "unison";
publisher = "unison-lang";
version = "1.2.0";
sha256 = "ulm3a1xJxtk+SIQP1sByEqgajd1a4P3oEfVgxoF5GcQ=";
};
};
in
flake-utils.lib.eachSystem systems
Expand All @@ -65,13 +78,17 @@
(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;
};

emacs = final: prev: efinal: eprev: {
Expand All @@ -91,7 +108,44 @@
};
};

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
## // <grammars from other flakes>;
## };
## }
##
## 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;
};
};

## Deprecated
Expand All @@ -110,78 +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
## // <grammars from other flakes>;
## };
## }
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
"[email protected]:${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
"[email protected]:${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];
};
};
})
];
extraSpecialArgs.unison = self;
modules = [./nix/home.nix];
pkgs = nixpkgs.legacyPackages.${system};
};
}) ["aarch64-darwin" "x86_64-darwin" "x86_64-linux"]);
};
Expand Down
90 changes: 90 additions & 0 deletions nix/home.nix
Original file line number Diff line number Diff line change
@@ -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";
};
}