commit a4571e5290293d49235c5c20e600408c8a4f1b52
parent 9957a6d6be583b376e9d20cf85b26a416aec79a4
Author: Thomas Vigouroux <me@vigoux.eu>
Date: Thu, 7 Mar 2024 07:59:20 +0100
feat(latex): simplify textobjects
Diffstat:
2 files changed, 28 insertions(+), 79 deletions(-)
diff --git a/after/ftplugin/tex.lua b/after/ftplugin/tex.lua
@@ -111,88 +111,34 @@ do
end), { buffer = true })
end
----@param captures string[]
-local function well_defined(captures, capture_to_id, matches)
- for _, capture in ipairs(captures) do
- if not matches[capture_to_id[capture:sub(2)]] then
- return false
- end
- end
- return true
+local function well_defined(root, capture_to_id, matches)
+ return (matches[capture_to_id[root .. ".inner"]]
+ or (matches[capture_to_id[root .. ".inner.from"]]
+ and matches[capture_to_id[root .. ".inner.to"]]
+ )) and (matches[capture_to_id[root .. ".outer"]]
+ or (matches[capture_to_id[root .. ".outer.from"]]
+ and matches[capture_to_id[root .. ".outer.to"]]
+ ))
end
-local function extract_range(spec, match, capture_to_id)
+local function extract_range(root, match, capture_to_id)
local ret = {}
- if type(spec) == "string" then
- local start_row, start_col, end_row, end_col = match[capture_to_id[spec:sub(2)]]:range()
+ 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[spec.from:sub(2)]]:start()
+ 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[spec.to:sub(2)]]:end_()
+ local end_row, end_col = match[capture_to_id[root .. ".to"]]:end_()
ret.to = { line = end_row, col = end_col }
end
return ret
end
-function captures_inout(spec)
- vim.validate {
- spec = {
- spec,
- 'table'
- }
- }
-
- vim.validate {
- ["spec.inner"] = {
- spec.inner,
- { 'string', 'table' },
- },
- ["spec.outer"] = {
- spec.outer,
- { 'string', 'table' },
- }
- }
-
- local all_captures = {}
-
- if type(spec.inner) == 'table' then
- vim.validate {
- ["spec.inner.from"] = {
- spec.inner.from,
- "string",
- },
- ["spec.inner.to"] = {
- spec.inner.to,
- "string",
- }
- }
- all_captures[#all_captures + 1] = spec.inner.from
- all_captures[#all_captures + 1] = spec.inner.to
- else
- all_captures[#all_captures + 1] = spec.inner
- end
-
- if type(spec.outer) == 'table' then
- vim.validate {
- ["spec.outer.from"] = {
- spec.outer.from,
- "string",
- },
- ["spec.outer.to"] = {
- spec.outer.to,
- "string"
- }
- }
- all_captures[#all_captures + 1] = spec.outer.from
- all_captures[#all_captures + 1] = spec.outer.to
- else
- all_captures[#all_captures + 1] = spec.outer
- end
-
+function captures_inout(root)
local lang = require 'nvim-treesitter.parsers'.get_buf_lang()
local query = vim.treesitter.query.get(lang, 'textobjects')
if query == nil then error("Could not get query") end
@@ -202,18 +148,20 @@ function captures_inout(spec)
capture_to_id[val] = idx
end
+ root = root:sub(2)
local ok, parser = pcall(vim.treesitter.get_parser, 0, lang)
+ if not ok then return end
-- Compute matched captures
local res = {}
for _, tree in ipairs(parser:trees()) do
for _, match, _ in query:iter_matches(tree:root(), 0) do
- if well_defined(all_captures, capture_to_id, match) then
+ if well_defined(root, capture_to_id, match) then
res[#res + 1] = {
- outer = extract_range(spec.outer, match, capture_to_id),
- inner = extract_range(spec.inner, match, capture_to_id)
+ outer = extract_range(root .. ".outer", match, capture_to_id),
+ inner = extract_range(root .. ".inner", match, capture_to_id)
}
end
end
@@ -248,10 +196,10 @@ end
-- local spec_treesitter = require('mini.ai').gen_spec.treesitter
vim.b.miniai_config = {
custom_textobjects = {
- m = ai_treesitter { outer = "@math.outer", inner = { from = "@math.inner.from", to = "@math.inner.to" } },
- e = ai_treesitter { outer = "@env.outer", inner = { from = "@env.inner.from", to = "@env.inner.to" } },
- s = ai_treesitter { outer = "@section.outer", inner = { from = "@section.inner.from", to = "@section.inner.to" } },
- i = ai_treesitter { outer = "@item.outer", inner = { from = "@item.inner.from", to = "@item.inner.to" } }
+ m = ai_treesitter "@math",
+ e = ai_treesitter "@env",
+ s = ai_treesitter "@section",
+ i = ai_treesitter "@item",
}
}
@@ -310,16 +258,16 @@ end
vim.b.minisurround_config = {
custom_surroundings = {
f = {
- input = surround_treesitter { outer = "@call.outer", inner = "@call.inner" },
+ input = surround_treesitter "@call",
output = output_ask("Function name", "\\%s{", "}")
},
e = {
- input = surround_treesitter { outer = "@env.outer", inner = { from = "@env.inner.from", to = "@env.inner.to" } },
+ input = surround_treesitter "@env",
output = output_ask("Env name", "\\begin{%s}\n", "\n\\end{%s}")
},
c = {
- input = surround_treesitter { outer = { from = "@color.outer.from", to = "@color.outer.to" }, inner = "@color.inner" },
- output = output_ask("Color name", "{\\textcolor{%s}{", "}}")
+ input = surround_treesitter "@color",
+ output = output_ask("Color name", "\\textcolor{%s}{", "}")
}
}
}
diff --git a/after/queries/latex/textobjects.scm b/after/queries/latex/textobjects.scm
@@ -19,3 +19,4 @@
;; Colored text
((color_reference) @color.outer.from . (curly_group (_) @color.inner) @color.outer.to)
+((_ (color_reference) @color.outer.from) . (curly_group (_) @color.inner) @color.outer.to)