Iron-E / nvim-cartographer

Create Neovim `:map`pings in Lua with ease!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

if buffer then
for _, mode in ipairs(modes) do
vim.api.nvim_buf_set_keymap(buffer, mode, lhs, rhs, opts)
end
else
for _, mode in ipairs(modes) do
vim.api.nvim_set_keymap(mode, lhs, rhs, opts)
end
end
else
if buffer then
for _, mode in ipairs(modes) do
vim.api.nvim_buf_del_keymap(buffer, mode, lhs)
end
else
for _, mode in ipairs(modes) do
vim.api.nvim_del_keymap(mode, lhs)
end
that would call a delegate if it was provided, otherwise fallback to 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 _calls 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!