rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

Make expand-selection smarter

Open eulerdisk opened this issue 2 years ago • 5 comments

Suppose we have this: (|...| delimits the selection)

let r = test(0, 2).saturating_|a|dd(3).saturating_sub(4);

This is what RA expand selection currently does:

let r = test(1, 2).|saturating_add|(3).saturating_sub(4); let r = |test(1, 2).saturating_add|(3).saturating_sub(4); let r = |test(1, 2).saturating_add(3)|.saturating_sub(4); let r = |test(1, 2).saturating_add(3).saturating_sub|(4); let r = |test(1, 2).saturating_add(3).saturating_sub(4)|;

That's not very useful. This is what I would expect:

let r = test(1, 2).|saturating_add|(3).saturating_sub(4); let r = test(1, 2).|saturating_add(3)|.saturating_sub(4); let r = test(1, 2).|saturating_add(3).saturating_sub|(4); let r = test(1, 2).|saturating_add(3).saturating_sub(4)|; let r = test|(1, 2).saturating_add(3).saturating_sub(4)|;

// Or let r = test(1, 2).|saturating_add|(3).saturating_sub(4); let r = test(1, 2).|saturating_add(3)|.saturating_sub(4); let r = test(1, 2).|saturating_add(3).saturating_sub(4)|; let r = |test(1, 2).saturating_add(3).saturating_sub(4)|;

RA (as many TreeSitter based editors) follows strictly the grammar structure (left-associativity in the example above) which is easy to implement but often expands the selection the "wrong" way. IntelliJ does a better job expanding the section for Kotlin, it's very smart and in the example above it goes to the right. (If I recall correctly)

As of today this kind of "blind" expand-selection is of little use to me, I wonder what other people here think.

eulerdisk avatar Sep 10 '22 15:09 eulerdisk

Hmm... I often use expand selection when I need for example to wrap the expression in parentheses, so I want a valid expression to be selected.

ChayimFriedman2 avatar Sep 11 '22 08:09 ChayimFriedman2

Ye, so this is tricky. I can absolutely see situations where you want either of these behaviors to happen. Expanding the selection to proper expansions is preferred if you want to, well, deal with expressions and do something with it (as Chayim stated). But as outlined in the issue, there are reasons where you'd like to handle method calls by only selecting the actual calling part (that is without the receiver) which becomes useful if you want to copy and paste for example ...

Neither of these is particularly smarter or more useful than the other, they both come with trade offs.

Veykril avatar Sep 11 '22 10:09 Veykril

Hmm... I often use expand selection when I need for example to wrap the expression in parentheses, so I want a valid expression to be selected.

Never thought about that, I think it's not a very common use case. In Rust is very common to have method chains like the one above (iterators, futures, builders ...). If you change a method in the middle of the chain then most of the time the return type will change and so it's obvious you have to change all the right part of the chain.

Moreover, as shown in the example above, after the first expansion which select the middle method name, it expands to the left method and only after that it expands to the middle method argument list. So you cannot isolate the middle method to change only that. That's super frustrating and makes no sense.

It would very nice to have a configurable option to change this behaviour.

eulerdisk avatar Sep 11 '22 10:09 eulerdisk

Yeah, I’ve also felt since forever that for method chains we should just lie :) I wonder if the Kotlin’s feature is new? I remember being annoyed with it in Kotlin as well.

matklad avatar Sep 12 '22 22:09 matklad

Yeah, I’ve also felt since forever that for method chains we should just lie :) I wonder if the Kotlin’s feature is new? I remember being annoyed with it in Kotlin as well.

Actually I was wrong, I misremembered. Event IntelliJ goes to the left but other than that still provides a much better experience. I opened the same discussion here a few days ago to point out that tree-sitter based expansion has the same usability problems. jcornaz poited out I misremebered, but He provided some better examples on why IntelliJ implementation is much better anyway.

eulerdisk avatar Sep 13 '22 08:09 eulerdisk