2023-05-30 07:29:49 +00:00
---@module 'tsql.token_select'
---@class mod_token_select
2023-05-30 04:39:15 +00:00
local M = { }
2023-05-30 07:29:49 +00:00
---@class mod_ts_query
M.ts_query = { }
---@class TSQuery
---@field query string the passthru for treesitter language parser
M.TSQuery = { }
2023-06-03 22:34:25 +00:00
M.TSQuery . __index = M.TSQuery
---@type Ctor<{query: string}, TSQuery>
function M . TSQuery . new ( q )
local self = q
setmetatable ( self , M.TSQuery )
self.__index = M.TSQuery
return self
end
2023-05-30 07:29:49 +00:00
2023-05-30 04:39:15 +00:00
---@class FileLoc
2023-05-30 07:29:49 +00:00
---@field row_0 number 0-index row location
---@field col_0 number 0-index col location
M.FileLoc = { }
M.FileLoc . __index = M.FileLoc
2023-05-30 04:39:15 +00:00
2023-06-03 22:34:25 +00:00
---@type Ctor<{row_0: number, col_0: number}, FileLoc>
function M . FileLoc . new ( file_loc )
assert ( file_loc ~= nil )
local self = file_loc
setmetatable ( self , M.FileLoc )
self.__index = M.FileLoc
return self
end
2023-05-30 04:39:15 +00:00
---@class QNode
2023-05-30 07:29:49 +00:00
---@field start FileLoc
---@field end_ex_col FileLoc
---@field buf QBuf
2023-05-30 04:39:15 +00:00
M.QNode = { }
2023-05-30 07:29:49 +00:00
M.QNode . __index = M.QNode
2023-05-30 04:39:15 +00:00
2023-06-03 22:34:25 +00:00
---@type Ctor<{start: FileLoc, end_ex_col: FileLoc, buf: QBuf}, QNode>
function M . QNode . new ( qnode )
assert ( qnode ~= nil )
local self = qnode
setmetatable ( self , M.QNode )
self.__index = M.QNode
return self
end
2023-05-30 07:29:49 +00:00
---@param treesitter_query string the passthru for treesitter language
---parser
2023-05-30 04:39:15 +00:00
---@return TSQuery
2023-05-30 07:29:49 +00:00
function M . ts_query . from_scm ( treesitter_query )
2023-06-03 22:34:25 +00:00
return M.TSQuery . new {
2023-05-30 07:29:49 +00:00
query = treesitter_query
}
2023-05-30 04:39:15 +00:00
end
2023-05-30 07:29:49 +00:00
---@param files QBuf[]
---@return QNode[]
function M . TSQuery : find_nodes ( files )
local result = { }
for _ , file in ipairs ( files ) do
2023-06-03 22:34:25 +00:00
if file.lang == nil then
goto continue
end
local sts , parser = pcall ( vim.treesitter . get_parser , file.bufnr , file.filetype )
if not sts then
-- NOTE: no parser for language
goto continue
end
2023-05-30 07:29:49 +00:00
local tree = parser : parse ( ) [ 1 ]
local root = tree : root ( )
---@type Query
2023-06-03 22:34:25 +00:00
local sts , query = pcall ( vim.treesitter . query.parse , file.lang , self.query )
if not sts then
error ( " Error parsing query \" " .. self.query .. " \" on lang " .. file.lang .. " for file " .. file.path )
end
2023-05-30 07:29:49 +00:00
for _ , match , _ in query : iter_matches ( root , file.bufnr , 0 , - 1 ) do
for id , node in pairs ( match ) do
local start_row , start_col , end_row , end_col = node : range ( false )
2023-06-03 22:34:25 +00:00
local start = M.FileLoc . new { row_0 = start_row , col_0 = start_col }
2023-06-01 15:20:36 +00:00
-- CORRECTNESS:
2023-05-30 07:29:49 +00:00
-- :lua local parser = vim.treesitter.get_parser(0, 'lua'); local tree = parser:parse()[1]; local query = vim.treesitter.parse_query('lua', '(identifier) @name'); for id, node in query:iter_captures(tree:root(), 0) do local name = query.captures[id]; if name == 'name' and vim.treesitter.get_node_text(node, 0) == 'TSQuery' then local sr, sc, er, ec = node:range(); print(string.format("TSQuery Start: (%d, %d), End: (%d, %d)", sr, sc, er, ec)); end; end
2023-06-03 22:34:25 +00:00
local end_ex_col = M.FileLoc . new { row_0 = end_row , col_0 = end_col }
local qnode = M.QNode . new { buf = file , start = start , end_ex_col = end_ex_col }
2023-05-30 07:29:49 +00:00
table.insert ( result , qnode )
end
end
2023-06-03 22:34:25 +00:00
:: continue ::
2023-05-30 07:29:49 +00:00
end
return result
end
2023-05-30 04:39:15 +00:00
2023-05-30 07:29:49 +00:00
return M