Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: can not overwrite mini.surround keybinds #172

Closed
3 tasks done
pprotas opened this issue Feb 4, 2023 · 15 comments · Fixed by #186
Closed
3 tasks done

bug: can not overwrite mini.surround keybinds #172

pprotas opened this issue Feb 4, 2023 · 15 comments · Fixed by #186
Labels
bug Something isn't working

Comments

@pprotas
Copy link

pprotas commented Feb 4, 2023

Did you check docs and existing issues?

  • I have read all the LazyVim docs
  • I have searched the existing issues of LazyVim
  • I have searched the exsiting issues of plugins related to this issue

Neovim version (nvim -v)

v0.9.0-dev-2057+g8376486e8-dirty

Operating system/version

MacOS 13.2

Describe the bug

You can not overwrite the keybinds for surround objects with mini.surround. Here is an example config:

return {
  {
    "echasnovski/mini.surround",
    opts = {
      mappings = {
        add = "sa",
        delete = "sd",
        find = "sf",
        find_left = "sF",
        highlight = "sh",
        replace = "sr",
        update_n_lines = "sn",
      },
    },
  },
}

This doesn't work, see how the keybinds look like in Telescope:

image

I tried replicating the full spec from the docs, but now I have duplicate keybinds:

return {
  {
    "echasnovski/mini.surround",
    keys = function(plugin, keys)
      local opts = require("lazy.core.plugin").values(plugin, "opts", false)
      local mappings = {
        { opts.mappings.add, desc = "Add surrounding", mode = { "n", "v" } },
        { opts.mappings.delete, desc = "Delete surrounding" },
        { opts.mappings.find, desc = "Find right surrounding" },
        { opts.mappings.find_left, desc = "Find left surrounding" },
        { opts.mappings.highlight, desc = "Highlight surrounding" },
        { opts.mappings.replace, desc = "Replace surrounding" },
        { opts.mappings.update_n_lines, desc = "Update `MiniSurround.config.n_lines`" },
      }
      return vim.list_extend(mappings, keys)
    end,
    opts = {
      mappings = {
        add = "sa",
        delete = "sd",
        find = "sf",
        find_left = "sF",
        highlight = "sh",
        replace = "sr",
        update_n_lines = "sn",
      },
    },
  },
}

image

Flit and Leap are both disabled.

Steps To Reproduce

  1. Use one of the example configs above
  2. Notice that the shortcuts aren't as configured or there are duplicate shortcuts

Expected Behavior

I can use s instead of gz for surrounding

Repro

-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")
-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  "folke/tokyonight.nvim",
  "folke/LazyVim",
  -- add any other plugins here
}
require("lazy").setup(plugins, {
  root = root .. "/plugins",
})

vim.cmd.colorscheme("tokyonight")
-- add anything else here
@pprotas pprotas added the bug Something isn't working label Feb 4, 2023
@dpetka2001
Copy link
Contributor

dpetka2001 commented Feb 4, 2023

s is the default key for Neovim to delete characters and enter into insert mode to enter new characters for
the deleted ones. I don't think this is specifically a LazyVim behavior. You should probably try to use a <leader>
key in your keymappings or some other key that doesn't conflict with the default Neovim mappings.
leap of course overrides this keymap binding but I think you would have to do it programmatically if you wanted to
override this Neovim binding. It would be easier to add something else as your keybinding.

@pprotas
Copy link
Author

pprotas commented Feb 4, 2023

These are the default keybinds for mini.surround. Just because vim uses s by default shouldn't mean that I can't re-map it.

Also other keymaps don't work either. I can not change the keymaps at all, I just used s as an example.

For example, the following config doesn't work either:

return {
  {
    "echasnovski/mini.surround",
    opts = {
      mappings = {
        add = "<leader>ma",
        delete = "<leader>md",
        find = "<leader>mf",
        find_left = "<leader>mF",
        highlight = "<leader>mh",
        replace = "<leader>mr",
        update_n_lines = "<leader>mn",
      },
    },
  },
}

@alezunino
Copy link

alezunino commented Feb 4, 2023

I redefined mini.surround keymaps using this:

-- disable leap to avoid conflict with mini.aling and mini.jump
 {
   "ggandor/leap.nvim",
   enabled = false,
 },

 {
   "echasnovski/mini.surround",
   event = "BufRead",
   keys = function(_, keys)
     local mappings = {
       { "sa", desc = "Add surrounding", mode = { "n", "v" } },
       { "sd", desc = "Delete surrounding" },
       { "sf", desc = "Find right surrounding" },
       { "sF", desc = "Find left surrounding" },
       { "sh", desc = "Highlight surrounding" },
       { "sr", desc = "Replace surrounding" },
     }
     return vim.list_extend(mappings, keys)
   end,
   config = function(_, _)
     require("mini.surround").setup({})
   end,
 },

@dpetka2001
Copy link
Contributor

dpetka2001 commented Feb 4, 2023

{
    "echasnovski/mini.surround",
    keys = function(plugin, keys)
      -- Populate the keys based on the user's options
      local opts = require("lazy.core.plugin").values(plugin, "opts", false)
      local mappings = {
        { opts.mappings.add, desc = "Add surrounding", mode = { "n", "v" } },
        { opts.mappings.delete, desc = "Delete surrounding" },
        { opts.mappings.find, desc = "Find right surrounding" },
        { opts.mappings.find_left, desc = "Find left surrounding" },
        { opts.mappings.highlight, desc = "Highlight surrounding" },
        { opts.mappings.replace, desc = "Replace surrounding" },
        { opts.mappings.update_n_lines, desc = "Update `MiniSurround.config.n_lines`" },
      }
      return vim.list_extend(mappings, keys)
    end,
    opts = {
      mappings = {
        add = "gza", -- Add surrounding in Normal and Visual modes
        delete = "gzd", -- Delete surrounding
        find = "gzf", -- Find surrounding (to the right)
        find_left = "gzF", -- Find surrounding (to the left)
        highlight = "gzh", -- Highlight surrounding
        replace = "gzr", -- Replace surrounding
        update_n_lines = "gzn", -- Update `n_lines`
      },
    },
    config = function(_, opts)
      -- use gz mappings instead of s to prevent conflict with leap
      require("mini.surround").setup(opts)
    end,
  },

If you use this config and just replace the mappings with for example <leader>ma> as you wrote in
your previous post it will work. Just tried it. Of course you would have to add a corresponding which-key
keymap for <leader>m so that it could show in the which-key pop-up menu.

Edit: the previous post from @alezunino is much more elegant so you should prefer his solution.

@pprotas
Copy link
Author

pprotas commented Feb 4, 2023

@dpetka2001 This works but I already mentioned this in my original post. This results in duplicate keybindings, so it is not a good solution.

@alezunino's solution works! Thanks

In my opinion this should still be considered a bug, since you have to go out of your way to get this working properly. It's good there is a workaround though!

@dpetka2001
Copy link
Contributor

@pprotas It doesn't result in duplicate keybindings for me. I only have the <leader>m keybindings which replaced
the original ones.

I don't see how this could be considered a bug. You have to customize the configuration to apply for your
preferences. Not everyone likes the default keybindings, but there are others that don't mind. Since you are given
the possibility to tinker the default configuration according to your preferences, how is this a bug?

@pprotas
Copy link
Author

pprotas commented Feb 4, 2023

Interesting, I have duplicate keybinds with the configuration you provided:
image

@dpetka2001
Copy link
Contributor

Yes you are correct!! I must have done something wrong in my previous test with the config provided. Just tested
again and I get duplicate entries as well. Sorry for what I stated in my previous comment.

@dpetka2001
Copy link
Contributor

dpetka2001 commented Feb 4, 2023

Yes, that is because we use vim.list_extend, which appends the new values to the already constructed list and we
get dupplicate keybindings. If you use instead vim.tbl_deep_extend you shouldn't get any more duplicates. This applies
to the other more elegant solution as well. I tried it and it seems to work.

Edit: just use return vim.tbl_deep_extend("keep", mappings, keys) instead of return vim.list_extend and you should be fine.

@pprotas
Copy link
Author

pprotas commented Feb 4, 2023

Hmm I am back to sew some chaos in this thread... I was too hasty in saying that @alezunino's solution worked. It does add the mappings to my WhichKey, but the keys don't actually don't do anything.

I am now using @dpetka2001's solution with return vim.tbl_deep_extend("keep", mappings, keys), that seems to fix both of my problems. So no more duplicate keybinds and the keys are correctly remapped.

@alezunino
Copy link

My solution does work. I use it on several computers. Besides, I am addicted to "sa" "se" and "sd" keys 😜. Just copy the code I posted before, including: event = "BufRead"

@dpetka2001
Copy link
Contributor

Could you plz elaborate on what event = "BufRead" does exactly. I tried your solution as well and indeed it works.
But then when i went to remap the keys to <leader>ma> your keys would still show up in Telescope search keymaps.
When I commented out event = "BufRead", then they stopped showing. Just LazyVim keep some kind of state for the
buffer and it still shows your keymaps when event = "BufRead" is not commented? Really curious why this is happening.

@pprotas
Copy link
Author

pprotas commented Feb 5, 2023

I made a PR to fix the bug, see #177.

@alezunino
Copy link

Could you plz elaborate on what event = "BufRead" does exactly. I tried your solution as well and indeed it works. But then when i went to remap the keys to <leader>ma> your keys would still show up in Telescope search keymaps. When I commented out event = "BufRead", then they stopped showing. Just LazyVim keep some kind of state for the buffer and it still shows your keymaps when event = "BufRead" is not commented? Really curious why this is happening.

The "BufRead" event is triggered when starting to edit a new buffer. On the other hand, the original config of mini.surround will load it "VeryLazy"ly, which is AFAIK after than BufRead. In other words, BufRead in my config seems to take precedence over the one defined in LazyVim. Not 100% sure about this...

Anyway, in my code the keybindings defined by mini.surround are not modified (meaning that sa, sd, etc... are defined in mini). To modify the keys you should use something like this:
{ "echasnovski/mini.surround", event = "BufRead", -- keys = function(_, _) end, keys = function(_, keys) local mappings = { { "<leader>ma", desc = "Add surrounding", mode = { "n", "v" } }, { "<leader>md", desc = "Delete surrounding" }, { "<leader>mf", desc = "Find right surrounding" }, { "<leader>mF", desc = "Find left surrounding" }, { "<leader>mh", desc = "Highlight surrounding" }, { "<leader>mr", desc = "Replace surrounding" }, } return vim.list_extend(mappings, keys) end, opts = { mappings = { add = "<leader>ma", -- Add surrounding in Normal and Visual modes delete = "<leader>md", -- Delete surrounding find = "<leader>mf", -- Find surrounding (to the right) find_left = "<leader>mF", -- Find surrounding (to the left) highlight = "<leader>mh", -- Highlight surrounding replace = "<leader>mr", -- Replace surrounding update_n_lines = "<leader>mn", -- Updaten_lines}, }, config = function(_, opts) require("mini.surround").setup(opts) end, }

the difference here is that we are passing the "opts" parameter to mini, where "opts" contain the keys.

@folke folke closed this as completed in 1823236 Feb 6, 2023
@folke
Copy link
Collaborator

folke commented Feb 6, 2023

This should now be fixed. You can just change the opts and the keys will be updated as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants