From 1445e0c01e38ad0e06b5ff0e895d20765838a162 Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 17 Feb 2023 14:10:24 +0200 Subject: [PATCH 1/4] feat(query_linter): add new option use_diagnostics Adds a new option (enabled by default) for the query_linter that uses the builtin `vim.diagnostic` "framework" to display any errors found. Disable `use_virtual_text` by default. --- lua/nvim-treesitter-playground.lua | 3 ++- .../query_linter.lua | 27 ++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lua/nvim-treesitter-playground.lua b/lua/nvim-treesitter-playground.lua index d4b3d3e..8b8b294 100644 --- a/lua/nvim-treesitter-playground.lua +++ b/lua/nvim-treesitter-playground.lua @@ -22,7 +22,8 @@ function M.init() }, query_linter = { module_path = "nvim-treesitter-playground.query_linter", - use_virtual_text = true, + use_diagnostics = true, + use_virtual_text = false, 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..a8dcc33 100644 --- a/lua/nvim-treesitter-playground/query_linter.lua +++ b/lua/nvim-treesitter-playground/query_linter.lua @@ -5,7 +5,7 @@ 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 namespace = api.nvim_create_namespace "nvim-playground-lints" local ERROR_HL = "TSQueryLinterError" local MAGIC_NODE_NAMES = { "_", "ERROR" } local playground_module = require "nvim-treesitter-playground.internal" @@ -13,18 +13,19 @@ local playground_module = require "nvim-treesitter-playground.internal" local M = {} M.lints = {} -M.use_virtual_text = true +M.use_diagnostics = true +M.use_virtual_text = false 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) + if not M.use_diagnostics and error_type ~= "Invalid Query" then + ts_utils.highlight_node(node, buf, namespace, ERROR_HL) end 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 } }, {}) + api.nvim_buf_set_virtual_text(buf, 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 @@ -127,17 +128,31 @@ function M.lint(query_buf) end end end + + 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, M.lints[query_buf]) + vim.diagnostic.set(namespace, query_buf, diagnostics) + end 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) + api.nvim_buf_clear_namespace(buf, namespace, 0, -1) end function M.attach(buf, _) M.lints[buf] = {} local config = configs.get_module "query_linter" + M.use_diagnostics = config.use_diagnostics M.use_virtual_text = config.use_virtual_text M.lint_events = config.lint_events From d1fb4bf0fd2cafa268cc23db28dee67e6892edb6 Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 17 Feb 2023 14:20:53 +0200 Subject: [PATCH 2/4] refactor(query_linter): do all the decorations in one place This also replaces the apparently deprecated `nvim_buf_set_virtual_text` with `nvim_buf_set_extmark` --- .../query_linter.lua | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/lua/nvim-treesitter-playground/query_linter.lua b/lua/nvim-treesitter-playground/query_linter.lua index a8dcc33..2600b14 100644 --- a/lua/nvim-treesitter-playground/query_linter.lua +++ b/lua/nvim-treesitter-playground/query_linter.lua @@ -17,16 +17,38 @@ M.use_diagnostics = true M.use_virtual_text = false M.lint_events = { "BufWrite", "CursorHold" } -local function lint_node(node, buf, error_type, complete_message) - if not M.use_diagnostics and error_type ~= "Invalid Query" then - ts_utils.highlight_node(node, buf, 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) + else + for _, lint in ipairs(lints) do + if lint.type ~= "Invalid Query" then + ts_utils.highlight_range(lint.range, buf, namespace, ERROR_HL) + end + + if M.use_virtual_text then + api.nvim_buf_set_extmark(buf, namespace, lint.range[1], lint.range[2], { + end_row = lint.range[3], + end_col = lint.range[4], + virt_text = { lint.message, ERROR_HL } + }) + end + end 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, 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 @@ -81,7 +103,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") @@ -90,7 +112,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 @@ -113,7 +135,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 @@ -123,23 +145,13 @@ 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 - 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, M.lints[query_buf]) - vim.diagnostic.set(namespace, query_buf, diagnostics) - end + show_lints(query_buf, M.lints[query_buf]) return M.lints[query_buf] end From a3757e6210174b4ddf81eaf8e66fcab9d224aa73 Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 17 Feb 2023 14:25:50 +0200 Subject: [PATCH 3/4] feat(query_linter)!: remove use_virtual_text I believe `use_diagnostics` is superior in every way --- lua/nvim-treesitter-playground.lua | 1 - .../query_linter.lua | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/lua/nvim-treesitter-playground.lua b/lua/nvim-treesitter-playground.lua index 8b8b294..89eaaa0 100644 --- a/lua/nvim-treesitter-playground.lua +++ b/lua/nvim-treesitter-playground.lua @@ -23,7 +23,6 @@ function M.init() query_linter = { module_path = "nvim-treesitter-playground.query_linter", use_diagnostics = true, - use_virtual_text = false, 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 2600b14..2d78e6d 100644 --- a/lua/nvim-treesitter-playground/query_linter.lua +++ b/lua/nvim-treesitter-playground/query_linter.lua @@ -1,12 +1,10 @@ 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 namespace = api.nvim_create_namespace "nvim-playground-lints" -local ERROR_HL = "TSQueryLinterError" local MAGIC_NODE_NAMES = { "_", "ERROR" } local playground_module = require "nvim-treesitter-playground.internal" @@ -14,7 +12,6 @@ local M = {} M.lints = {} M.use_diagnostics = true -M.use_virtual_text = false M.lint_events = { "BufWrite", "CursorHold" } local function show_lints(buf, lints) @@ -28,20 +25,6 @@ local function show_lints(buf, lints) } end, lints) vim.diagnostic.set(namespace, buf, diagnostics) - else - for _, lint in ipairs(lints) do - if lint.type ~= "Invalid Query" then - ts_utils.highlight_range(lint.range, buf, namespace, ERROR_HL) - end - - if M.use_virtual_text then - api.nvim_buf_set_extmark(buf, namespace, lint.range[1], lint.range[2], { - end_row = lint.range[3], - end_col = lint.range[4], - virt_text = { lint.message, ERROR_HL } - }) - end - end end end @@ -157,7 +140,6 @@ end function M.clear_virtual_text(buf) vim.diagnostic.reset(namespace, buf) - api.nvim_buf_clear_namespace(buf, namespace, 0, -1) end function M.attach(buf, _) @@ -165,7 +147,6 @@ function M.attach(buf, _) local config = configs.get_module "query_linter" M.use_diagnostics = config.use_diagnostics - M.use_virtual_text = config.use_virtual_text M.lint_events = config.lint_events vim.api.nvim_create_autocmd(M.lint_events, { From f2ae937170ff727679ab59a9e0e84ae9549e50f6 Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 17 Feb 2023 15:16:32 +0200 Subject: [PATCH 4/4] fix: stylua --- lua/nvim-treesitter-playground/query_linter.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lua/nvim-treesitter-playground/query_linter.lua b/lua/nvim-treesitter-playground/query_linter.lua index 2d78e6d..cf6dab5 100644 --- a/lua/nvim-treesitter-playground/query_linter.lua +++ b/lua/nvim-treesitter-playground/query_linter.lua @@ -18,10 +18,12 @@ 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], + 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 + message = lint.message, } end, lints) vim.diagnostic.set(namespace, buf, diagnostics)