aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/bracketmatch.lua64
1 files changed, 38 insertions, 26 deletions
diff --git a/plugins/bracketmatch.lua b/plugins/bracketmatch.lua
index 71fb26a..432dd42 100644
--- a/plugins/bracketmatch.lua
+++ b/plugins/bracketmatch.lua
@@ -1,11 +1,37 @@
local core = require "core"
local style = require "core.style"
-local config = require "core.config"
local command = require "core.command"
local keymap = require "core.keymap"
local DocView = require "core.docview"
-local bracket_map = { ["["] = "]", ["("] = ")", ["{"] = "}" }
+local bracket_maps = {
+ -- [ ] ( ) { }
+ { [91] = 93, [40] = 41, [123] = 125, step = 1 },
+ -- ] [ ) ( } {
+ { [93] = 91, [41] = 40, [125] = 123, step = -1 },
+}
+
+
+local function get_matching_bracket(doc, line, col, line_limit, open_byte, close_byte, step)
+ local end_line = line + line_limit * step
+ local depth = 0
+
+ while line ~= end_line do
+ local byte = doc.lines[line]:byte(col)
+ if byte == open_byte then
+ depth = depth + 1
+ elseif byte == close_byte then
+ depth = depth - 1
+ if depth == 0 then return line, col end
+ end
+
+ local prev_line, prev_col = line, col
+ line, col = doc:position_offset(line, col, step)
+ if line == prev_line and col == prev_col then
+ break
+ end
+ end
+end
local state = {}
@@ -27,34 +53,20 @@ local function update_state(line_limit)
return
end
- -- find matching rbracket if we have an lbracket
+ -- find matching bracket if we're on a bracket
local line2, col2
- local chr = doc:get_text(line, col - 1, line, col)
- local rbracket = bracket_map[chr]
-
- if rbracket then
- local ptn = "[%" .. chr .. "%" .. rbracket .. "]"
- local offset = col - 1
- local depth = 1
-
- for i = line, math.min(#doc.lines, line + line_limit) do
- while offset do
- local n = doc.lines[i]:find(ptn, offset + 1)
- if n then
- local match = doc.lines[i]:sub(n, n)
- if match == chr then
- depth = depth + 1
- elseif match == rbracket then
- depth = depth - 1
- if depth == 0 then line2, col2 = i, n end
- end
- end
- offset = n
+ for _, map in ipairs(bracket_maps) do
+ for i = 0, -1, -1 do
+ local line, col = doc:position_offset(line, col, i)
+ local open = doc.lines[line]:byte(col)
+ local close = map[open]
+ if close then
+ line2, col2 = get_matching_bracket(doc, line, col, line_limit, open, close, map.step)
+ goto found
end
- if line2 then break end
- offset = 0
end
end
+ ::found::
-- update
state = {