Skip to content

feat: remap treesitter incremental selection not to collide with mini.ai#1992

Open
nathanzeng wants to merge 1 commit intonvim-lua:masterfrom
nathanzeng:treesitter-incremental
Open

feat: remap treesitter incremental selection not to collide with mini.ai#1992
nathanzeng wants to merge 1 commit intonvim-lua:masterfrom
nathanzeng:treesitter-incremental

Conversation

@nathanzeng
Copy link
Copy Markdown
Contributor

@nathanzeng nathanzeng commented Apr 14, 2026

Treesitter incremental selection is pretty cool, let's make sure people have it right out the gate.

This PR requires neovim 0.12, and addresses an issue in #1971

These mappings are yoinked from core here

@ro0gr
Copy link
Copy Markdown

ro0gr commented Apr 14, 2026

Why is it called "remap"? I only see two new mappings being added. How does it compare to neovim's new builtin v_an and v_in mappings for incremental selection? Is it an attempt to recreate those two?

Copy link
Copy Markdown
Collaborator

@oriori1703 oriori1703 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great change, though I'm not sure about +/- for the keybinds.
I don't like the shift asymmetry between them (at least when using normal keyboards) - though they are easy to remember.

what do you think about aa/ii ?
ofc feel free to disagree. I will not force my taste in keybinds on everyone :)

Comment thread init.lua
Comment on lines +924 to +942

-- Treesitter incremental selection, see `:help treesitter-incremental-selection`
-- Note: the default keymaps `an` and `in` collide with mini.ai, so we remap them below
-- Try putting your cursor in one of the lines below and typing `v+` (then continue to type `+` or `-`)
vim.keymap.set({ 'x', 'o' }, '+', function()
if vim.treesitter.get_parser(nil, nil, { error = false }) then
require('vim.treesitter._select').select_parent(vim.v.count1)
else
vim.lsp.buf.selection_range(vim.v.count1)
end
end, { desc = 'Select parent (outer) node' })

vim.keymap.set({ 'x', 'o' }, '-', function()
if vim.treesitter.get_parser(nil, nil, { error = false }) then
require('vim.treesitter._select').select_child(vim.v.count1)
else
vim.lsp.buf.selection_range(-vim.v.count1)
end
end, { desc = 'Select child (inner) node' })
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this would fit better in the mini.nvim package spec?
That's the source of the conflict, and incremental selection is not exclusive to treesitter (it's also an lsp feature).

WDYT?

@nathanzeng
Copy link
Copy Markdown
Contributor Author

I'm glad you commented on the keybinds. I use <up> and <down> in my personal config for this, but wasn't sure if that was going to be invasive for people used to using arrows for navigation. What do you think about that?

aa and ii seems good to me, it resembles the defaults. We could also do oo and ii to match [o]uter node and [i]nner node.

@nathanzeng
Copy link
Copy Markdown
Contributor Author

nathanzeng commented Apr 14, 2026

I feel conflicted about putting it in the mini package spec. It is true that the conflict is with mini, but the name of the relevant help doc is treesitter here. Also, we are exposing some lower level treesitter code here. If they were to make changes upstream in core that affects this code, it will almost certainly be labeled as treesitter so I do feel like there is reason to keep this in treesitter.

@ro0gr
Copy link
Copy Markdown

ro0gr commented Apr 14, 2026

TLDR: Should mini.ai be removed to avoid conflicts with Neovim defaults?

Personally, I don't use mini.ai(can't recall why), so I'm not entirely sure what the exact issue is. However, it seems that mini.ai overrides a built-in Neovim keybind.

For a project like kickstart.nvim, I believe Neovim defaults should be respected as much as possible to reduce the learning curve for newcomers, maintain clarity, and avoid unnecessary workarounds. Also, we're partially replicating the core implementation and relying on private APIs(_select).

So the question remains: Is it worth working around a plugin, or should we simply remove it and rely on defaults instead? I realize this is a controversial suggestion, but addressing the issue from the mini.ai side feels more approachable to me.

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.

3 participants