tree-sitter-jac works with Neovim's tree-sitter integration
(nvim-treesitter). Until the parser lands in the nvim-treesitter community
registry, register it manually as shown below.
This repo doubles as a Neovim plugin: it ships ftdetect/jac.lua (filetype
detection for *.jac and the *.impl.jac / *.cl.jac / *.sv.jac /
*.na.jac / *.test.jac variants) and ftplugin/jac.lua (commentstring,
indent). Install it like any plugin to get those for free, e.g. with lazy.nvim:
{ "jaseci-labs/tree-sitter-jac" }If you are not installing it as a plugin, add filetype detection yourself:
vim.filetype.add({ extension = { jac = "jac" } })The snippet below targets nvim-treesitter's master branch. On the rewritten
main branch the registration API differs; follow its
"add a parser"
docs, keeping the same url and both files (src/parser.c,
src/scanner.c).
local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
parser_config.jac = {
install_info = {
url = "https://github.com/jaseci-labs/tree-sitter-jac",
-- BOTH files are required: the grammar uses an external scanner
-- (src/scanner.c) for f-strings, JSX text, and `::py::` blocks.
files = { "src/parser.c", "src/scanner.c" },
branch = "main",
generate_requires_npm = false, -- src/parser.c is committed
},
filetype = "jac",
}Then :TSInstall jac.
For local development against a checkout, point the url at the path:
parser_config.jac.install_info.url = "/path/to/tree-sitter-jac":TSInstall compiles the parser but does not ship queries. They live at
queries/jac/ here, which is exactly where Neovim looks on the runtimepath —
so installing this repo as a plugin (above) provides them automatically. If
you are not using it as a plugin, copy queries/jac/*.scm to
~/.config/nvim/queries/jac/. Provided queries:
highlights.scm— syntax highlighting (incl. f-string interpolations & JSX)locals.scm— scopes & definitionsfolds.scm—foldmethod=exprfoldinginjections.scm— embedded languages (inline Python, comments)indents.scm— indentationtextobjects.scm—nvim-treesitter-textobjects(functions, classes, …)
::py:: … ::py::blocks (and code-in-comments) are highlighted by injecting another language, so install that parser for it to render — e.g.:TSInstall python. Thetextobjects.scmmotions additionally require thenvim-treesitter-textobjectsplugin.
-- folding
vim.opt_local.foldmethod = "expr"
vim.opt_local.foldexpr = "v:lua.vim.treesitter.foldexpr()"
-- indentation: enable in your nvim-treesitter setup
require("nvim-treesitter.configs").setup({ indent = { enable = true } })Highlighting (this grammar) and semantic features (completion, hover, diagnostics, go-to-definition) are independent. For the latter, point Neovim's built-in LSP at the Jac language server, which ships with jaclang:
vim.api.nvim_create_autocmd("FileType", {
pattern = "jac",
callback = function(args)
vim.lsp.start({
name = "jac",
cmd = { "jac", "lsp" },
root_dir = vim.fs.root(args.buf, { "jac.toml", ".git" }),
})
end,
})Once jac is added to nvim-lspconfig, this becomes
require("lspconfig").jac.setup({}). The upstream tracking issue is
jaseci-labs/jac#6784.