summaryrefslogtreecommitdiffstats
path: root/pairs.lua
diff options
context:
space:
mode:
authorGeorgi Kirilov <>2020-11-22 15:10:50 +0200
committerGeorgi Kirilov <>2023-10-04 18:24:59 +0800
commit508e8d162e67774a7658097943741ce2691cf0c7 (patch)
tree843a730dc3552cea490d38e3a16448d61e550afa /pairs.lua
parent132b6ca349f30b22bc67161a7c082dfb7397ffe7 (diff)
downloadvis-pairs-508e8d162e67774a7658097943741ce2691cf0c7.tar.gz
Prevent conflicts with external key mappings
The global single-letter mappings were shadowed by longer window-local mappings outside the plugin. Add help field for the built-in and any custom global mappings. (Had to make vis-surround ignore it, too.)
Diffstat (limited to 'pairs.lua')
-rw-r--r--pairs.lua84
1 files changed, 56 insertions, 28 deletions
diff --git a/pairs.lua b/pairs.lua
index 8ad1ea2..93808f3 100644
--- a/pairs.lua
+++ b/pairs.lua
@@ -9,13 +9,13 @@ local l = require("lpeg")
local M
local builtin_textobjects = {
- ["["] = { "[" , "]" },
- ["{"] = { "{" , "}" },
- ["<"] = { "<" , ">" },
- ["("] = { "(" , ")" },
- ['"'] = { '"' , '"' },
- ["'"] = { "'" , "'" },
- ["`"] = { "`" , "`" },
+ ["["] = { "[" , "]", "[] block" },
+ ["{"] = { "{" , "}", "{} block" },
+ ["<"] = { "<" , ">", "<> block" },
+ ["("] = { "(" , ")", "() block" },
+ ['"'] = { '"' , '"', "A quoted string" },
+ ["'"] = { "'" , "'", "A single quoted string" },
+ ["`"] = { "`" , "`", "A backtick delimited string" },
}
local builtin_motions = {
@@ -250,6 +250,23 @@ local function bail_early()
return false
end
+local function win_map(textobject, prefix, binding, help)
+ return function(win)
+ if not textobject then
+ win:map(vis.modes.NORMAL, prefix, binding, help)
+ end
+ win:map(vis.modes.VISUAL, prefix, binding, help)
+ win:map(vis.modes.OPERATOR_PENDING, prefix, binding, help)
+ end
+end
+
+local function bind_builtin(key, execute, id)
+ return function()
+ M.key = key
+ execute(vis, id)
+ end
+end
+
local function prep(func)
return function(win, pos)
if bail_early() then return pos end
@@ -258,6 +275,8 @@ local function prep(func)
end
end
+local mappings = {}
+
local function new(execute, register, prefix, handler, help)
local id = register(vis, prep(handler))
if id < 0 then
@@ -272,42 +291,37 @@ local function new(execute, register, prefix, handler, help)
end
return #keys
end
- 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)
+ table.insert(mappings, win_map(execute == vis.textobject, prefix, binding, help))
local builtin = execute == vis.motion and builtin_motions[prefix] or builtin_textobjects
for key, _ in pairs(builtin) do
+ local hlp = (execute == vis.motion and help or "") .. builtin_textobjects[key][3]
if execute ~= vis.textobject then
- vis:unmap(vis.modes.NORMAL, prefix..key)
+ vis:map(vis.modes.NORMAL, prefix..key, bind_builtin(key, execute, id), hlp)
end
- vis:unmap(vis.modes.VISUAL, prefix..key)
- vis:unmap(vis.modes.OPERATOR_PENDING, prefix..key)
+ local variant = prefix == M.prefix.outer and " (outer variant)" or prefix == M.prefix.inner and " (inner variant)" or ""
+ vis:map(vis.modes.VISUAL, prefix..key, bind_builtin(key, execute, id), hlp and hlp .. variant or help)
+ vis:map(vis.modes.OPERATOR_PENDING, prefix..key, bind_builtin(key, execute, id), hlp and hlp .. variant or help)
end
end
return id
end
-vis.events.subscribe(vis.events.INIT, function()
- M.motion = {
- opening = new(vis.motion, vis.motion_register, M.prefix.opening, opening, "Move cursor to the beginning of a delimited block"),
- closing = new(vis.motion, vis.motion_register, M.prefix.closing, closing, "Move cursor to the end of a delimited block"),
- }
- M.textobject = {
- 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)"),
- }
+vis.events.subscribe(vis.events.WIN_OPEN, function(win)
+ for _, map_keys in ipairs(mappings) do
+ map_keys(win)
+ end
+end)
+vis.events.subscribe(vis.events.INIT, function()
local function cmp(_, _, c1, c2) return c1 == c2 end
local function casecmp(_, _, c1, c2) return c1:lower() == c2:lower() end
- local function closing(s1, s2, cmpfunc) return l.Cmt(s1 * l.Cb("t") * l.C((1 - l.P(s2))^1) * s2, cmpfunc) end
- local tex_environment = {"\\begin{" * l.Cg(l.R("az", "AZ")^1, "t") * "}", closing("\\end{", "}", cmp), {"\\begin{\xef\xbf\xbd}", "\\end{\xef\xbf\xbd}"}, "environment name"}
+ local function end_tag(s1, s2, cmpfunc) return l.Cmt(s1 * l.Cb("t") * l.C((1 - l.P(s2))^1) * s2, cmpfunc) end
+ local tex_environment = {"\\begin{" * l.Cg(l.R("az", "AZ")^1, "t") * "}", end_tag("\\end{", "}", cmp), {"\\begin{\xef\xbf\xbd}", "\\end{\xef\xbf\xbd}"}, "environment name"}
local tag_name = (l.S"_:" + l.R("az", "AZ")) * (l.R("az", "AZ", "09") + l.S"_:.-")^0
local noslash = {--[[implicit:]] p=1, dt=1, dd=1, li=1, --[[void:]] area=1, base=1, br=1, col=1, embed=1, hr=1, img=1, input=1, link=1, meta=1, param=1, source=1, track=1, wbr=1}
local function is_not(_, _, v) return v ~= 1 end
- local html_tag = {"<" * l.Cg(l.Cmt(tag_name / string.lower / noslash, is_not), "t") * (1 - l.S"><")^0 * (">" - l.B"/"), closing("</", ">", casecmp), {"<\xef\xbf\xbd>", "</\xef\xbf\xbd>"}, "tag name"}
- local xml_tag = {"<" * l.Cg(tag_name, "t") * (1 - l.S"><")^0 * (">" - l.B"/"), closing("</", ">", cmp), {"<\xef\xbf\xbd>", "</\xef\xbf\xbd>"}, "tag name"}
+ local html_tag = {"<" * l.Cg(l.Cmt(tag_name / string.lower / noslash, is_not), "t") * (1 - l.S"><")^0 * (">" - l.B"/"), end_tag("</", ">", casecmp), {"<\xef\xbf\xbd>", "</\xef\xbf\xbd>"}, "tag name"}
+ local xml_tag = {"<" * l.Cg(tag_name, "t") * (1 - l.S"><")^0 * (">" - l.B"/"), end_tag("</", ">", cmp), {"<\xef\xbf\xbd>", "</\xef\xbf\xbd>"}, "tag name", "<tag></tag> block"}
local function any_pair(set, default) return {l.Cg(l.S(set), "s"), l.Cmt(l.Cb("s") * l.C(1), function(_, _, c1, c2) return builtin_textobjects[c1][2] == c2 end), builtin_textobjects[default]} end
local any_bracket = any_pair("({[", "(")
local presets = {
@@ -333,6 +347,20 @@ vis.events.subscribe(vis.events.INIT, function()
end
end
end
+ for key, d in pairs(M.map[1]) do
+ builtin_textobjects[key] = {d[1], d[2], d[#d]}
+ builtin_motions[M.prefix.opening][key] = true
+ builtin_motions[M.prefix.closing][key] = true
+ end
+
+ M.motion = {
+ opening = new(vis.motion, vis.motion_register, M.prefix.opening, opening, "Move cursor to the beginning of a "),
+ closing = new(vis.motion, vis.motion_register, M.prefix.closing, closing, "Move cursor to the end of a "),
+ }
+ M.textobject = {
+ 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)"),
+ }
end)