nvim-config

Log | Files | Refs | Submodules | README

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:
Mafter/ftplugin/tex.lua | 57+++++++++++++++++++++++++++++++++++++++++++--------------
Mafter/queries/latex/textobjects.scm | 5++---
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