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

vim: Add any brackets to support motions like ab and ib to work with any type of brackets #23679

Merged
merged 1 commit into from
Jan 29, 2025

Conversation

oca159
Copy link
Contributor

@oca159 oca159 commented Jan 26, 2025

Add AnyBrackets text object for Vim mode

Overview

This PR introduces a new text object AnyBrackets that allows operations on the closest matching pair of brackets, regardless of the bracket type. This enhances the editing experience by reducing the need to identify specific bracket types before performing text operations.

By default, this feature is NOT mapped to any key in vim.json. However, it can be enabled manually, and the recommended key for mapping is b:

If you want to add it to your zed keymap config you need to add the following config:

{
	"context": "vim_operator == a || vim_operator == i || vim_operator == cs",
	"bindings": {
		"b": "vim::AnyBrackets"
	}
}

Features

  • New text object that works with parentheses (), square brackets [], curly braces {}, they are also know as round brackets, square brackets and curly brackets in english.
  • Automatically finds the closest matching pair of any bracket type
  • Works with all standard Vim operators (delete, change, yank)
  • Supports both "inside" and "around" variants (i and a)

Usage Examples

# Delete inside the closest brackets
di(  # Works on (), [] or {} depending on which is closest

# Change around the closest brackets
ca[  # Works on (), [] or {}  depending on which is closest

# Visual select inside the closest brackets
vi{  # Works on (), [] or {}  depending on which is closest

References:

Important Notes

This PR also fixes a bug with nested quotes on AnyQuotes, now it works fine with any type of quotes or brackets.
Please take a look at the new tests to understand the expected behavior.

Release Notes:

  • vim: Add ab/ib "AnyBrackets" text objects that are the smallest of a(, a[ or a{ or i(, i[ or i{
  • vim: Fix aq/iq "AnyQuotes" text objects when they are nested

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Jan 26, 2025
@oca159 oca159 changed the title feat: add any brackets to support motions like ab and ib to work with any type of brackets vim feat: add any brackets to support motions like ab and ib to work with any type of brackets Jan 26, 2025
@oca159 oca159 changed the title vim feat: add any brackets to support motions like ab and ib to work with any type of brackets vim: add any brackets to support motions like ab and ib to work with any type of brackets Jan 26, 2025
@oca159 oca159 force-pushed the oca159/add-any-brackets branch 2 times, most recently from 5d26a3c to 81e6b4a Compare January 26, 2025 21:42
@maxdeviant maxdeviant changed the title vim: add any brackets to support motions like ab and ib to work with any type of brackets vim: Add any brackets to support motions like ab and ib to work with any type of brackets Jan 27, 2025
@oca159 oca159 force-pushed the oca159/add-any-brackets branch 2 times, most recently from 1aff51c to 34a683b Compare January 29, 2025 02:54
@oca159 oca159 force-pushed the oca159/add-any-brackets branch from 34a683b to 68f8b44 Compare January 29, 2025 03:03
@oca159
Copy link
Contributor Author

oca159 commented Jan 29, 2025

@ConradIrwin I identified that AnyQuotes Text object was not working fine with nested Quotes, This PR also fixes that, i added more test with new cases to make sure it works fine now.

@ConradIrwin ConradIrwin merged commit 9e31b10 into zed-industries:main Jan 29, 2025
12 checks passed
@ConradIrwin
Copy link
Member

Great, thanks for this!

Should we override b or not? On the one hand it's a vim incompatiblity which brings people up in arms, on the other it's pretty clearly better...

Another potential enhancement would be supporting any bracket listed by the language (e.g. rust also has |...| as a bracket range), but the downside there is we treat brackets and quotes the same way right now.

@oca159
Copy link
Contributor Author

oca159 commented Jan 29, 2025

@ConradIrwin For now, I think it makes sense to enable it manually, as it could be controversial for Vim purists. That said, I believe it's a clear improvement over the default behavior as it is super useful, specially if you use small keyboards with weird shortcuts to get the brackets symbols.

I'm also unsure if this should support other types of brackets, like the ones you mentioned for Rust or angle brackets (<...>). Let me know your thoughts, currently, the PR only supports brackets of the same type than the original plugin.

@ConradIrwin
Copy link
Member

Angle brackets seems good, not sure about "|" - One other approach would be to use the tree-sitter based enclosing_bracket_ranges and then filter out quotes (", ', `); but I appreciate that's probably more work than you signed up for.

@oca159
Copy link
Contributor Author

oca159 commented Jan 29, 2025

I'll add support for angle brackets tomorrow, it's getting late for me here in Mexico, haha. I'm also curious about the approach you're suggesting, so I'll take a look and see if I can refactor the code to improve it with Tree-sitter. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed The user has signed the Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants