Skip to content

fix(mini): disable mini.surround by default to preserve native S key behavior#1553

Open
SetsuikiHyoryu wants to merge 1 commit into
nvim-lua:masterfrom
SetsuikiHyoryu:hyoryu
Open

fix(mini): disable mini.surround by default to preserve native S key behavior#1553
SetsuikiHyoryu wants to merge 1 commit into
nvim-lua:masterfrom
SetsuikiHyoryu:hyoryu

Conversation

@SetsuikiHyoryu
Copy link
Copy Markdown

I have confirmed the source code of mini.surround (mini.nvim/lua/mini/surround.lua). Its setup function looks like this:

MiniSurround.setup = function(config)
  -- ...

  -- Setup config
  config = H.setup_config(config)

  -- Apply config
  H.apply_config(config)

  -- ...
end

If the user does not modify config, setup_config will use the default_config:

H.setup_config = function(config)
  H.check_type('config', config, 'table', true)
  config = vim.tbl_deep_extend('force', vim.deepcopy(H.default_config), config or {})

  -- ...

  return config
end

In default_config.mappings, multiple mappings start with the character s:

MiniSurround.config = {
  -- ...

  -- Module mappings. Use `''` (empty string) to disable one.
  mappings = {
    add = 'sa',          -- Add surrounding in Normal and Visual modes
    delete = 'sd',       -- Delete surrounding
    find = 'sf',         -- Find surrounding (to the right)
    find_left = 'sF',    -- Find surrounding (to the left)
    highlight = 'sh',    -- Highlight surrounding
    replace = 'sr',      -- Replace surrounding
    update_n_lines = 'sn', -- Update `n_lines`

    suffix_last = 'l',   -- Suffix to search with "prev" method
    suffix_next = 'n',   -- Suffix to search with "next" method
  },

  -- ...
}

H.default_config = vim.deepcopy(MiniSurround.config)

These mappings are then applied in the apply_config function called after setup:

H.apply_config = function(config)
  MiniSurround.config = config

  local expr_map = function(lhs, rhs, desc) H.map('n', lhs, rhs, { expr = true, desc = desc }) end
  local map = function(lhs, rhs, desc) H.map('n', lhs, rhs, { desc = desc }) end

  --stylua: ignore start
  -- Make regular mappings
  local m = config.mappings

  expr_map(m.add,     H.make_operator('add', nil, true), 'Add surrounding')
  expr_map(m.delete,  H.make_operator('delete'),         'Delete surrounding')
  expr_map(m.replace, H.make_operator('replace'),        'Replace surrounding')

  -- ...
end

The Neovim documentation on mappings (nvim/runtime/doc/map.txt) in the map-ambiguous section states:

“When two mappings start with the same sequence of characters, ... Vim is waiting for another character”:

    							*map-ambiguous*
When two mappings start with the same sequence of characters, they are
ambiguous.  Example: >
	:imap aa foo
	:imap aaa bar
When Vim has read "aa", it will need to get another character to be able to
decide if "aa" or "aaa" should be mapped.  This means that after typing "aa"
that mapping won't get expanded yet, Vim is waiting for another character.
If you type a space, then "foo" will get inserted, plus the space.  If you
type "a", then "bar" will get inserted.

I don't need the features this plugin provides, and it significantly disrupts the feel of my normal workflow.

I also see the #1328.

Therefore, I believe this plugin should be disabled by default, with a note explaining that its default mappings interfere with Neovim’s native S key behavior. Users should enable it consciously, understanding this limitation, or customize the mappings to avoid conflicts.

I believe beginner-friendly configurations should not include hidden side effects—especially those that override native key behaviors. If there's a strong reason this plugin must be enabled by default, please keep the warning comment to inform users.

@SetsuikiHyoryu SetsuikiHyoryu changed the title fix(mini): Disable mini.surround by default to preserve native S key behavior fix(mini): disable mini.surround by default to preserve native S key behavior May 19, 2025
@ro0gr
Copy link
Copy Markdown

ro0gr commented May 19, 2025

I don't remember the why, but I think that's why I ended up switching to "kylechui/nvim-surround". In my setup, it does not seem to have the issue you are describing.

If we do decide to drop the "mini.surround", I'd suggest installing mini.ai as a standalone package instead of pulling in the entire suite unnecessarily. Maybe it's just me, but I find it a bit annoying to see a bunch of unrelated mini updates when doing the "Lazy Sync", especially when I'm only using a single module from the collection.

@SetsuikiHyoryu
Copy link
Copy Markdown
Author

SetsuikiHyoryu commented May 19, 2025

I don't remember the why, but I think that's why I ended up switching to "kylechui/nvim-surround". In my setup, it does not seem to have the issue you are describing.

@ro0gr

Thank you for the introduction.

I took a look at the Usage section of nvim-surround:

https://github.com/kylechui/nvim-surround?tab=readme-ov-file#rocket-usage

It seems that by default, it uses keys like y, d, and c, which already have built-in timeout behavior in Neovim. The semantics of the operations are also intuitive and easy to understand.

I think this plugin takes a more reasonable approach.

@szechp
Copy link
Copy Markdown
Contributor

szechp commented May 20, 2025

I don't remember the why, but I think that's why I ended up switching to "kylechui/nvim-surround". In my setup, it does not seem to have the issue you are describing.

@ro0gr

Thank you for the introduction.

I took a look at the Usage section of nvim-surround:

https://github.com/kylechui/nvim-surround?tab=readme-ov-file#rocket-usage

It seems that by default, it uses keys like y, d, and c, which already have built-in timeout behavior in Neovim. The semantics of the operations are also intuitive and easy to understand.

I think this plugin takes a more reasonable approach.

we could do default mappings like the ones nvim-surround has? the proposal you make would mean installing another plugin?

i personally also like the lazyvim keybindings, its the same, but starts with g (example: gsa is for adding surroundings), which also fixes the doube-assignment with s.

@SetsuikiHyoryu
Copy link
Copy Markdown
Author

@szechp

we could do default mappings like the ones nvim-surround has? the proposal you make would mean installing another plugin?

i personally also like the lazyvim keybindings, its the same, but starts with g (example: gsa is for adding surroundings), which also fixes the doube-assignment with s.

If change the plugin, users who are already using mini.surround will encounter unfamiliar keybindings with other plugins, and the same goes for changing the key mappings. On the other hand, if we simply make the plugin disabled by default, those who actually use its functionality can just re-enable it, while those who never used it in the first place won't feel like they've lost any functionality—in fact, they might feel that the s key behaves more normally.

@echasnovski
Copy link
Copy Markdown
Contributor

Just a note: to preserve the s behavior (which is exactly equivalent to typing cl and is technically redundant) users can use config as in 'vim-surround'. The "prefix first" approach to surrounding mappings was chosen as it is more ergonomic for remembering and showing in "keybind helper" type of plugins (like 'which-key.nvim' and 'mini.clue').

@SetsuikiHyoryu
Copy link
Copy Markdown
Author

SetsuikiHyoryu commented May 23, 2026

Just a note: to preserve the s behavior (which is exactly equivalent to typing cl and is technically redundant) users can use config as in 'vim-surround'. The "prefix first" approach to surrounding mappings was chosen as it is more ergonomic for remembering and showing in "keybind helper" type of plugins (like 'which-key.nvim' and 'mini.clue').

Saying s is redundant just because cl does the same thing is a weak argument. That's like saying HJKL is redundant because Ctrl + HJKL exists—nobody looks at it that way. If you wanted a prefix-first design, you should have used the <leader> key. The real issue here isn't prefix-first design; it's that the plugin mini.surround is hijacking and polluting native Vim functionality that users rely on.

@echasnovski
Copy link
Copy Markdown
Contributor

That's like saying HJKL is redundant because Ctrl + HJKL exists—nobody looks at it that way.

Not quite. It's like saying that having both of them is redundant. With which 'kickstart.nvim' agrees.

Overriding built-in s functionality (that has very equivalent alternative) opens much more possibilities for new actions/operators: all start with s and work nicely with "keybind helper" plugins.

If you wanted a prefix-first design, you should have used the <leader> key.

Now plugins using <Leader> mapping for autocreated mappings is a bad idea. Those are usually reserved for user mappings.

it's that the plugin mini.surround is hijacking and polluting native Vim functionality that users rely on.

It can happen that users rely on many built-in things that don't make much sense for most other users. Like there are built-in gr and gO mappings, yet overriding or essentially hiding it them still makes overall experience better on average.

And again, if particular users feel strongly about s-prefix-based mappings, there is a documented way to use different key (as was mentioned).

@SetsuikiHyoryu
Copy link
Copy Markdown
Author

Not quite. It's like saying that having both of them is redundant. With which 'kickstart.nvim' agrees.

Obviously, kickstart.nvim considers Ctrl + HJKL to be redundant, not HJKL itself.

Now plugins using <Leader> mapping for autocreated mappings is a bad idea. Those are usually reserved for user mappings.

In my view, opting to use a plugin is, by definition, a pure form of user customization.

Like there are built-in gr and gO mappings, yet overriding or essentially hiding it them still makes overall experience better on average.

It's true that Neovim overrides the original gr behavior, but that is the default state out of the box for everyone, not a side effect introduced by a plugin.

While gr+ and gO are remapped here, they are meant to enhance the presentation/experience rather than alter the core functionality. The user's expectations and muscle memory are not significantly disrupted.

It can happen that users rely on many built-in things that don't make much sense for most other users.

Everyone has different muscle memory and habits. Making decisions on behalf of users like this feels overly arbitrary, especially without data to back it up.
Flip the argument around: the fact that upstream Neovim has shown no intention of changing the s behavior—doesn't that imply that changing what s does is actually the minority preference?

And again, if particular users feel strongly about s-prefix-based mappings, there is a documented way to use different key (as was mentioned).

This isn't an issue of whether a feature can be replaced; it's an issue of silent behavioral changes that conflict with standard expectations.
Everyone learns the same standard Vim keybindings, but not everyone shares the same customization habits.

My understanding of the kickstart.nvim philosophy is to achieve maximum editing convenience with a minimal footprint of plugins.
Most of its mappings that override native keys only enhance what those native keys were already doing.
Completely altering a key's original functionality like this feels too radical.
It begs a very straightforward question: if we are going this far, why not just use other highly-modded distributions, or even a different editor entirely?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants