Skip to content

Instantly share code, notes, and snippets.

@zetashift
Created November 11, 2023 17:35
Show Gist options
  • Save zetashift/9f9d43f30d408a749204aee634fa4add to your computer and use it in GitHub Desktop.
Save zetashift/9f9d43f30d408a749204aee634fa4add to your computer and use it in GitHub Desktop.
;;; unison-ts-mode.el --- Major mode for Unison with tree-sitter support -*- lexical-binding: t; -*-
(require 'treesit)
(require 'rx)
(declare-function treesit-parser-create "treesit.c")
(declare-function treesit-node-type "treesit.c")
(declare-function treesit-node-text "treesit.c")
(declare-function treesit-node-child-by-field-name "treesit.c")
(declare-function treesit-parent-while "treesit.c")
(declare-function treesit-parent-until "treesit.c")
(declare-function treesit-node-prev-sibling "treesit.c")
(declare-function treesit-node-next-sibling "treesit.c")
(declare-function treesit-node-type "treesit.c")
(declare-function treesit-node-text "treesit.c")
(declare-function treesit-node-start "treesit.c")
(declare-function treesit-node-end "treesit.c")
(declare-function treesit-node-child "treesit.c")
(defcustom unison-ts-indent-offset 2
"Number of spaces for each indentation in `unison-ts-mode'."
:version "29.1"
:type 'integer
:safe 'integerp
:group 'unison-ts)
(defvar unison-ts--keywords
'("use" "if" "else" "then" "unique" "structural"))
(defvar unison-ts--brackets
'("(" ")" "{" "}" "[" "]"))
(defvar unison-ts--treesit-font-lock-settings
(treesit-font-lock-rules
:language 'unison
:feature 'keyword
`([,@unison-ts--keywords] @font-lock-keyword-face
(kw_forall) @font-lock-keyword-face
(unique_kw) @font-lock-keyword-face
(structural_kw) @font-lock-keyword-face
(type_kw) @font-lock-keyword-face
(kw_equals) @font-lock-keyword-face
(do) @font-lock-keyword-face
(ability) @font-lock-keyword-face
(where) @font-lock-keyword-face
(test_watch_expression (wordy_id) @font-lock-keyword-face)
(match) @font-lock-keyword-face
(with) @font-lock-keyword-face
(cases) @font-lock-keyword-face)
:language 'unison
:feature 'comment
'((comment) @font-lock-comment-face)
:language 'unison
:feature 'literal
'((nat) @font-lock-number-face
(literal_boolean) @font-lock-constant-face
[(literal_text) (literal_char)] @font-lock-string-face)
:language 'unison
:feature 'operator
'((operator) @font-lock-operator-face
(pipe) @font-lock-operator-face
(arrow_symbol) @font-lock-operator-face
(">") @font-lock-operator-face
(or) @font-lock-operator-face
(and) @font-lock-operator-face
(bang) @font-lock-operator-face
(guard (pipe)) @font-lock-operator-face)
:language 'unison
:feature 'term
'(
(function_application function_name: (path) function_name: (wordy_id)) @font-lock-function-call-face
(function_application function_name: (wordy_id) @font-lock-function-call-face)
(type_signature term_name: (path) @function-lock-variable-name-face)
(type_signature (wordy_id) @font-lock-type-face)
(term_type (delayed (wordy_id)) @font-lock-type-face)
(term_definition
param: (wordy_id) @font-lock-variable-name-face))
:language 'unison
:feature 'type
'((effect (wordy_id)) @font-lock-constant-face
(ability_declaration type_name: (wordy_id) @font-lock-type-face type_arg: (wordy_id) @font-lock-variable-name-face)
(type_constructor (type_name (wordy_id) @font-lock-type-face))
(record_field name: (wordy_id) @font-lock-property-name-face type: (wordy_id) @font-lock-type-face))
:language 'unison
:feature 'namespace
'((path) @font-lock-type-face
(namespace) @font-lock-type-face
:language 'unison
:feature 'extra
`([,@unison-ts--brackets] @font-lock-bracket-face
(type_signature_colon) @font-lock-delimiter-face
(":") @font-lock-delimiter-face)))
;;###autoload
(define-derived-mode unison-ts-mode prog-mode "Unison (TS)"
"Major mode for Unison files using tree-sitter."
:group 'unison-ts
(when (treesit-ready-p 'unison)
(treesit-parser-create 'unison)
(setq-local treesit-font-lock-settings unison-ts--treesit-font-lock-settings)
(setq-local treesit-font-lock-feature-list '((comment term)
(keyword type namespace)
(literal operator)
(extra)))
(treesit-major-mode-setup)))
;;;###autoload
(progn
(add-to-list 'auto-mode-alist '("\\.u\\'" . unison-ts-mode)))
(provide 'unison-ts-mode)
;;; unison-ts-mode.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment