fix: load compiled parser.so via vim.treesitter.language.add
nvim-treesitter's :TSInstall reloads the parsers module from source
(package.loaded['nvim-treesitter.parsers'] = nil), which wipes runtime
config modifications. The old get_parser_configs() approach no longer
works for registering custom parsers with :TSInstall.
New approach:
- The mason build script now compiles parser.c into parser.so during
:MasonInstall tia-lsp (requires cc/gcc)
- The plugin's setup_syntax finds parser.so via:
1. opts.ts_parser_path (explicit override)
2. Mason package dir (resolved from exepath('tia-lsp'))
3. ~/dev/tia-lsp/parser.so (local dev fallback)
- Loads it with vim.treesitter.language.add('scl', { path = parser.so })
- Starts highlighting via vim.treesitter.start(bufnr, 'scl') in the
FileType autocmd
- Falls back to notifying the user if no parser.so is found
- Still registers with nvim-treesitter's parsers table as best-effort
for :TSInstall support (won't survive reload, but works in-session)
This commit is contained in:
+76
-5
@@ -53,6 +53,9 @@ function M.setup(opts)
|
|||||||
pattern = "scl",
|
pattern = "scl",
|
||||||
callback = function(args)
|
callback = function(args)
|
||||||
start_lsp(args.buf)
|
start_lsp(args.buf)
|
||||||
|
M.notify_parser_install_if_needed(args.buf)
|
||||||
|
-- Start tree-sitter highlighting if the parser is registered
|
||||||
|
pcall(vim.treesitter.start, args.buf, "scl")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -65,6 +68,8 @@ function M.setup(opts)
|
|||||||
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
||||||
if vim.bo[bufnr].filetype == "scl" and vim.api.nvim_buf_is_loaded(bufnr) then
|
if vim.bo[bufnr].filetype == "scl" and vim.api.nvim_buf_is_loaded(bufnr) then
|
||||||
start_lsp(bufnr)
|
start_lsp(bufnr)
|
||||||
|
M.notify_parser_install_if_needed(bufnr)
|
||||||
|
pcall(vim.treesitter.start, bufnr, "scl")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -78,14 +83,80 @@ function M.setup(opts)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Find a compiled tree-sitter parser (.so) for SCL.
|
||||||
|
-- Looks in: opts.ts_parser_path, mason package dir, ~/dev/tia-lsp.
|
||||||
|
-- Returns the path to parser.so, or nil if not found.
|
||||||
|
function M.find_parser_so(opts)
|
||||||
|
-- 1. Explicit path from opts
|
||||||
|
if opts.ts_parser_path and vim.fn.filereadable(opts.ts_parser_path) == 1 then
|
||||||
|
return opts.ts_parser_path
|
||||||
|
end
|
||||||
|
-- 2. Mason install: resolve exepath("tia-lsp") -> real bin -> package dir
|
||||||
|
local tia_bin = vim.fn.exepath("tia-lsp")
|
||||||
|
if tia_bin ~= "" then
|
||||||
|
local real_bin = vim.fn.resolve(vim.fn.fnamemodify(tia_bin, ":p"))
|
||||||
|
local pkg_dir = vim.fn.fnamemodify(real_bin, ":h:h")
|
||||||
|
local so = pkg_dir .. "/parser.so"
|
||||||
|
if vim.fn.filereadable(so) == 1 then
|
||||||
|
return so
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- 3. Local dev path
|
||||||
|
local dev_so = vim.fn.expand("~/dev/tia-lsp/parser.so")
|
||||||
|
if vim.fn.filereadable(dev_so) == 1 then
|
||||||
|
return dev_so
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Notify the user once per session if the tree-sitter parser isn't available.
|
||||||
|
local parser_notified = false
|
||||||
|
|
||||||
|
function M.notify_parser_install_if_needed(bufnr)
|
||||||
|
if parser_notified then return end
|
||||||
|
if vim.bo[bufnr].filetype ~= "scl" then return end
|
||||||
|
local ok = pcall(vim.treesitter.get_parser, bufnr, "scl")
|
||||||
|
if ok then return end
|
||||||
|
parser_notified = true
|
||||||
|
vim.schedule(function()
|
||||||
|
local msg = "SCL: Tree-sitter parser not found. "
|
||||||
|
if vim.fn.exepath("tia-lsp") ~= "" then
|
||||||
|
msg = msg .. "Run :MasonInstall tia-lsp to install it."
|
||||||
|
else
|
||||||
|
msg = msg .. "Install tia-lsp via mason or compile parser.so manually."
|
||||||
|
end
|
||||||
|
vim.notify(msg, vim.log.levels.INFO)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
function M.setup_syntax(opts)
|
function M.setup_syntax(opts)
|
||||||
local has_ts, ts = pcall(require, "nvim-treesitter.parsers")
|
-- Load the compiled tree-sitter parser (.so) via Neovim's built-in API.
|
||||||
if has_ts and ts.get_parser_configs then
|
-- This bypasses nvim-treesitter's install system, which reloads its
|
||||||
local ok, parser_config = pcall(ts.get_parser_configs)
|
-- parsers module from source on :TSInstall and wipes runtime config.
|
||||||
if ok and parser_config then
|
local parser_so = M.find_parser_so(opts)
|
||||||
|
if parser_so then
|
||||||
|
local ok, err = pcall(vim.treesitter.language.add, "scl", { path = parser_so })
|
||||||
|
if not ok then
|
||||||
|
vim.notify(
|
||||||
|
"SCL: Failed to load tree-sitter parser from " .. parser_so .. ": " .. tostring(err),
|
||||||
|
vim.log.levels.WARN
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Also register with nvim-treesitter (best-effort, for :TSInstall support
|
||||||
|
-- in sessions where the user wants to install from source).
|
||||||
|
local has_ts, parsers = pcall(require, "nvim-treesitter.parsers")
|
||||||
|
if has_ts and type(parsers) == "table" then
|
||||||
|
local parser_config
|
||||||
|
if type(parsers.get_parser_configs) == "function" then
|
||||||
|
parser_config = parsers.get_parser_configs()
|
||||||
|
else
|
||||||
|
parser_config = parsers
|
||||||
|
end
|
||||||
|
if type(parser_config) == "table" then
|
||||||
parser_config.scl = {
|
parser_config.scl = {
|
||||||
install_info = {
|
install_info = {
|
||||||
-- Override via setup({ ts_parser_url = "https://your-gitea/tia-lsp.git" }).
|
|
||||||
url = opts.ts_parser_url
|
url = opts.ts_parser_url
|
||||||
or "https://gitea.l-tech.rs/lazar/tia-lsp.git",
|
or "https://gitea.l-tech.rs/lazar/tia-lsp.git",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
|
|||||||
Reference in New Issue
Block a user