Iron-E / nvim-libmodal

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

Modifier mappings don't seem to work support #29

Closed mawkler closed 8 months ago

mawkler commented 8 months ago

Mappings with modifiers like ctrl/meta don't seem to work:

local M = {}

M.mode = {
  n = function()
    vim.notify('This works')
  end,
  ['<c-n>'] = function()
    vim.notify("This doesn't work")
  end,
  ['<m-n>'] = function()
    vim.notify("This throws error: 'attempt to compare number with string'")
  end
}

vim.keymap.set('n', 'M', function()
  require('libmodal').mode.enter('My mode', M.mode)
end)
  1. Press M to enter custom mode
  2. Pressing n produces notification 'This works'
  3. Pressing <c-n> doesn't produce a notification
  4. Pressing <m-n> throws an error
Iron-E commented 8 months ago

I see what's going on here— sorry in advance for the confusion. Keys are not preprocessed by nvim_replace_termcodes, just on the off case someone really does want to bind the sequence < c - n > (and if you press that sequence in the the example mode you'll see it runs vim.notify).

To fix it, you can do this:

local M = {}

-- neovim >= 0.10
local k = vim.keycode

-- neovim < 0.10
local function k(s)
  return vim.api.nvim_replace_termcodes(s, true, true, true)
end

M.mode = {
  -- (the rest of your mode)

  -- ↓ call `k`
  [k'<c-n>'] = function()
    -- (the definition)
  end,

  -- ↓ call `k`
  [k'<m-n>'] = function()
    -- (the definition)
  end
}

-- (the rest of the module)

Alternatively, in insert mode if you press <C-v> and then another control sequence it will replace termcodes directly into the file (e.g. <C-v><Esc>)

mawkler commented 8 months ago

Ah, that makes sense. Thank you!