diff --git a/lua/nvim-treesitter-playground.lua b/lua/nvim-treesitter-playground.lua index d4b3d3e..89eaaa0 100644 --- a/lua/nvim-treesitter-playground.lua +++ b/lua/nvim-treesitter-playground.lua @@ -22,7 +22,7 @@ function M.init() }, query_linter = { module_path = "nvim-treesitter-playground.query_linter", - use_virtual_text = true, + use_diagnostics = true, lint_events = { "BufWrite", "CursorHold" }, is_supported = function(lang) return lang == "query" and parsers.has_parser "query" diff --git a/lua/nvim-treesitter-playground/query_linter.lua b/lua/nvim-treesitter-playground/query_linter.lua index f1e2136..cf6dab5 100644 --- a/lua/nvim-treesitter-playground/query_linter.lua +++ b/lua/nvim-treesitter-playground/query_linter.lua @@ -1,31 +1,39 @@ local api = vim.api local queries = require "nvim-treesitter.query" local parsers = require "nvim-treesitter.parsers" -local ts_utils = require "nvim-treesitter.ts_utils" local utils = require "nvim-treesitter.utils" local configs = require "nvim-treesitter.configs" -local hl_namespace = api.nvim_create_namespace "nvim-playground-lints" -local ERROR_HL = "TSQueryLinterError" +local namespace = api.nvim_create_namespace "nvim-playground-lints" local MAGIC_NODE_NAMES = { "_", "ERROR" } local playground_module = require "nvim-treesitter-playground.internal" local M = {} M.lints = {} -M.use_virtual_text = true +M.use_diagnostics = true M.lint_events = { "BufWrite", "CursorHold" } -local function lint_node(node, buf, error_type, complete_message) - if error_type ~= "Invalid Query" then - ts_utils.highlight_node(node, buf, hl_namespace, ERROR_HL) +local function show_lints(buf, lints) + if M.use_diagnostics then + local diagnostics = vim.tbl_map(function(lint) + return { + lnum = lint.range[1], + end_lnum = lint.range[3], + col = lint.range[2], + end_col = lint.range[4], + severity = vim.diagnostic.ERROR, + message = lint.message, + } + end, lints) + vim.diagnostic.set(namespace, buf, diagnostics) end +end + +local function add_lint_for_node(node, buf, error_type, complete_message) local node_text = vim.treesitter.query.get_node_text(node, buf):gsub("\n", " ") local error_text = complete_message or error_type .. ": " .. node_text local error_range = { node:range() } - if M.use_virtual_text then - api.nvim_buf_set_virtual_text(buf, hl_namespace, error_range[1], { { error_text, ERROR_HL } }, {}) - end table.insert(M.lints[buf], { type = error_type, range = error_range, message = error_text, node_text = node_text }) end @@ -80,7 +88,7 @@ function M.lint(query_buf) local error_node = utils.get_at_path(m, "error.node") if error_node then - lint_node(error_node, query_buf, "Syntax Error") + add_lint_for_node(error_node, query_buf, "Syntax Error") end local toplevel_node = utils.get_at_path(m, "toplevel-query.node") @@ -89,7 +97,7 @@ function M.lint(query_buf) local err ok, err = pcall(vim.treesitter.parse_query, query_lang, query_text) if not ok then - lint_node(toplevel_node, query_buf, "Invalid Query", err) + add_lint_for_node(toplevel_node, query_buf, "Invalid Query", err) end end @@ -112,7 +120,7 @@ function M.lint(query_buf) end, parser_info.symbols) if not found then - lint_node(node, query_buf, "Invalid Node Type") + add_lint_for_node(node, query_buf, "Invalid Node Type") end end @@ -122,23 +130,25 @@ function M.lint(query_buf) local field_name = vim.treesitter.query.get_node_text(field_node, query_buf) local found = vim.tbl_contains(parser_info.fields, field_name) if not found then - lint_node(field_node, query_buf, "Invalid Field") + add_lint_for_node(field_node, query_buf, "Invalid Field") end end end end + + show_lints(query_buf, M.lints[query_buf]) return M.lints[query_buf] end function M.clear_virtual_text(buf) - api.nvim_buf_clear_namespace(buf, hl_namespace, 0, -1) + vim.diagnostic.reset(namespace, buf) end function M.attach(buf, _) M.lints[buf] = {} local config = configs.get_module "query_linter" - M.use_virtual_text = config.use_virtual_text + M.use_diagnostics = config.use_diagnostics M.lint_events = config.lint_events vim.api.nvim_create_autocmd(M.lint_events, {