Skip to content
This repository was archived by the owner on Jun 6, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ we'd like to include the following features in future versions:
- [ ] API for creating user autocommands.
- [ ] Support passing mapping mode in opts.
- [ ] Support specifying multiple modes as a string like 'nvt'.
- [ ] Support specifying labels on groups which become which-key group names.
- [ ] Support progressively building up maps with groups, like:
- [x] Support specifying labels on groups which become which-key group names.
- [x] Support progressively building up maps with groups, like:

```lua
mapx.group({ prefix = "<leader>t" }, "LSP", function()
Expand Down
53 changes: 45 additions & 8 deletions lua/mapx/mapper.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
local merge = require('mapx.util').merge
local util = require 'mapx.util'
local merge = util.merge
local setMerge = util.setMerge
local log = require 'mapx.log'

local dbgi = log.dbgi
Expand All @@ -11,6 +13,7 @@ local Mapper = {
script = { script = true },
expr = { expr = true },
unique = { unique = true },
prefix = { prefix = '<leader>' },
},
}

Expand All @@ -22,12 +25,12 @@ local function expandStringOpts(opts)
for k, v in pairs(opts) do
if type(k) == 'number' then
if Mapper.mapopts[v] then
res[v] = true
res = merge(res, Mapper.mapopts[v])
goto continue
end
local vsub = type(v) == 'string' and vim.fn.substitute(v, [[^<\|>$]], '', 'g')
if vsub and Mapper.mapopts[vsub] ~= nil then
res[vsub] = true
res = merge(res, Mapper.mapopts[vsub])
goto continue
end
table.insert(res, v)
Expand Down Expand Up @@ -57,6 +60,7 @@ function Mapper.new()
luaFuncs = {},
filetypeMaps = {},
groupOpts = {},
groupMapsType = {},
groupActive = false,
whichkey = nil,
}
Expand Down Expand Up @@ -179,6 +183,19 @@ function Mapper:register(config, lhss, rhs, ...)
if type(lhss) ~= 'table' then
lhss = { lhss }
end

if opts.prefix ~= nil then
local new_lhss = {}
for _, lhs in ipairs(lhss) do
table.insert(new_lhss, opts.prefix .. lhs)
end
lhss = new_lhss
opts.prefix = nil
end
if self.groupActive then
self.groupMapsType[config.mode] = true
end

if type(rhs) == 'function' then
-- TODO: rhs gets inserted multiple times if a filetype mapping is
-- triggered multiple times
Expand Down Expand Up @@ -212,18 +229,38 @@ function Mapper:group(...)
end
end
self.groupOpts = expandStringOpts(self.groupOpts)
self.groupOpts = self:normalizeOpts(self.groupOpts)
dbgi('group', self.groupOpts)
local opts = self:normalizeOpts(self.groupOpts)
if opts.label ~= nil then
error('mapx.group: cannot set label on group: ' .. tostring(opts.label))
local opts = self.groupOpts
if opts.label ~= nil and opts.prefix == nil then
error('mapx.group: cannot set label on group without prefix: ' .. tostring(opts.label))
end
local label = opts.label
opts.label = nil
local prevGroupActive = self.groupActive
local prevGroupMapsType = self.groupMapsType
self.groupActive = true
self.groupMapsType = {}
fn()
if opts.prefix ~= nil and label ~= nil then
local new_opts = vim.deepcopy(opts)
new_opts.name = label
new_opts.prefix = nil
for k, v in pairs(self.groupMapsType) do
if v then
self:registerName(k, opts.prefix, new_opts)
end
end
end
self.groupActive = prevGroupActive
self.groupOpts = prevOpts
if self.groupActive == false and self.whichkey then
self.whichkey:flush()
self.groupMapsType = setMerge(self.groupMapsType, prevGroupMapsType)
self.groupActive = true
if self.groupActive == false then
if self.whichkey then
self.whichkey:flush()
end
self.groupMapsType = {}
end
end

Expand Down
20 changes: 20 additions & 0 deletions lua/mapx/util.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
local M = {}

-- Flat merge of 2 or more tables, supporting a mixture of map-like tables and
-- list-list tables.
-- - Right-most arguments take precedence.
-- - Numeric indices are extended, not replaced.
-- - No side effects.
function M.setMerge(...)
local res = {}
for i = 1, select('#', ...) do
local arg = select(i, ...)
for k, v in pairs(arg) do
if v then
res[k] = true
end
end
end
return res
end

-- Flat merge of 2 or more tables, supporting a mixture of map-like tables and
-- list-list tables.
-- - Right-most arguments take precedence.
Expand All @@ -13,6 +31,8 @@ function M.merge(...)
for k, v in pairs(arg) do
if type(k) == 'number' then
table.insert(res, v)
elseif k == 'prefix' then
res[k] = res[k] ~= nil and res[k] .. v or v
else
res[k] = v
end
Expand Down