commit 7ad205adb43ec98ace41e340cfac3ccafb0f360c
parent 843b3e15442000112ac494b11667c358e9831ba1
Author: Thomas Vigouroux <me@vigoux.eu>
Date: Mon, 25 Mar 2024 16:17:45 +0100
fix(latex): correctly handle math textobjects
Diffstat:
2 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/after/ftplugin/tex.lua b/after/ftplugin/tex.lua
@@ -120,26 +120,55 @@ local function well_defined(root, capture_to_id, matches)
))
end
+local function resolve_capture(node, idx)
+ if type(node) == 'table' then
+ return node[idx or #node]
+ else
+ return node
+ end
+end
+
local function extract_range(root, match, capture_to_id)
local ret = {}
- if match[capture_to_id[root]] then
- local start_row, start_col, end_row, end_col = match[capture_to_id[root]]:range()
- ret.from = { line = start_row, col = start_col }
- ret.to = { line = end_row, col = end_col }
- else
- local start_row, start_col = match[capture_to_id[root .. ".from"]]:start()
- ret.from = { line = start_row, col = start_col }
- local end_row, end_col = match[capture_to_id[root .. ".to"]]:end_()
- ret.to = { line = end_row, col = end_col }
+ local fromnode
+ local tonode
+
+ local tmp = match[capture_to_id[root]]
+ if tmp then
+ fromnode = resolve_capture(tmp, 1)
+ tonode = resolve_capture(tmp)
+ else
+ fromnode = resolve_capture(match[capture_to_id[root .. ".from"]], 1)
+ tonode = resolve_capture(match[capture_to_id[root .. ".to"]]) or fromnode
end
+ local start_row, start_col = fromnode:start()
+ ret.from = { line = start_row, col = start_col }
+
+ local end_row, end_col = tonode:end_()
+ ret.to = { line = end_row, col = end_col }
+
return ret
end
+local qcache = setmetatable({}, {
+ __mode = "v",
+ __index = function(tbl, key)
+ local val = rawget(tbl, key)
+ if val then
+ return val
+ else
+ local q = vim.treesitter.query.get(key, 'textobjects')
+ rawset(tbl, key, q)
+ return q
+ end
+ end
+})
+
function captures_inout(root)
local lang = require 'nvim-treesitter.parsers'.get_buf_lang()
- local query = vim.treesitter.query.get(lang, 'textobjects')
+ local query = qcache[lang]
if query == nil then error("Could not get query") end
local capture_to_id = {}
@@ -156,11 +185,12 @@ function captures_inout(root)
-- Compute matched captures
local res = {}
for _, tree in ipairs(parser:trees()) do
- for _, match, _ in query:iter_matches(tree:root(), 0) do
+ for _, match, _ in query:iter_matches(tree:root(), 0, 0, -1, {all = true}) do
if well_defined(root, capture_to_id, match) then
+ local innerrange = extract_range(root .. ".inner", match, capture_to_id)
res[#res + 1] = {
outer = extract_range(root .. ".outer", match, capture_to_id),
- inner = extract_range(root .. ".inner", match, capture_to_id)
+ inner = innerrange
}
end
end
@@ -173,9 +203,8 @@ local function ai_treesitter(captures)
return function(ai_type)
local tgt_captures = ai_type == "a" and "outer" or "inner"
- local matches = captures_inout(captures)
local res = {}
- for _, match in ipairs(matches) do
+ for _, match in ipairs(captures_inout(captures)) do
local tgt = match[tgt_captures]
res[#res + 1] = {
from = {
diff --git a/after/queries/latex/textobjects.scm b/after/queries/latex/textobjects.scm
@@ -1,6 +1,5 @@
-((displayed_equation . (_) @math.inner.from (_)? @math.inner.to .) @math.outer)
-
-((inline_formula . (_) @math.inner.from (_)? @math.inner.to .) @math.outer)
+((displayed_equation "\\[" _+ @math.inner "\\]") @math.outer)
+((inline_formula "$" _+ @math.inner "$") @math.outer)
((math_environment
begin: (_) . (_) @math.inner.from @env.inner.from