summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorgi Kirilov <>2020-11-22 15:10:50 +0200
committerGeorgi Kirilov <>2023-10-04 18:24:59 +0800
commitd43d7b5288fddbcd52a02f890e25f542916b2f0f (patch)
tree9049bdf040d196c5cc69aa31c579eb450a8b41d7
parent58d7d0d754b2d1ebc3a95c0dac58a9cf37663a39 (diff)
downloadvis-pairs-d43d7b5288fddbcd52a02f890e25f542916b2f0f.tar.gz
Consider the whole selection, not just the cursor
Fixes: * vibib would stop as soon as the cursor gets to adjacent delimiters: (asdf (asdf)) * ib/ab on a selection partially covering a block wouldn't result in a fully selected block
-rw-r--r--pairs.lua38
1 files changed, 18 insertions, 20 deletions
diff --git a/pairs.lua b/pairs.lua
index 49ec19a..7312030 100644
--- a/pairs.lua
+++ b/pairs.lua
@@ -39,7 +39,7 @@ local function get_pair(key, win)
end
local function at_pos(t, pos)
- if pos >= t[1] and pos < t[#t] then return t end
+ if pos.start + 1 >= t[1] and pos.finish < t[#t] then return t end
end
local function asymmetric(d, escaped, pos)
@@ -101,10 +101,9 @@ local function not_past(_, position, pos)
end
local function match_at(str, pattern, pos)
- local string_pos = pos + 1
prev_match = 0
local I = l.Cp()
- local p = l.P{l.Cmt(l.Ct(I * (pattern/0) * I) * l.Cc(string_pos) / at_pos * l.Cc(0), any_captures) + 1 * l.Cmt(l.Cc(string_pos), not_past) * l.V(1)}
+ local p = l.P{l.Cmt(l.Ct(I * (pattern/0) * I) * l.Cc(pos) / at_pos * l.Cc(0), any_captures) + 1 * l.Cmt(l.Cc(pos.start + 1), not_past) * l.V(1)}
local t = p:match(str)
if t then return t[1] - 1, t[#t] - 1 end
end
@@ -120,14 +119,11 @@ local function escaping_context(win, range, data)
end
if not p then return {} end
if not range then return {escape = p} end -- means we are retrying with a "fake" pos
- local e1 = {match_at(data, p, range.start)}
- local e2 = range.finish - range.start > 1 and {match_at(data, p, range.finish - 1)} or e1
- if #e1 == 0 and #e2 == 0 then return {escape = p} end
- if #e1 == 0 and #e2 > 0 then return {escape = p, newpos = range.start} end
- if #e2 == 0 and #e1 > 0 then return {escape = p, newpos = range.finish - 1} end
+ local e1, e2 = match_at(data, p, range)
+ if not (e1 and e2) then return {escape = p} end
p = nil
- local escaped_range = {e1[1] + 1, e1[2]}
- local escaped_data = data:sub(e1[1] + 1, e1[2])
+ local escaped_range = {e1 + 1, e2}
+ local escaped_data = data:sub(e1 + 1, e2)
for _, level in ipairs({vis.lexers.COMMENT, vis.lexers.STRING}) do
if l.match(rules[level] / 0 * -1, escaped_data) then
for _, name in ipairs(precedence[level]) do
@@ -148,26 +144,28 @@ local function get_range(key, win, pos, file_data, count)
local sel_range = selection_range(win, pos)
local c = escaping_context(win, sel_range, file_data)
local range = c.range or {1, #file_data}
- if c.newpos then
- pos = c.newpos
+ correction = range[1] - 1
+ pos = pos - correction
+ if sel_range then
+ sel_range.start = sel_range.start - correction
+ sel_range.finish = sel_range.finish - correction
else
- pos = pos - (range[1] - 1)
+ sel_range = {start = pos + 1, finish = pos + 2}
end
- correction = range[1] - 1
- local p = d[1] ~= d[2] and symmetric(d[1], d[2], c.escape, pos + 1) or asymmetric(d[1], c.escape, pos + 1)
+ local p = d[1] ~= d[2] and symmetric(d[1], d[2], c.escape, sel_range) or asymmetric(d[1], c.escape, sel_range)
local can_abut = d[1] == d[2] and #d[1] == 1 and not (builtin_textobjects[key] or M.map[1][key] or M.map[win.syntax] and M.map[win.syntax][key])
local skip = c.escape and c.escape + 1 or 1
local data = c.range and file_data:sub(unpack(c.range)) or file_data
local pattern = l.P{l.Cmt(p * l.Cc(can_abut and 1 or 0), any_captures) + skip * l.Cmt(l.Cc(pos + 1), not_past) * l.V(1)}
prev_match = 0
local hierarchy = pattern:match(data)
- if not hierarchy then return end
- offsets = {nth_innermost(hierarchy, count or 1)}
- offsets[3] = nil -- a leftover from calling nth_innermost() with count higher than the hierarchy depth.
- if #offsets == 0 then
+ if hierarchy then
+ offsets = {nth_innermost(hierarchy, count or 1)}
+ offsets[3] = nil -- a leftover from calling nth_innermost() with count higher than the hierarchy depth.
+ else
pos = correction - 1
end
- until #offsets > 0 or pos < 0
+ until hierarchy or pos < 0
for _, o in ipairs(offsets) do
for i, v in ipairs(o) do
o[i] = v - 1 + correction