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

Add tree-sitter based textobject for pairings and fields #3006

Closed
EpocSquadron opened this issue Jul 8, 2022 · 1 comment · Fixed by #8150
Closed

Add tree-sitter based textobject for pairings and fields #3006

EpocSquadron opened this issue Jul 8, 2022 · 1 comment · Fixed by #8150
Labels
A-tree-sitter Area: Tree-sitter C-enhancement Category: Improvements

Comments

@EpocSquadron
Copy link
Contributor

Motivation

Currently we support tree-sitter based textobjects based on a few common concepts to general programming languages:

c - Classes, structs, interfaces, etc
f - Functions, methods, closures, etc
o - Comments
a - Function/method/closure call arguments, function/method/closure definition parameters, etc

This last one is interesting, in that there are adjacent concepts such as elements of arrays, key value pairs in maps/structs/objects, and the like. Since we added these textobjects, I have found myself occasionally trying to use mia to match an array element, since it also occurs in a delimited list inside a matching pair. I think for these instances we should introduce two new textobjects:

e - Fields of enums, elements of lists, etc
k - Key-value pairs, fields of structs, properties of classes/objects, named parameters with their parameter, etc

Example

In the following JSON document:

{
  "devMode": true,
  "host": "localhost:3000",
  "protocols": [ "http", "https", "sftp"]
}

mak while inside the string localhost:3000 would match the entire key-value pair up to and including the comma. Using mik would make two selections, one for the key and one for the value.

mie while inside the string https would be the same as ma" in this case (but would be superior to it in the case the string contained escaped quotes). mae would select all of "https", including the comma.

]k while on the devMode line would move to and select the host key-value pair as a single selection, including the comma (unimpaired textobject jumps default in general to the around capture, so this is consistent).

[e while https is selected would result in "http", being the selection.

The unimpaired mode functionality will be more desireable once #1999 is resolved and we can combine it with v.

Besides making tree-sitter powered textobjects available to configuration languages like the above, they could also generally apply to lists, arrays, maps, struct fields, and more that also occur frequently in general programming languages.

Alternatives

Don't Make Multiple Selections with inside

This behaviour (as described with mik in the above example), doesn't have any precedent in helix today. While I believe it is interesting, we could keep it simple and default to simply not including the comma in the selection with the inside variant. This makes things less interesting both now and in the future, as I can imagine a day when we add tree-sitter textobjects to the functionality of s, where being able to split a selection into it's keys and values could be helpful.

Combine Textobjects

One might consider folding the proposed functionality of e with the existing a as they will look and act very similar in many cases. The only difficulty here is in generalizing the mnemonic so that it makes sense for both use cases, or making it clear from the autoinfo how a user should expect it to behave. I think this might be enough of a usability issue to justify having it be a separate bind, especially considering it involves writing the same amount of queries, just using different capture names.

Both

If we are simplifying the inside action for key-value pairs, then the distinction between it and regular e gets much less clear, and so it may be worth folding k also into a, again at the risk of further burdening the end user to know how it will act in a multitide of contexts a priori.

@EpocSquadron
Copy link
Contributor Author

EpocSquadron commented Sep 3, 2023

I've started working on a PR for this (already linked) and in the course of working on it figured it would be simpler not to split the concept of key-value pairs from elements of lists, as they are too often easily interchanged in thought. I've also abandoned the idea of giving multiple selections when using the inside variant, instead opting to allow selecting of either the key or value when inside is defined based on the location of the current selection. This keeps things simpler to use, I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tree-sitter Area: Tree-sitter C-enhancement Category: Improvements
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants