aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter/query.lua
diff options
context:
space:
mode:
authorThomas Vigouroux <tomvig38@gmail.com>2020-08-10 18:25:52 +0200
committerThomas Vigouroux <tomvig38@gmail.com>2020-08-13 20:30:15 +0200
commitd7b12e58dfc7303dbc06381a9bedd5c3539d5413 (patch)
treeac8754a46a21b87305777126d9f9cd52caaad53b /runtime/lua/vim/treesitter/query.lua
parent58e37d7df8ab3afc4d77e6ff1248d26a2559399e (diff)
downloadrneovim-d7b12e58dfc7303dbc06381a9bedd5c3539d5413.tar.gz
rneovim-d7b12e58dfc7303dbc06381a9bedd5c3539d5413.tar.bz2
rneovim-d7b12e58dfc7303dbc06381a9bedd5c3539d5413.zip
treesitter: add and test vim-match? predicate
Diffstat (limited to 'runtime/lua/vim/treesitter/query.lua')
-rw-r--r--runtime/lua/vim/treesitter/query.lua46
1 files changed, 40 insertions, 6 deletions
diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua
index b30bf5fb6b..b43c28b0ab 100644
--- a/runtime/lua/vim/treesitter/query.lua
+++ b/runtime/lua/vim/treesitter/query.lua
@@ -24,7 +24,11 @@ function M.parse_query(lang, query)
end
-- TODO(vigoux): support multiline nodes too
-local function get_node_text(node, bufnr)
+
+--- Gets the text corresponding to a given node
+-- @param node the node
+-- @param bufnr the buffer from which the node in extracted.
+function M.get_node_text(node, bufnr)
local start_row, start_col, end_row, end_col = node:range()
if start_row ~= end_row then
return nil
@@ -34,11 +38,11 @@ local function get_node_text(node, bufnr)
end
-- Predicate handler receive the following arguments
--- (match, pattern, bufnr, regexes, index, predicate)
+-- (match, pattern, bufnr, predicate)
local predicate_handlers = {
["eq?"] = function(match, _, bufnr, predicate)
local node = match[predicate[2]]
- local node_text = get_node_text(node, bufnr)
+ local node_text = M.get_node_text(node, bufnr)
local str
if type(predicate[3]) == "string" then
@@ -46,7 +50,7 @@ local predicate_handlers = {
str = predicate[3]
else
-- (#eq? @aa @bb)
- str = get_node_text(match[predicate[3]], bufnr)
+ str = M.get_node_text(match[predicate[3]], bufnr)
end
if node_text ~= str or str == nil then
@@ -63,12 +67,42 @@ local predicate_handlers = {
return false
end
- return string.find(get_node_text(node, bufnr), regex)
+ return string.find(M.get_node_text(node, bufnr), regex)
end,
+ ["vim-match?"] = (function()
+
+ local magic_prefixes = {['\\v']=true, ['\\m']=true, ['\\M']=true, ['\\V']=true}
+ local function check_magic(str)
+ if string.len(str) < 2 or magic_prefixes[string.sub(str,1,2)] then
+ return str
+ end
+ return '\\v'..str
+ end
+
+ local compiled_vim_regexes = setmetatable({}, {
+ __index = function(t, pattern)
+ local res = vim.regex(check_magic(pattern))
+ rawset(t, pattern, res)
+ return res
+ end
+ })
+
+ return function(match, _, bufnr, pred)
+ local node = match[pred[2]]
+ local start_row, start_col, end_row, end_col = node:range()
+ if start_row ~= end_row then
+ return false
+ end
+
+ local regex = compiled_vim_regexes[pred[3]]
+ return regex:match_line(bufnr, start_row, start_col, end_col)
+ end
+ end)(),
+
["contains?"] = function(match, _, bufnr, predicate)
local node = match[predicate[2]]
- local node_text = get_node_text(node, bufnr)
+ local node_text = M.get_node_text(node, bufnr)
for i=3,#predicate do
if string.find(node_text, predicate[i], 1, true) then