-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Improving refactoring discoverability and UX #34930
Comments
My first question is, for cases where there is no selection, how do you decide how large of a subexpression (if not the whole thing!) to take? For example say I trigger the refactor on an expression within a function call, do we take only that argument, or take the entire function call? It seems like this question isn’t always going to be straightforward and could get pretty hairy. And people will necessarily have different opinions on what the right thing to do is... |
We don't have to be perfect. The idea is that the more fuzzy expansion would show additional potential refactorings, not prevent using refactorings as they work today. The main risk is that we don't want to show a bunch of not very help refactorings everywhere all the time—i.e. have the VS Code lightbulb always show up—which I why I propose that we are less aggressive expanding the selection for implicit refactoring requests vs explicit ones |
A couple of thoughts, I played a little with this when trying to write automated refactorings for TS https://github.com/greyepoxy/typescript-refactoring-plugin/blob/master/test/refactorings/tryGetTargetExpression.tests.ts#L63. There is definitely some corner cases but as long as your consistent it should be fine (although I cannot say I was super consistent in my linked example). |
I have split out two concrete proposals based on the ideas brought up:
|
@jessetrinity to address the selection range issues described here. |
There are some cases for which I think it makes sense to offer an extract refactor for a cursor location. function func1(){
function func2(a: number){
return a;
}
} is another case where we only offer the extract refactor for an exact selection function func2(a: number){
return a;
} Assuming we change this, we wouldn't want to offer a refactor if the cursor (no selection) is anywhere in the function body (due to too many refactors as already mentioned), but we may want to offer an implicit refactor if the cursor is, say, within the If there is an actual selection, we can be more liberal and offer a refactor if the start position of the selection is anywhere in If I request refactors using |
@jessetrinity That behavior sounds good to me. I've also opened #35096 about providing TS with information about why refactorings were requested. If you are experimenting with the behavior, I can hook up VS Code to send along a refactor trigger reason |
That would be handy. I think @PranavSenthilnathan is already working on adding the trigger reason on our end (does this require more than just adding a I listed my thoughts on other cases in #37895. They seem pretty straightforward but I noticed there might be some performance concerns with offering too many refactors while going through them. |
Closing as completed by #41975 |
Problem
Consider the following code:
TypeScript currently only returns refactorings for
extract function
andextract constant
if you exactly select the range of the given expression. To extracta + 20 * 10
to a constant for example, I have to fully selecta + 20 * 10
.There are a few limitations with this approach:
On the VS Code side we'd like to improve the discoverability and general UX around refactorings, and believe we need some new TS server work to make this happen.
Ideas
This issue in intended to be high level discussion about improving refactorings. We can split out specific proposals into their own issues.
As background, VS Code has two ways that refactorings can be requested:
Here are some initial ideas about improving both cases
Be less strict about selection range for automatic refactorings
To example cases:
20 * 1
in the example, automatically expand the refactor target to the subexpression20 * 10
a + 20 * 10;
with the trailing semicolon, automatically shrink the refactor to just the target expressiona + 20 * 10
.For basic cases like the above, it may make sense to always perform some basic massaging of the selection. This would mean that these refactorings would show in VS Code's automatic lightbulb
More aggressive expanding of selections for explicit refactorings
If I explicitly request a refactoring such as
extract constant
, we could always try to expand the selection to the minimal extractable expression and possibly show multiple extract constant refactorings if multiple parent expressions could all be extracted.In the example code, if I simply have the cursor before
a
in the expressiona + 20 * 10
(with no selection), when I try to trigger extract constant then we could show refactorings for:extract expression 'a + 20 * 10' to constant
Feedback on why an explicitly requested refactoring is not available
When I explicitly request refactorings on a selection that cannot be refactored, we should show a message about why the refactoring is not possible.
The text was updated successfully, but these errors were encountered: