diff options
author | Georgi Kirilov <> | 2020-11-22 15:10:49 +0200 |
---|---|---|
committer | Georgi Kirilov <> | 2023-10-04 18:24:58 +0800 |
commit | e2a571588c141120286912147892b401a066b5cd (patch) | |
tree | 62d405f6f45d6dcb6cfd99df06a345b41dd98a98 /pairs.lua | |
parent | c4cc47a8e5fc3192d5a178c4c3edba17451a0b97 (diff) | |
download | vis-pairs-e2a571588c141120286912147892b401a066b5cd.tar.gz |
DRY fixes
Diffstat (limited to 'pairs.lua')
-rw-r--r-- | pairs.lua | 91 |
1 files changed, 40 insertions, 51 deletions
@@ -8,25 +8,33 @@ local l = require("lpeg") local M -local builtins = { +local builtin_textobjects = { ["["] = { "[" , "]" }, ["{"] = { "{" , "}" }, ["<"] = { "<" , ">" }, ["("] = { "(" , ")" }, + ['"'] = { '"' , '"' }, + ["'"] = { "'" , "'" }, + ["`"] = { "`" , "`" }, +} + +local builtin_motions = { + ["["] = { ["("] = true, ["{"] = true }, + ["]"] = { [")"] = true, ["}"] = true }, } local aliases = {} -for _, pair in pairs(builtins) do aliases[pair[2]] = pair end -for key, pair in pairs(aliases) do builtins[key] = pair end -for key, pair in pairs({ +for key, pair in pairs(builtin_textobjects) do aliases[pair[2]] = key ~= pair[2] and pair or nil end +for alias, pair in pairs(aliases) do builtin_textobjects[alias] = pair end +for alias, key in pairs({ B = "{", b = "(", -}) do builtins[key] = builtins[pair] end +}) do builtin_textobjects[alias] = builtin_textobjects[key] end local function get_pair(key) return M.map[vis.win.syntax] and M.map[vis.win.syntax][key] or M.map[1] and M.map[1][key] - or builtins[key] + or builtin_textobjects[key] or not key:match("%w") and {key, key} end @@ -76,6 +84,14 @@ local function get_range(key, file, pos) return nth(l.match(pattern, file:content(0, file.size))) end +local function get_delimiters(key, pos) + local d = get_pair(key) + if not d or type(d[1]) == "string" and type(d[2]) == "string" then return d end + local start, finish = get_range(key, vis.win.file, pos) + if not (start and finish) then return end + return {vis.win.file:content(start[1], start[2] - start[1]), vis.win.file:content(finish[1], finish[2] - finish[1])} +end + local function outer(win, pos) local start, finish = get_range(M.key, win.file, pos) if not (start and finish) then return end @@ -88,38 +104,6 @@ local function inner(win, pos) return start[2], finish[1] end -local function get_delimiters(key, pos) - local d = get_pair(key) - if not d or type(d[1]) == "string" and type(d[2]) == "string" then return d end - local start, finish = get_range(key, vis.win.file, pos) - if not (start and finish) then return end - return {vis.win.file:content(start[1], start[2] - start[1]), vis.win.file:content(finish[1], finish[2] - finish[1])} -end - -local function textobject_new(prefix, textobject, help) - local id = vis:textobject_register(textobject) - if id < 0 then - return false - end - if prefix then - for _, o in ipairs({"[", "]", "{", "}", "<", ">", "(", ")", "b", "B", '"', "'", "`", "i"}) do - vis:unmap(vis.modes.VISUAL, prefix..o) - vis:unmap(vis.modes.OPERATOR_PENDING, prefix..o) - end - local binding = function(keys) - if #keys < 1 then return -1 end - if #keys == 1 then - M.key = keys - vis:textobject(id) - end - return #keys - end - vis:map(vis.modes.VISUAL, prefix, binding, help) - vis:map(vis.modes.OPERATOR_PENDING, prefix, binding, help) - end - return id -end - local function opening(win, pos) local start, _ = get_range(M.key, win.file, pos) if start then @@ -146,40 +130,45 @@ local function closing(win, pos) return pos end -local function motion_new(prefix, motion, help) - local id = vis:motion_register(motion) +local function new(execute, register, prefix, handler, help) + local id = register(vis, handler) if id < 0 then return false end if prefix then - for _, o in ipairs({"{", "}", "(", ")"}) do - vis:unmap(vis.modes.NORMAL, prefix..o) - vis:unmap(vis.modes.VISUAL, prefix..o) - vis:unmap(vis.modes.OPERATOR_PENDING, prefix..o) - end local binding = function(keys) if #keys < 1 then return -1 end if #keys == 1 then M.key = keys - vis:motion(id) + execute(vis, id) end return #keys end - vis:map(vis.modes.NORMAL, prefix, binding, help) + if execute ~= vis.textobject then + vis:map(vis.modes.NORMAL, prefix, binding, help) + end vis:map(vis.modes.VISUAL, prefix, binding, help) vis:map(vis.modes.OPERATOR_PENDING, prefix, binding, help) + local builtin = execute == vis.motion and builtin_motions[prefix] or builtin_textobjects + for key, _ in pairs(builtin) do + if execute ~= vis.textobject then + vis:unmap(vis.modes.NORMAL, prefix..key) + end + vis:unmap(vis.modes.VISUAL, prefix..key) + vis:unmap(vis.modes.OPERATOR_PENDING, prefix..key) + end end return id end vis.events.subscribe(vis.events.INIT, function() M.motion = { - opening = motion_new(M.prefix.opening, opening, "Move cursor to the opening delimiter inside a pair of delimiters"), - closing = motion_new(M.prefix.closing, closing, "Move cursor to the closing delimiter inside a pair of delimiters"), + opening = new(vis.motion, vis.motion_register, M.prefix.opening, opening, "Move cursor to the opening delimiter inside a pair of delimiters"), + closing = new(vis.motion, vis.motion_register, M.prefix.closing, closing, "Move cursor to the closing delimiter inside a pair of delimiters"), } M.textobject = { - inner = textobject_new(M.prefix.inner, inner, "Delimited block (inner variant)"), - outer = textobject_new(M.prefix.outer, outer, "Delimited block (outer variant)"), + inner = new(vis.textobject, vis.textobject_register, M.prefix.inner, inner, "Delimited block (inner variant)"), + outer = new(vis.textobject, vis.textobject_register, M.prefix.outer, outer, "Delimited block (outer variant)"), } local tag = {"<" * l.Cg(l.C((1 - l.S" />")^1), "t") * (1 - l.P">")^0 * (">" - l.B" /"), l.Cmt("</" * l.Cb("t") * l.C((1 - l.P">")^1) * ">", function(_, _, c1, c2) return c1 == c2 end)} M.map.html = {t = tag} |