Emacs major mode for Unison using tree-sitter.
Status: Ready for MELPA submission. Once accepted, install with M-x package-install RET unison-ts-mode.
- Install the package (see Installation)
- Open a
.ufile - you'll be prompted to install the tree-sitter grammar - (Optional) Enable LSP:
M-x eglotorM-x lsp
- Syntax highlighting with tree-sitter (4 customizable levels)
- Automatic indentation for all Unison constructs
- imenu support for navigation (functions, types, abilities)
- LSP integration (eglot and lsp-mode)
- UCM REPL integration with keybindings
- Auto-install of tree-sitter grammar
- Emacs 29+ (with native tree-sitter support)
- Unison tree-sitter grammar (auto-installed)
use-package + straight:
(use-package unison-ts-mode
:straight (:host github :repo "fmguerreiro/unison-ts-mode")
:mode ("\\.u\\'" "\\.unison\\'"))straight.el:
(straight-use-package
'(unison-ts-mode :type git :host github :repo "fmguerreiro/unison-ts-mode"))Doom Emacs:
;; packages.el
(package! unison-ts-mode :recipe (:host github :repo "fmguerreiro/unison-ts-mode"))The tree-sitter grammar installs automatically when you first open a .u file. Customize behavior with unison-ts-grammar-install:
'prompt(default): Ask before installing'auto: Install automaticallynil: Never auto-install
Manual install: M-x unison-ts-install-grammar
Custom grammar source:
(setq unison-ts-grammar-repository "https://github.com/yourname/tree-sitter-unison")
(setq unison-ts-grammar-revision "your-branch") ; OptionalCustomize highlighting depth via treesit-font-lock-level:
- comment, doc, string, declaration, preprocessor, error
- keyword, type, constant
- function-call, variable
- bracket, operator, delimiter
Apply changes: M-x treesit-font-lock-recompute-features
Navigate to functions, types, and abilities:
M-x imenu- Jump to definitionM-x which-function-mode- Show current function in mode line- Works with helm-imenu, counsel-imenu, consult-imenu
;; Auto-enable which-function-mode
(add-hook 'unison-ts-mode-hook 'which-function-mode)Requires UCM. UCM auto-starts in headless mode when you open a .u file.
Eglot (built-in Emacs 29+):
(with-eval-after-load 'unison-ts-mode
(with-eval-after-load 'eglot
(unison-ts-mode-setup-eglot)))
(add-hook 'unison-ts-mode-hook 'eglot-ensure)lsp-mode:
(with-eval-after-load 'unison-ts-mode
(with-eval-after-load 'lsp-mode
(unison-ts-mode-setup-lsp)))
(add-hook 'unison-ts-mode-hook 'lsp-deferred)Custom port:
export UNISON_LSP_PORT=5758Windows: LSP is disabled by default. Enable it:
[System.Environment]::SetEnvironmentVariable('UNISON_LSP_ENABLED','true')Manual UCM:
ucm headlessInteract with UCM directly from Emacs. Open the REPL with C-c C-u r or use these commands:
| Keybinding | Command | Description |
|---|---|---|
C-c C-u r |
unison-ts-repl |
Open UCM REPL |
C-c C-u a |
unison-ts-add |
Add definitions from current file |
C-c C-u u |
unison-ts-update |
Update existing definitions |
C-c C-u t |
unison-ts-test |
Run tests (prompts for pattern) |
C-c C-u x |
unison-ts-run |
Run a term |
C-c C-u w |
unison-ts-watch |
Watch current file for changes |
C-c C-u l |
unison-ts-load |
Load current file |
Grammar installation fails:
Install build tools:
# macOS
xcode-select --install
# Debian/Ubuntu
sudo apt-get install build-essential git
# Fedora/RHEL
sudo dnf install gcc gitABI version mismatch:
tree-sitter generate --abi=13Grammar not found:
Check ~/.emacs.d/tree-sitter/ or treesit-extra-load-path contains the compiled grammar.
LSP connection refused:
- Verify
ucmis in PATH:which ucm - Check port 5757:
lsof -i :5757(macOS/Linux) ornetstat -an | findstr 5757(Windows) - Start manually:
ucm headless - Check logs:
*EGLOT events*(eglot) or*lsp-log*(lsp-mode)
LSP features not working:
Ensure you're in a valid Unison codebase directory.
If auto-install fails:
git clone https://github.com/fmguerreiro/tree-sitter-unison.git
cd tree-sitter-unison
# Determine shared library extension
if [ "$(uname)" = "Darwin" ]; then soext="dylib"
elif uname | grep -q "MINGW"; then soext="dll"
else soext="so"; fi
cd src
cc -fPIC -c -I. parser.c
cc -fPIC -c -I. scanner.c
cc -fPIC -shared *.o -o "libtree-sitter-unison.${soext}"
# Copy to Emacs tree-sitter directory
mkdir -p ~/.emacs.d/tree-sitter
cp "libtree-sitter-unison.${soext}" ~/.emacs.d/tree-sitter/Use M-x treesit-explore-mode to inspect the syntax tree while developing or debugging.
Set up the pre-commit hook to run MELPA-style checks:
ln -s ../../scripts/pre-commit .git/hooks/pre-commitContributions welcome via GitHub pull requests.
GPL-3.0 License. See LICENSE for details.
Tree-sitter grammar by @kylegoetz.