mirror of
https://github.com/neovim/neovim.git
synced 2026-01-25 22:51:14 +10:00
Merge pull request #12826 from vigoux/ts-lua-match
treesitter: use lua-match? instead of match?
This commit is contained in:
@@ -756,14 +756,15 @@ Here is a list of built-in predicates :
|
||||
((node1) @left (node2) @right (#eq? @left @right))
|
||||
<
|
||||
`match?` *ts-predicate-match?*
|
||||
This will match if the provived lua regex matches the text
|
||||
`vim-match?` *ts-predicate-vim-match?*
|
||||
This will match if the provived vim regex matches the text
|
||||
corresponding to a node : >
|
||||
((idenfitier) @constant (#match? @constant "^[A-Z_]+$"))
|
||||
< Note: the `^` and `$` anchors will respectively match the
|
||||
start and end of the node's text.
|
||||
|
||||
`vim-match?` *ts-predicate-vim-match?*
|
||||
This will match the same way than |match?| but using vim
|
||||
`lua-match?` *ts-predicate-lua-match?*
|
||||
This will match the same way than |match?| but using lua
|
||||
regexes.
|
||||
|
||||
`contains?` *ts-predicate-contains?*
|
||||
|
||||
@@ -60,7 +60,7 @@ local predicate_handlers = {
|
||||
return true
|
||||
end,
|
||||
|
||||
["match?"] = function(match, _, bufnr, predicate)
|
||||
["lua-match?"] = function(match, _, bufnr, predicate)
|
||||
local node = match[predicate[2]]
|
||||
local regex = predicate[3]
|
||||
local start_row, _, end_row, _ = node:range()
|
||||
@@ -71,7 +71,7 @@ local predicate_handlers = {
|
||||
return string.find(M.get_node_text(node, bufnr), regex)
|
||||
end,
|
||||
|
||||
["vim-match?"] = (function()
|
||||
["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
|
||||
@@ -114,6 +114,9 @@ local predicate_handlers = {
|
||||
end
|
||||
}
|
||||
|
||||
-- As we provide lua-match? also expose vim-match?
|
||||
predicate_handlers["vim-match?"] = predicate_handlers["match?"]
|
||||
|
||||
--- Adds a new predicates to be used in queries
|
||||
--
|
||||
-- @param name the name of the predicate, without leading #
|
||||
@@ -132,25 +135,38 @@ function M.list_predicates()
|
||||
return vim.tbl_keys(predicate_handlers)
|
||||
end
|
||||
|
||||
local function xor(x, y)
|
||||
return (x or y) and not (x and y)
|
||||
end
|
||||
|
||||
function Query:match_preds(match, pattern, bufnr)
|
||||
local preds = self.info.patterns[pattern]
|
||||
if not preds then
|
||||
return true
|
||||
end
|
||||
for _, pred in pairs(preds) do
|
||||
|
||||
for _, pred in pairs(preds or {}) do
|
||||
-- Here we only want to return if a predicate DOES NOT match, and
|
||||
-- continue on the other case. This way unknown predicates will not be considered,
|
||||
-- which allows some testing and easier user extensibility (#12173).
|
||||
-- Also, tree-sitter strips the leading # from predicates for us.
|
||||
local pred_name
|
||||
local is_not
|
||||
if string.sub(pred[1], 1, 4) == "not-" then
|
||||
local pred_name = string.sub(pred[1], 5)
|
||||
if predicate_handlers[pred_name] and
|
||||
predicate_handlers[pred_name](match, pattern, bufnr, pred) then
|
||||
return false
|
||||
end
|
||||
pred_name = string.sub(pred[1], 5)
|
||||
is_not = true
|
||||
else
|
||||
pred_name = pred[1]
|
||||
is_not = false
|
||||
end
|
||||
|
||||
elseif predicate_handlers[pred[1]] and
|
||||
not predicate_handlers[pred[1]](match, pattern, bufnr, pred) then
|
||||
local handler = predicate_handlers[pred_name]
|
||||
|
||||
if not handler then
|
||||
a.nvim_err_writeln(string.format("No handler for %s", pred[1]))
|
||||
return false
|
||||
end
|
||||
|
||||
local pred_matches = handler(match, pattern, bufnr, pred)
|
||||
|
||||
if not xor(is_not, pred_matches) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -250,13 +250,13 @@ void ui_refresh(void)
|
||||
}, res)
|
||||
end)
|
||||
|
||||
it('allow loading query with escaped quotes and capture them with `match?` and `vim-match?`', function()
|
||||
it('allow loading query with escaped quotes and capture them with `lua-match?` and `vim-match?`', function()
|
||||
if not check_parser() then return end
|
||||
|
||||
insert('char* astring = "Hello World!";')
|
||||
|
||||
local res = exec_lua([[
|
||||
cquery = vim.treesitter.parse_query("c", '((_) @quote (vim-match? @quote "^\\"$")) ((_) @quote (match? @quote "^\\"$"))')
|
||||
cquery = vim.treesitter.parse_query("c", '((_) @quote (vim-match? @quote "^\\"$")) ((_) @quote (lua-match? @quote "^\\"$"))')
|
||||
parser = vim.treesitter.get_parser(0, "c")
|
||||
tree = parser:parse()
|
||||
res = {}
|
||||
@@ -323,7 +323,7 @@ void ui_refresh(void)
|
||||
return list
|
||||
]]
|
||||
|
||||
eq({ 'contains?', 'eq?', 'is-main?', 'match?', 'vim-match?' }, res_list)
|
||||
eq({ 'contains?', 'eq?', 'is-main?', 'lua-match?', 'match?', 'vim-match?' }, res_list)
|
||||
end)
|
||||
|
||||
it('supports highlighting', function()
|
||||
@@ -373,7 +373,7 @@ static int nlua_schedule(lua_State *const lstate)
|
||||
|
||||
; Use lua regexes
|
||||
((identifier) @Identifier (#contains? @Identifier "lua_"))
|
||||
((identifier) @Constant (#match? @Constant "^[A-Z_]+$"))
|
||||
((identifier) @Constant (#lua-match? @Constant "^[A-Z_]+$"))
|
||||
((identifier) @Normal (#vim-match? @Constant "^lstate$"))
|
||||
|
||||
((binary_expression left: (identifier) @WarningMsg.left right: (identifier) @WarningMsg.right) (#eq? @WarningMsg.left @WarningMsg.right))
|
||||
|
||||
Reference in New Issue
Block a user