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

Swap operands #313

Open
znd4 opened this issue Oct 17, 2022 · 4 comments
Open

Swap operands #313

znd4 opened this issue Oct 17, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@znd4
Copy link

znd4 commented Oct 17, 2022

Is your feature request related to a problem? Please describe.
imagine you write out something like this

df["column_1"] - df["long_column_name"].a_couple().of_transformations()

But you realize that you actually want to swap these.

you've gotten okay at vim motions, so you F-D0P, but then realize you've still got a ways to go:

- df["long_column_name"].a_couple().of_transformations()df["column_1"] 

Thankfully your cursor's in a convenient place, so you can easily add a minus sign in the middle:

- df["long_column_name"].a_couple().of_transformations()-df["column_1"] 

You've still got to 0dw to clear up the leading - . Finally, you're in a state where your format-on-save hooks will clean things up:

df["long_column_name"].a_couple().of_transformations()-df["column_1"] 

Describe the solution you'd like
I'd like to be able to add an @operand mapping to my swap configuration, e.g.:

		swap = {
			enable = true,
			swap_next = {
				["<leader>o"] = "@operand",
			},
			swap_previous = {
				["<leader>O"] = "@operand",
			},
		},

Describe alternatives you've considered

I guess there might be a swapping-specific plugin that I could look for. If it doesn't exist, I suppose I could try to implement it, although I'd rather try to implement it in this project if it's possible (I don't know what's involved in creating a textobject for treesitter)

Additional context
nil

@znd4 znd4 added the enhancement New feature or request label Oct 17, 2022
@HungryJoe
Copy link

I love this idea, I've been wanting it for a while. Not sure I'll be able to implement it for every language we support, but I'll try 😃

@HungryJoe
Copy link

I've run into some unexpected behavior when swapping operands within chained associative operations.

The Problem

To see what I mean, consider the following expression:

1 + 2 + 3

Treesitter parses this into an AST with two binary_expression's. They look like:

binary_expression (1 + 2 + 3)
left: integer (1)
right: binary_expression (2 + 3)

and

binary_expression (2 + 3)
left: integer (2)
right: integer (3)

So there are two swaps that I can make, corresponding to the two binary_expression's:

  • 1 and 2 + 3
  • 2 and 3

However, as a user, I want to imagine this expression as a list of integer's joined by +, where any two adjacent elements can be swapped. In this case, the second possible swap stays the same, but the first one changes:

  • 1 and 2 <- different from above
  • 2 and 3

Proposed Solutions

  1. We ask that users change their expectations to match treesitter's.
    1. This would probably require people to use unnecessary parentheses so that they're on the same page as treesitter about what the operands are in a given situation.
    2. Example: 1 + (2 + 3)
  2. We make treesitter match my (and probably most users') expectations.
    1. This would require treesitter-textobjects to check that two nodes share a common ancestor that's a binary_expression, rather than just a common parent like it does now.
    2. This would be a large refactor as far as I can tell.
  3. We disable swapping, or the capturing of the operand textobject, for nested binary_expression's that all have the same operator.
    1. This would also be a large refactor to my knowledge.
  4. We don't implement this feature, disappointing users like @zdog234 and I.

@zdog234 @theHamsta, what do you make of these options?

@fmorroni
Copy link

Hi, any news on this feature?

@znd4
Copy link
Author

znd4 commented Jul 24, 2024

sorry @HungryJoe I missed you question :/

fwiw, I do agree that 2 is the most intuitive behavior. If it'd require a major refactor for this project, it seems like this might be a good opportunity for a dedicated plugin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants