From 58bbc2ea0b3dfed13471e8cc0447d7598be24276 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Fri, 10 Mar 2023 16:40:27 +0000 Subject: [PATCH] refactor(treesitter): add Range type aliase for Range4|Range6 --- runtime/doc/news.txt | 5 +++++ runtime/doc/treesitter.txt | 3 ++- runtime/lua/vim/treesitter/_range.lua | 14 ++++++++------ runtime/lua/vim/treesitter/languagetree.lua | 15 ++++++--------- runtime/lua/vim/treesitter/query.lua | 12 ++++++++++-- scripts/lua2dox.lua | 2 +- test/functional/treesitter/parser_spec.lua | 14 ++++++++------ 7 files changed, 40 insertions(+), 25 deletions(-) diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 04ae9360a0..7df96874ea 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -50,6 +50,11 @@ The following changes may require adaptations in user config or plugins. • Unsaved changes are now preserved rather than discarded when |channel-stdio| is closed. +• Changes to |vim.treesitter.get_node_text()|: + - It now returns `string`, as opposed to `string|string[]|nil`. + - The `concat` option has been removed as it was not consistently applied. + - Invalid ranges now cause an error instead of returning `nil`. + ============================================================================== NEW FEATURES *news-features* diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index dc577a015e..8a0145127c 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -898,7 +898,8 @@ Query:iter_captures({self}, {node}, {source}, {start}, {stop}) • {self} Return: ~ - (fun(): integer, TSNode, TSMetadata ): capture id, capture node, metadata + (fun(): integer, TSNode, TSMetadata): capture id, capture node, + metadata *Query:iter_matches()* Query:iter_matches({self}, {node}, {source}, {start}, {stop}) diff --git a/runtime/lua/vim/treesitter/_range.lua b/runtime/lua/vim/treesitter/_range.lua index 0017a567ec..f4db5016ac 100644 --- a/runtime/lua/vim/treesitter/_range.lua +++ b/runtime/lua/vim/treesitter/_range.lua @@ -16,6 +16,8 @@ local M = {} ---@field [5] integer end column ---@field [6] integer end bytes +---@alias Range Range4|Range6 + ---@private ---@param a_row integer ---@param a_col integer @@ -85,8 +87,8 @@ function M.validate(r) end ---@private ----@param r1 Range4|Range6 ----@param r2 Range4|Range6 +---@param r1 Range +---@param r2 Range ---@return boolean function M.intercepts(r1, r2) local srow_1, scol_1, erow_1, ecol_1 = M.unpack4(r1) @@ -106,7 +108,7 @@ function M.intercepts(r1, r2) end ---@private ----@param r Range4|Range6 +---@param r Range ---@return integer, integer, integer, integer function M.unpack4(r) local off_1 = #r == 6 and 1 or 0 @@ -121,8 +123,8 @@ function M.unpack6(r) end ---@private ----@param r1 Range4|Range6 ----@param r2 Range4|Range6 +---@param r1 Range +---@param r2 Range ---@return boolean whether r1 contains r2 function M.contains(r1, r2) local srow_1, scol_1, erow_1, ecol_1 = M.unpack4(r1) @@ -143,7 +145,7 @@ end ---@private ---@param source integer|string ----@param range Range4|Range6 +---@param range Range ---@return Range6 function M.add_bytes(source, range) if type(range) == 'table' and #range == 6 then diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua index 0bb0601241..6869fae92c 100644 --- a/runtime/lua/vim/treesitter/languagetree.lua +++ b/runtime/lua/vim/treesitter/languagetree.lua @@ -484,7 +484,6 @@ function LanguageTree:included_regions() end ---@private ---- TODO(lewis6991): cleanup of the node_range interface ---@param node TSNode ---@param source string|integer ---@param metadata TSMetadata @@ -530,7 +529,7 @@ end ---@param pattern integer ---@param lang string ---@param combined boolean ----@param ranges Range4[] +---@param ranges Range6[] local function add_injection(t, tree_index, pattern, lang, combined, ranges) assert(type(lang) == 'string') @@ -558,13 +557,11 @@ end --- https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection ---@param match table ---@param metadata TSMetadata ----@return string, boolean, Range4[] +---@return string?, boolean, Range6[] function LanguageTree:_get_injection(match, metadata) - local ranges = {} ---@type Range4[] + local ranges = {} ---@type Range6[] local combined = metadata['injection.combined'] ~= nil - local lang = metadata['injection.language'] - assert(type(lang) == 'string') - + local lang = metadata['injection.language'] --[[@as string?]] local include_children = metadata['injection.include-children'] ~= nil for id, node in pairs(match) do @@ -584,7 +581,7 @@ end ---@private ---@param match table ---@param metadata TSMetadata ----@return string, boolean, Range4[] +---@return string, boolean, Range6[] function LanguageTree:_get_injection_deprecated(match, metadata) local lang = nil ---@type string local ranges = {} ---@type Range6[] @@ -910,7 +907,7 @@ end ---@private ---@param tree TSTree ----@param range Range4 +---@param range Range ---@return boolean local function tree_contains(tree, range) return Range.contains({ tree:root():range() }, range) diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 70af4f7bce..f4e038b2d8 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -59,10 +59,18 @@ end ---@private ---@param buf integer ----@param range Range6 +---@param range Range ---@returns string local function buf_range_get_text(buf, range) local start_row, start_col, end_row, end_col = Range.unpack4(range) + if end_col == 0 then + if start_row == end_row then + start_col = -1 + start_row = start_row - 1 + end + end_col = -1 + end_row = end_row - 1 + end local lines = a.nvim_buf_get_text(buf, start_row, start_col, end_row, end_col, {}) return table.concat(lines, '\n') end @@ -396,7 +404,7 @@ local predicate_handlers = { predicate_handlers['vim-match?'] = predicate_handlers['match?'] ---@class TSMetadata ----@field range Range4|Range6 +---@field range Range ---@field [integer] TSMetadata ---@field [string] integer|string diff --git a/scripts/lua2dox.lua b/scripts/lua2dox.lua index b99cd955f4..de9f2926f2 100644 --- a/scripts/lua2dox.lua +++ b/scripts/lua2dox.lua @@ -302,7 +302,7 @@ local types = { 'integer', 'number', 'string', 'table', 'list', 'boolean', 'func local tagged_types = { 'TSNode', 'LanguageTree' } -- Document these as 'table' -local alias_types = { 'Range4', 'Range6' } +local alias_types = { 'Range', 'Range4', 'Range6', 'TSMetadata' } -- Processes the file and writes filtered output to stdout. function TLua2DoX_filter.filter(this, AppStamp, Filename) diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index 0f00fcfe0d..c6ca65f9a1 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -196,7 +196,7 @@ void ui_refresh(void) local manyruns = q(100) -- First run should be at least 400x slower than an 100 subsequent runs. - local factor = is_os('win') and 300 or 400 + local factor = is_os('win') and 200 or 400 assert(factor * manyruns < firstrun, ('firstrun: %f ms, manyruns: %f ms'):format(firstrun / 1e6, manyruns / 1e6)) end) @@ -277,13 +277,13 @@ void ui_refresh(void) eq('void', res2) end) - it('support getting text where start of node is past EOF', function() + it('support getting text where start of node is one past EOF', function() local text = [[ def run a = <<~E end]] insert(text) - local result = exec_lua([[ + eq('', exec_lua[[ local fake_node = {} function fake_node:start() return 3, 0, 23 @@ -291,12 +291,14 @@ end]] function fake_node:end_() return 3, 0, 23 end - function fake_node:range() + function fake_node:range(bytes) + if bytes then + return 3, 0, 23, 3, 0, 23 + end return 3, 0, 3, 0 end - return vim.treesitter.get_node_text(fake_node, 0) == nil + return vim.treesitter.get_node_text(fake_node, 0) ]]) - eq(true, result) end) it('support getting empty text if node range is zero width', function()