Iron-E / nvim-libmodal

Create new "modes" for Neovim!
Other
118 stars 7 forks source link

Using default bindings from within a mode #22

Closed vE5li closed 1 year ago

vE5li commented 1 year ago

For my plugin I need to be able to send key codes from Lua without the active Mode interfering. I'm not completely sure how the event loop inside a mode works, but even me setting a variable manually like this

if userInput == 'd' then
    vim.g.fooModePassthrough = true
    vim.api.nvim_input("d")
    vim.g.fooModePassthrough = false
end

would be sufficient for me. Is this possible?

Iron-E commented 1 year ago

Would a :h libmodal-layer help in this case?

vE5li commented 1 year ago

Sadly not really. I don't want unrecognized input to be passed through, but rather the ability to trigger other "lower" bindings in a very controlled manner.

vE5li commented 1 year ago

Although the snippet I sent earlier was just a random example, I think it also shows a problem I would run into with layers. If I wanted to handle the key 'd' in my layer, I would be unable to trigger a lower binding that is also bound to 'd'

Iron-E commented 1 year ago

I see. I'll do some investigation.

Iron-E commented 1 year ago

I had a thought, would something like this work? You can pass a table of possible inputs to the mode and anything which executes there is taken as raw input (and if it doeen't still do that, it's most certainly a bug)

If that doesn't fit your use case I can investigate it further.

vE5li commented 1 year ago

I'm sorry but you're going to have to be a bit more specific, I don't really understand how this could solve my issue

Iron-E commented 1 year ago

Apologies if that was vague! I'll try to be more specific. From what I understand, this issue is related to doing something like this:

libmodal.mode.enter('FOO', function()
  vim.api.nvim_input('dd')
end)

…and the mode eats the dd input? (If I'm not understanding that right, please let me know / post a small example and I can help better).

Based on my understanding, the following is a solution:

libmodal.mode.enter('FOO', {
  d = 'norm! dd', -- map 'd' to 'dd'
  f = function() -- map `f` to a function
    vim.api.nvim_command 'norm! dd' -- (or nvim_input)
  end, 
})

There are also some benefits to providing a mapping table like this, such as automatic generation of a mode summary (i.e. press ? to see available mappings). It won't be a great solution if you need to dynamically respond to user actions (i.e. the available mappings aren't predetermined), although this can be somewhat mitigated by using submodes.

vE5li commented 1 year ago

Thank you for taking the time to elaborate. I think that should cover my use case, especially with the help of submodes (thanks for the hint)