Vscode: Expand selection functionality issues

Created on 30 Mar 2016  Â·  46Comments  Â·  Source: microsoft/vscode

  • VSCode Version: 0.10.11
  • OS Version: Windows 10

Steps to Reproduce:

  1. Create statement which assigns some value to nested property like scope.vm.renderSettings = {};
  2. Put cursor into renderSettings
  3. Execute command editor.action.smartSelect.grow

Expected behavior:
renderSettings part would be selected
exp

Current behavior:
the whole left part of statement selected with tabs.
2

Also would be nice to see the fix with smart grow, when editor.action.smartSelect.grow executed in series.

editor-commands feature-request smart-select

Most helpful comment

this is how it should work

Users shall be able to successively select expanding logical blocks of code so that you can easily select any expression in the code by placing the caret somewhere inside it and pressing a shortcut.

Extends selection to the next containing node (for example, an expression, a paired tag, an entire conditional block, a method body, a class, a group of vararg arguments, etc.)

In plain text, with the caret anywhere in a word, the selection would extend to to the word, the sentence, the paragraph

Shrink does the opposite.

Examples

vs129006090-f158a6be-7b23-11e7-9b52-f67ce1d57c4b
vs229006092-f2e4302a-7b23-11e7-95ee-38ab89ac6f7a
vs329006095-f4c3089e-7b23-11e7-8c08-661b1362d54f

All 46 comments

I was too optimistic planning this for April. The current implementation is based of token/scope information in TM grammars. The issue is that each grammar does it different, like scope from above where it seems to include the leading whitespace. We redo this with a implementation that doesn't rely on token information

@rozzzly, @TobiaszCudnik Since I am not as familiar with the optimal solution can you guys help out with 'how it should work?'. I guess, selector word, line?, bracket/paran-block? ...

I like the way it's implemented in https://atom.io/packages/expand-region or at Jetbrain's products like Webstorm

Inner-camelCase expansion would be cool.
_so let's pretend _ is the cursor, and [ ] denotes the selected region._

ren_derSettings -> [render]Settings -> [renderSettings]

Would it be best to have people just list out a bunch of examples, using something like the markup I just used to show the behaviour desired? Then, from those. distil the logic in regards to he AST? There's a lot of edgecases I would think, that might be easier

@jrieken The simplest solution I see is to combine the AST and word separators.

Case-sensitive boundaries could be implemented as a word separator as well. In IntelliJ it works also for CTRL+Left/Right jumps, when active.

I really count for this feature, as it saves a lot of time when moving code around.

Thanks all for the input. Note that we do not have access to the AST or any other form of syntax tree. Even token information isn't working well enough. So it's unfortunately entirely word based

I think improving smartSelect is a great plan. I agree with the suggestions for making smartSelect even more useful. Might I suggest that #11458 is solving for a different problem? I get the feeling that mixing its requirements in with smartSelect could further bog down smartSelect.

In my mind, smartSelect is about being able to quickly select _something_ nearby the cursor. Whereas #11458 is about quickly selecting _everything_ within a bounding context.

If smartSelect were enhanced to achieve this type of eventual selection, it would still have the downside of repeated keystrokes to achieve the "select stuff inside here" functionality.

So they feel similar because the end result is "intelligent selection" but I suspect in-the-end they would function better as separate features. Thanks for listening. :)

The value of optimal Expand Select and Shrink Select commands is high in my opinion. I used to use ReSharper in Visual Studio and their implementation was about perfect. When I use this command, I'm usually looking to copy, replace, or delete certain code.
As an example, if my selection is inside the name of a function definition ([] denotes my cursor location or selection)...

myFun[]ction(){
  something.do();
}

...it should snap first to the function name...

[myFunction](){
  something.do();
}

...and next to the function name with the parentheses...

[myFunction()]{
  something.do();
}

...and next to the entire function block...

[myFunction(){
  something.do();
}]

If my selection is inside the function, however, I would expect the progression to look something like...

myFunction(){
  so[]mething.do();
}
myFunction(){
  [something].do();
}
myFunction(){
  [something.do()];
}
myFunction(){
  [something.do();]
}
myFunction(){
[  something.do();
]}
myFunction()[{
  something.do();
}]
[myFunction(){
  something.do();
}]

Note that my suggestion progression has rather small steps. For instance, after selecting the expression [something.do()]; it then selects the statement [something.do();] (including the semicolon). And, in the next step, it selects the entire line. If there were multiple lines in that block, then I would suggest yet another step where it selects the entire _contents_ of the block (before selecting the entire block including the curly braces). I prefer this more granular stepping because it's not an inconvenience to hit the left/right arrows to grow/shrink and get exactly what you want.

Just wanted to add that it would be great for this to work with python code, where code blocks aren't delineated by brackets or parentheses, but tabs (currently, once it you expand the selection beyond the current block in a python file, all of the code is selected). I'll second that I'd like to see it work as in the Jetbrains products. In PyCharm it works great with both python and javascript files.
I have no problem with the way it currently works in JS files with VSCode.

sco|pe.vm.renderSetting = {};, there | is cursor and [] is highlighted selection:
So, the first execution of command editor.action.smartSelect.grow produces:
[scope].vm.renderSetting = {};
The second one:
[scope.vm].renderSetting = {};
The third one:
[scope.vm.renderSetting] = {};
Then fourth one:
[scope.vm.renderSetting = {};]
Then fifth one(selects the whole line):
[ scope.vm.renderSetting] = {};]

Is it possible to get an update on this?

I found this functionality really limited in VS Code, it is not as fine grained as I'd wish.
For Python, after selecting a line, it selects the whole buffer, instead of current block as I'd wish. For JS it works better, maybe because of the brackets...
I see that when I select a Python function in ctrl-shift-o it shadows exactly the scope of that function, so it should not be a problem to select that scope.
Also, expand to indent level, like in Sublime Text, is also very useful (definitely works better than now for Python), and should not be very hard to implement,

For anyone who has landed here and - just like me - wasn't aware of a way to solve this for now, I've found this wonderful extension that can do this and much more in regards to selection expansion (works like a charm for HTML as well). If you're not sure about what keys to bind this to, here's how I set it:
CTRL + ALT + UP into expand_region;
CTRL + ALT + DOWN into undo_expand_region.

EDIT: I should note that the above commands are used by VSCode in editor.action.insertCursorBelow & editor.action.insertCursorAbove by default. I've changed those for convenience.

tl;dr:

CTRL + P › ext install expand-region › add these to your keybindings.json¹.

¹ Usually at C:\{{YOUR.username}}\admin\AppData\Roaming\Code\User

I confirm this _Expand Selection_ functionality is eagerly awaited. We can always rely on extension to fix it but a better built-in support for such a thing is the least a user can expect from a code editor.

Expand a selection in a string such as "this is a[] string" and the first selection jump to the outer quotes ["this is a string"] is very annoying and a waste of time. I expect it selects first the string inside the quotes and works no matter the language, even in txt file.

I hope to see all the feature users above describe to come up.

There are several issues I've encountered as well (this is JS):

  1. Within a string, can't use expand-selection to select one word before expanding to the entire string
  2. Growing inside block if () { ..growing from here.. } will select the block, then the entire block lines, instead of just the block itself, this is just one example where it goes to entire line too fast.

  3. Growing from function params with a long path, should grow by one word on every press

server.folder.file.delete(filename) if the cursor is in filename, it should grow to parens, then to delete with parens, then to file, folder and server. Right now it selects the entire line after filename for me.

  1. Within template string `${someword}`, can't select the word inside ${}, it selects the entire placeholder

  2. When growing inside an else if block, it should select the if (){} part first before selecting all the lines containing the else if (so the else in the else-if is only selected AFTER the if (){} part).

+1 for this request. This has been driving me absolutely nuts. I spend most of my time in IntelliJ IDEs and make extensive use of selection expansion, even in plain text files. The current state of selection expansion in VSCode is one of the few things preventing me from using it more often.

this is how it should work

Users shall be able to successively select expanding logical blocks of code so that you can easily select any expression in the code by placing the caret somewhere inside it and pressing a shortcut.

Extends selection to the next containing node (for example, an expression, a paired tag, an entire conditional block, a method body, a class, a group of vararg arguments, etc.)

In plain text, with the caret anywhere in a word, the selection would extend to to the word, the sentence, the paragraph

Shrink does the opposite.

Examples

vs129006090-f158a6be-7b23-11e7-9b52-f67ce1d57c4b
vs229006092-f2e4302a-7b23-11e7-95ee-38ab89ac6f7a
vs329006095-f4c3089e-7b23-11e7-8c08-661b1362d54f

The post above is definitely how everyone expects this to work. Currently it's pretty unusable. It's not even consistent. For example in json:

Growing in value selects everything within the quotes:

smartgrow-value

Growing in key selects everything within the quotes and the quotes! 😢

smartgrow-key

The state of this feature is currently my biggest gripe with vscode.

Any news ?

It is the only feature stopping me from switching back from JetBrains IDEs

can we pay to fund features like this?

Even more to inconsistency — using this feature depends on color scheme (!) being used.

Given string
import { Switch } from 'react-router-dom';
and 2 color schemes Dark (Visual Studio) and Arc Dark and cursor placed on the word Switch expanding selection selects word Switch with spaces around it in case of 1st color scheme and switch without spaces in case of the 2nd color scheme.

I wrote this extension that largely solves this problem for TypeScript, JavaScript, and JSON files. It uses the TypeScript compiler to generate smart selection expansions. Happy to accept contributions for other languages.

Just for the record, this doesn't solve the problem as it's fails to handle text selections more granularity (like webstorm). Also fails to retract correctly.

looks like jetbrains has monopoly on this feature

Cannot upvote this enough. It's my most-used hotkey in PHPStorm, and the only thing keeping me from switching too.

Hi,
Please try to solve this smart select issue, I used it a lot.
For example:
if we have this:

AppLocalization.of(context).|courses,

The cursor above is after the dot and before 'c'. If I grow the selection then it will select:

AppLocalization.of(context)[.courses,]

as you can see above (I used []), it will select the portion

.courses,

As I can see all the issues with smartSelect go here. So this is PR https://github.com/Microsoft/vscode/pull/56807 that should fix a problem with block selection.

I'm not sure if this issue is collecting bugs, but I just found this feature and tried it out in Dart, but it seems to get stuck weirdly on the => of some members:

screen shot 2018-10-09 at 19 04 04

Press Cmd+Ctrl+Shift+Right a few times, and you end up with:

screen shot 2018-10-09 at 19 04 13

The end of the selection gets stuck in that position for a few more expands.

LMK if this should be raised as its own issue.

@creal1976

Please stop emailing me

What very good manners.

Otherwise, CTRL + F (CMD + F on mac) : Unsubscribe, then click the button.

@creal1976

Please stop emailing me

You're receiving emails because you've either commented on or subscribed to this GitHub issue (I presume you subscribed, since it doesn't seem like you'd previously commented). There's a link at the bottom of each email that lets you mute the thread with one click:

screen shot 2018-10-09 at 20 50 05

@abderrahmane-tj

Same here. But also a bug-free tag renaming support on webstorm.

It's quite shocking how impoverished the expand selection feature is in a major code editor! It's dramatically inadequate compared to Webstorm. The VS Code team should hire someone from Jetbrains. These issues have been running for 2 years.

@Maxhodges some support shipped last update: https://code.visualstudio.com/updates/v1_31#_smart-selections

Looks like there's more to come too, see the various related issues

yes, that's what I just tested. It was a miserable failure. I think the authors of this feature don't share the same vision. The way Webstorm has implemented this feature it makes it an extremely useful productivity enhancement; in vscode it's a 2-year-running exercise in frustration and disappointment.

@Maxhodges Can you please be more specific on what is lacking? This is still a work in progress, so specific feedback would probably be helpful in shaping how it ends up. This could especially be the case if, as you say, the vision differs.

The behavior in the various JetBrains IDEs is excellent in my opinion. As an example, here's the behavior for each selection increment ([] indicating the caret/selection):

return moment(value[type], 'YYYY-M[]M-DD');
return moment(value[type], 'YYYY-[MM]-DD');
return moment(value[type], '[YYYY-MM-DD]');
return moment(value[type], ['YYYY-MM-DD']);
return moment([value[type], 'YYYY-MM-DD']);
return moment[(value[type], 'YYYY-MM-DD')];
return [moment(value[type], 'YYYY-MM-DD')];
[return moment(value[type], 'YYYY-MM-DD');]

Like this I can step through parts I might want to change easily - and even select logical blocks (e.g. dash-separated groups) inside strings easily.

@ThiefMaster Thanks! Something like that is not at odds with their vision and would be easily implemented with the new API. There was apparently an issue according to #64004 where the token information was not sufficient for the default provider to work like that for strings (or function calls), but the API can be used per language so it can be smarter. The issue is simply that it has not yet been implemented for that language.

I find JSX expansion to be too eager:

2019-02-14 at 16 12
Notice how it grows from <Foo /> straight to <div />, while I'd expect it to grow <Foo/> > <Link/> > <div/>

Another frustration for me is attributes selection, there's currently no way to select attribute and/or all attributes of the tag:

2019-02-14 at 16 16

Here it grows from href to <Link />, while I'd prefer href > href="/about" > all tag attributes > <Link />

As far as I'm concerned, I can't expand the selection for text inside javascript quotes.
It goes beyond the quotes…

expand 1

I find JSX expansion to be too eager:

2019-02-14 at 16 12
Notice how it grows from <Foo /> straight to <div />, while I'd expect it to grow <Foo/> > <Link/> > <div/>

Another frustration for me is attributes selection, there's currently no way to select attribute and/or all attributes of the tag:

2019-02-14 at 16 16

Here it grows from href to <Link />, while I'd prefer href > href="/about" > all tag attributes > <Link />

Use editor.emmet.action.balanceOut instead.

While it might be possible for the default provider to be improved further, it would be best to rely on language-specific selection which will probably be adopted after the API is finalized during the current iteration. Language-specific issues should then have their own Issues so that the maintainers of their respective language extensions can address them.

It also doesn't work with script tags or style tags in html. It just treats it as an HTML element and selects thewhole tag, rather than the closest block.

Are you looking for contributors on this issue? Also, will the resolution deal specifically with multi-cursor support of the feature? I noted that 40516 was closed as a dupe of this issue, but I don't see anything regarding multi-cursor noted here.

@anied The API (which was delayed) does support multiple cursors. It takes a Position[] for this purpose and returns a SelectionRange[][] which are the selection ranges for their respective input positions. I just tested with the default provider and could not reproduce losing the multiple cursors. Perhaps you could provide a more specific example where this happens.

@KamasamaK - Certainly, thanks for taking the time to look into this. Here is my VSCode version info:

VSCode Info

I just checked for updates and found none.

Consider the following code selection:

const username = new MDCTextField(document.querySelector('.username'));
const password = new MDCTextField(document.querySelector('.password'));

new MDCRipple(document.querySelector('.cancel'));
new MDCRipple(document.querySelector('.next'));

Now I can select the '. from ('.username') and leverage Selection > Add Next Occurrence three times to get four cursors, one in each string in the arg to querySelector. However, if I now use Selection > Expand Selection, rather than selecting all four strings in their entirety I lose all additional cursors, and only '.username' is selected.

So, as far as I understand it, there remains here a bug in which expanding selection loses multi-cursor context, but perhaps I am misunderstanding or trying to execute this incorrectly.

Thanks for taking the time to review this.

Closing this as we have finalised the extension API for VS Code 1.33 (planned to ship this week). Remaining work is tracked here: https://github.com/Microsoft/vscode/labels/smart-select. Please file new issues for more feedback. Thanks & Happy Coding!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

NikosEfthias picture NikosEfthias  Â·  3Comments

chrisdias picture chrisdias  Â·  3Comments

VitorLuizC picture VitorLuizC  Â·  3Comments

biij5698 picture biij5698  Â·  3Comments

omidgolparvar picture omidgolparvar  Â·  3Comments