diff options
-rw-r--r-- | pairs.lua | 59 |
1 files changed, 29 insertions, 30 deletions
@@ -60,11 +60,11 @@ local function symmetric(d1, d2, escaped, pos) return l.P{l.Ct(I * d1 * I * ((skip - d1 - d2) + l.V(1))^0 * I * d2 * I) * l.Cc(pos) / at_pos} end -local function nth(t) +local function nth(t, count) if type(t) == "table" then - local start, finish, c = 0, 0, vis.count or 1 + local start, finish, c = 0, 0, count if #t == 5 then - start, finish, c = nth(t[3]) + start, finish, c = nth(t[3], count) end if c then return {t[1], t[2]}, {t[#t - 1], t[#t]}, c > 1 and c - 1 or nil @@ -143,7 +143,7 @@ local function escaping_context(win, range, data) end end -local function get_range(key, win, pos, file_data) +local function get_range(key, win, pos, file_data, count) local d = get_pair(key, win) if not d then return end local offsets, correction @@ -163,7 +163,7 @@ local function get_range(key, win, pos, file_data) 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 - offsets = {nth(pattern:match(data))} + offsets = {nth(pattern:match(data), count or 1)} offsets[3] = nil if #offsets == 0 then pos = correction - 1 @@ -203,11 +203,11 @@ local function barf_linewise(win, content, start, finish) return start, finish end -local function get_delimiters(key, win, pos) +local function get_delimiters(key, win, pos, count) local d = get_pair(key, win) if not d or type(d[1]) == "string" and type(d[2]) == "string" then return d end local content = win.file:content(0, win.file.size) - local start, finish = get_range(key, win, pos, content) + local start, finish = get_range(key, win, pos, content, count or vis.count) if start and finish then return {win.file:content(start[1], start[2] - start[1]), win.file:content(finish[1], finish[2] - finish[1]), d[3], d.prompt} elseif #d > 2 then @@ -215,42 +215,32 @@ local function get_delimiters(key, win, pos) end end -local function outer(win, pos, content) - local start, finish = get_range(M.key, win, pos, content) +local function outer(win, pos, content, count) + local start, finish = get_range(M.key, win, pos, content, count) if not (start and finish) then return end return start[1], finish[2] end -local function inner(win, pos, content) - local start, finish = get_range(M.key, win, pos, content) +local function inner(win, pos, content, count) + local start, finish = get_range(M.key, win, pos, content, count) if not (start and finish) then return end return barf_linewise(win, content, start[2], finish[1]) end -local function opening(win, pos, content) - local start, _ = get_range(M.key, win, pos, content) +local function opening(win, pos, content, count) + local start, _ = get_range(M.key, win, pos, content, count) if start then - if pos == start[2] - 1 then - start, _ = get_range(M.key, win, start[1] - 1, content) - end - if start then - local exclusive = (vis.mode == vis.modes.OPERATOR_PENDING or vis.mode == vis.modes.VISUAL and pos < start[2] - 1) and 1 or 0 - return start[2] - 1 + exclusive - end + local exclusive = (vis.mode == vis.modes.OPERATOR_PENDING or vis.mode == vis.modes.VISUAL and pos < start[2] - 1) and 1 or 0 + return start[2] - 1 + exclusive end return pos end -local function closing(win, pos, content) - local _, finish = get_range(M.key, win, pos, content) +local function closing(win, pos, content, count) + local _, finish = get_range(M.key, win, pos, content, count) if finish then - if pos == finish[1] then - _, finish = get_range(M.key, win, finish[2], content) - end - if finish then - local exclusive = (vis.mode == vis.modes.VISUAL and pos > finish[1]) and 1 or 0 - return finish[1] - exclusive - end + local exclusive = (vis.mode == vis.modes.VISUAL and pos > finish[1]) and 1 or 0 + return finish[1] - exclusive end return pos end @@ -290,7 +280,16 @@ local function prep(func) return function(win, pos) if bail_early() then return pos end local content = win.file:content(0, win.file.size) - return func(win, pos, content) + local start, finish = func(win, pos, content, vis.count) + if not vis.count and vis.mode == vis.modes.VISUAL or start and not finish then + local old = selection_range(win, pos) + local same_or_smaller = finish and start >= old.start and finish <= old.finish + local didnt_move = not finish and start == pos + if same_or_smaller or didnt_move then + start, finish = func(win, pos, content, 2) + end + end + return start, finish end end |