which-key integration
Esgariot opened this issue · comments
Hi, (again, I'm new to lua and vimscript,) I was wondering if there's any mechanism in which I could provide a mapping callback, or a delegate that would set the mapping instead?
Something here
nvim-cartographer/lua/cartographer.lua
Lines 83 to 100 in 2c89288
nvim_set_keymap(...
I see mention of "Callbacks" above the linked part, but I don't feel like it's related to what I'm asking about, more like assigning lua code to mapping
Would like to map some key combination to Lua code which you would like to run? Or do you want to create a Lua function which creates a keybinding?
For example,
-- map a function
map.n.nore['gr'] = function()
-- stuff
end
-- map in function
function foo()
map.n.nore['gr'] = -- something
end
Or are you looking for neither? (In which case a little psuedocode would be helpful 😉)
Edit: to be clear, both examples are possible.
local map = require('cartographer').n.nore
local function foo()
map['gP'] = 'gg'
end
map['gP'] = foo
Now, pressing gP
will remap gP
to gg
. Pressing gP
a second time will move your cursor to the top of the screen, since gP
maps to gg
now.
I'm looking for something like
local map = require('cartographer')
local function myCallback(mode, opts, mapping)
-- perform mapping here, using arbitrary method, e.g.
require("which-key").register{ name = "something", f = mapping, mode = mode, silent = opts['silent'], noremap = opts.Contains('noremap'), ... }
-- another example
print 'setting binding to' + mode + ' ' + mapping
vim.api.nvim_set_keymap(mode, mapping, opts)
-- this receives "n","<leader>b","silent", ":TreeOpen<CR>" under appropriate fields/keys, from function parameters
end
map.n.callback(myCallback).silent['<leader>b'] = ":TreeOpen<CR>"
meaning - delegate actual registration to some function
this way cartographer would be composable with other mapping plugins
and I could use "which-key" while using sweet sweet cartographer DSL
I think there's definitely something we can do for that. I'll do some experimenting.
(after learning 5 minutes of lua)
I suppose there could be a :delegate(myRegistrar)
in the fluent chain
map.n:delegate(myFn("group A" --[[ partially applied, for one group of keybindings --]]).silent['<leader>g'] = 'gg'
and in cartographer.lua
Cartographer = {}
-- ...
function Cartographer:delegate(fn)
self.the_delegate = fn; return self -- I think this needs to know it's a function, not a table or something
end
-- in __newindex, in rhs clause:
for _, mode in ipairs(modes) do
the_delegate(mode, lhs, rhs, opts) or --[[ if the_delegate is nil --]] vim.api.nvim_set_keybind(mode, lhs, rhs, opts)
end
This errors in runtime, and I'd need to set up a lua development workflow to fix it
@Esgariot I have created #12 with the map:hook()
syntax. See the PR for more details, and let me know if you run into any issues. Note the hook runs after the keymap is created or deleted (to catch errors), so you don't have to set the keymap yourself. Also, it passes all modes that they keymap was set for, rather than calling one at a time (though I can change this last bit if desired).
Also note you can set and/or reset the hook at any point in the fluent interface:
local map = require 'cartographer'
local nnoremap = map.n.nore:hook(function(buffer, modes, lhs, rhs, opts)
-- do something
end)
nnoremap['zfy'] = vim.lsp.foo
nnoremap:hook(function(buffer, modes, lhs, rhs, opts)
-- do something else
end)['zfyx'] = vim.lsp.bar
Very cool! I've been learning about _call
s and metatables and was trying to come up with something, I'll check out how have you done it!
So far so good, checked that it works well with buffers and globally, thanks a lot!
So those examples I posted on the PR are working for you? That's good to hear!