Skip to content

Commit

Permalink
Set up a working build for the tree-sitter grammar
Browse files Browse the repository at this point in the history
The gist:

- Correctly define the extension in `Syntaxes`.
- Set up a build configuration based on the one Panic ships, tweaked to
  work correctly with the `node_modules` path for the grammar.
- Set that up to work with `pnpm build`.

This does not yet get syntax highlighting working, because the grammar
it is pulling in does not supply the relevant queries to make it work,
but the build itself does work correctly, and Nova correctly identifies
the scopes in `.u` files. 🎉
chriskrycho committed Aug 28, 2023
1 parent 9b53ebe commit 5f11305
Showing 7 changed files with 116 additions and 19 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.DS_Store

node_modules
build
*.dylib
65 changes: 65 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Repository
SRC_DIR := node_modules/tree-sitter-unison/src

PARSER_REPO_URL ?= $(shell git -C $(SRC_DIR) remote get-url origin )
# the # in the sed pattern has to be escaped or it will be interpreted as a comment
PARSER_NAME ?= "unison"
UPPER_PARSER_NAME := $(shell echo $(PARSER_NAME) | tr a-z A-Z )

# install directory layout
PREFIX ?= /usr/local
INCLUDEDIR ?= $(PREFIX)/include
LIBDIR ?= $(PREFIX)/lib

# collect sources, and link if necessary
# Some Tree Sitter grammars include .cc files directly in others,
# so we shouldn't just wildcard select them all.
# Only collect known file names.
ifneq ("$(wildcard $(SRC_DIR)/parser.c)", "")
SRC += $(SRC_DIR)/parser.c
endif
ifneq ("$(wildcard $(SRC_DIR)/scanner.c)", "")
SRC += $(SRC_DIR)/scanner.c
endif
ifneq ("$(wildcard $(SRC_DIR)/parser.cc)", "")
CPPSRC += $(SRC_DIR)/parser.cc
endif
ifneq ("$(wildcard $(SRC_DIR)/scanner.cc)", "")
CPPSRC += $(SRC_DIR)/scanner.cc
endif

ifeq (, $(CPPSRC))
ADDITIONALLIBS :=
else
ADDITIONALLIBS := -lc++
endif

SRC += $(CPPSRC)
OBJ := $(addsuffix .o,$(basename $(SRC)))

CFLAGS ?= -O3 -Wall -Wextra -I$(SRC_DIR)
CXXFLAGS ?= -O3 -Wall -Wextra -I$(SRC_DIR)
override CFLAGS += -std=gnu99 -fPIC
override CXXFLAGS += -fPIC

LINKSHARED := $(LINKSHARED)-dynamiclib -Wl,
ifneq ($(ADDITIONALLIBS),)
LINKSHARED := $(LINKSHARED)$(ADDITIONALLIBS),
endif
LINKSHARED := $(LINKSHARED)-install_name,$(LIBDIR)/libtree-sitter-$(PARSER_NAME).dylib,-rpath,@executable_path/../Frameworks

all: libtree-sitter-$(PARSER_NAME).dylib

libtree-sitter-$(PARSER_NAME).dylib: $(OBJ)
$(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@

install: all
install -d '$(DESTDIR)$(LIBDIR)'
install -m755 libtree-sitter-$(PARSER_NAME).dylib '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).dylib
install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter

clean:
rm -f $(OBJ) libtree-sitter-$(PARSER_NAME).dylib
rm -rf build/

.PHONY: all install clean
1 change: 1 addition & 0 deletions Queries/highlights.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(kw_forall) @keyword
35 changes: 16 additions & 19 deletions Syntaxes/unison.xml
Original file line number Diff line number Diff line change
@@ -1,43 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<syntax name="mylang">
<syntax name="unison">
<meta>
<name>unison</name>
<type>script</type>
<preferred-file-extension>mylang</preferred-file-extension>
<name>Unison</name>
<type>compiled</type>
<preferred-file-extension>u</preferred-file-extension>
</meta>

<detectors>
<extension priority="1.0">mylang</extension>
<extension priority="1.0">u</extension>
</detectors>


<!-- TODO: work out what other things should trigger indent/dedent -->
<indentation>
<increase>
<expression></expression>
<expression>=|\{\{|let|if|else|(match .* with)</expression>
</increase>
<decrease>
<expression></expression>
<expression>\}\}</expression>
</decrease>
</indentation>

<comments>
<single>
<expression>//</expression>
<expression>--</expression>
</single>
<multiline>
<starts-with>
<expression></expression>
<expression>{{</expression>
</starts-with>
<ends-with>
<expression></expression>
<expression>}}</expression>
</ends-with>
</multiline>
</comments>

<injection>
<expression>^(mylang)$</expression>
</injection>

<tree-sitter language="mylang">

<tree-sitter>
<highlights path="highlights.scm" />
<folds path="folds.scm" />
<symbols path="symbols.scm" />
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -6,6 +6,9 @@
"typescript": "5.2",
"tree-sitter-unison": "kylegoetz/tree-sitter-unison#1df9e35477b4261abb7cd9d3ab5b2f565fc3fd8a"
},
"scripts": {
"build": "scripts/build.sh"
},
"volta": {
"node": "18.17.1",
"pnpm": "8.6.12"
4 changes: 4 additions & 0 deletions scripts/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/zsh
$(pwd)/scripts/compile_parser.sh $(pwd) /Applications/Nova.app
mv libtree-sitter-unison.dylib ./Syntaxes
cp node_modules/tree-sitter-unison/queries/* Queries
25 changes: 25 additions & 0 deletions scripts/compile_parser.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/zsh
set -euxo pipefail

BASEDIR=$1
APPBUNDLE=$2
FRAMEWORKS_PATH="${APPBUNDLE}/Contents/Frameworks/"
WORKINGDIR=$(pwd)

# - Build both arm64 (Apple Silicon) and x86_64 (Intel)
# - Require a minimum of macOS 11.0
# - Include the /src/ directory for headers (for `tree_sitter/parser.h`)
BUILD_FLAGS="-arch arm64 -arch x86_64 -mmacosx-version-min=11.0 -I${BASEDIR}/src/"

# Build in a temporary `build/` directory.
TMP_BUILD_DIR=$WORKINGDIR/build
mkdir -p $TMP_BUILD_DIR

pushd $BASEDIR

CFLAGS="${BUILD_FLAGS} -O3" \
CXXFLAGS="${BUILD_FLAGS} -O3" \
LDFLAGS="${BUILD_FLAGS} -F${FRAMEWORKS_PATH} -framework SyntaxKit -rpath @loader_path/../Frameworks" \
PREFIX="$TMP_BUILD_DIR" make install

popd

0 comments on commit 5f11305

Please sign in to comment.