microsoft/vscode

Column selection

sirius1024 opened this issue ยท 59 comments

Just a remark, though: the default key bindings for "Shrink/expand selection" (Shift+Alt+Left/Right) conflict with a feature that doesn't exist yet, but which I hope will be implemented someday: column selection. In Visual Studio, and many other editors, if you hold Alt at the same time as you change the selection with Shift+arrows, it changes the selection across multiple lines. So Shift+Alt+arrows should be reserved for column selection, unless you plan to never implement this (very useful) feature.

So hope that Code can support such a useful feature.

I'd like to see this feature as well, much please and thanks!

@SiriusGuo We support independent multiple cursors, which are slightly more powerful than column selection. So, you could use Ctrl+Alt+Down/Up to add more cursors and then regular shift+left/right to expand each cursor's selection. Or ctrl+shift+left/right, or end, etc.

@zry656565 @groksrc @diegostamigni Is there something I'm missing or can you get column selection and more with the multicursor support we already have?

multicursor

The multicursor support is nice, but it's a workaround for editing columns of text. On mac Ctrl+Alt+Down/Up writes a non-printable character instead of adding cursors. I have Command+Alt+Down/Up mapped with Spectacle for window management so that doesn't work either. The best I can do is Command+Click for new cursors. I'd like to be able to just Alt+Click/Drag to select an area of text for editing like Sublime.

@groksrc The default keybindings on mac are cmd+alt+down/up.

Perhaps Spectacle eats them up and they never reach us. Please try to edit your keybindings.json to change them. Specifically insert different keybindings in the key fields below:

[
{ "key": "ctrl+alt+up",           "command": "editor.action.insertCursorAbove",
                                     "when": "editorTextFocus" },
{ "key": "ctrl+alt+down",         "command": "editor.action.insertCursorBelow",
                                     "when": "editorTextFocus" }
]

You are correct, Spectacle is eating them so they aren't reaching the editor. So these keybindings do work, but this still feels like a workaround. It's a lot of keystrokes to select something that's say 4 columns wide and 50 lines long.

Also, say you do something like add 4 cursors and select to the end of the line. Unless all of the lines are the same length your cursors are now in different columns. This is usually not what you want when doing columnar editing.

riclf commented

Listen, vertical or column selection is a very simple concept, not including grander concepts like "multiple cursors". You put your cursor where you want to start, hold the Alt key down for the duration, and with the mouse move the cursor to the right and then down to create the desired box of selected text. One keystroke held down, the Alt Key, then a simple drawing action. Please, don't make this thing be some fangled 3-finger salute!

@riclf Thank you for your input, I am really just trying to understand how the feature should work, I'm not trying to sell anything :).

I have pushed a change just now that adds column select with the mouse with the same modifiers as Visual Studio (Shift and Alt pressed), the key difference being currently our cursors cannot float on air (they get bounded by the text shape).

To better explain, here is VS:
column-mouse-vs

Here is VSCode on master:
column-mouse-vscode

Is this different behaviour a deal-breaker when it comes to using column selection? Again, I am asking to understand how the feature should work and how it is being used so I can figure out how to implement it.

That works for me, what you have is the same as how it works in Sublime Text.

riclf commented

Alexandru,

Thank you for reaching out. The way VS performs a vertical selection is the
"correct" way, in that it is the classic way we expect that action to
perform, coming from other editors.

Your second demo as VSCode performs on master is interesting and of value but
not the expected behavior.

The problem with the current VSCode behavior is that it specifies in the
design that the "box" selection will always be to an "end of line" condition, including
the CR. An expected vertical selection would be my desired box of data,
not always extended out to the CR at a variable horizontal distance. The current VSCode implementation is not a vertical selection box behavior. It is a variable length selection at each line.

In a perfect world the classic VS way would be the default, implemented with
just an Alt Key and mouse draw. Then maybe your current VSCode way with a
Alt+Shift and mouse movement, as a secondary option. But it is not very
usable.

If I could only have one I would much prefer the expected classic behavior,
as in VS, as that permits me to select the vertical data what I want/choose
and not be forced to include more data + CRยนs in my selection.

Can we have the classic behavior as implemented in VS?

Thanks for asking !

-Ric

@riclf, doesn't the 2nd example give the same 'result' as the 1st? It's just not as visually appealing.

The second is how it works in sublime and atom, though I'd prefer just alt+drag like sublime.

Looking forward to this, working without it is painful...

Interestingly, sublime doesn't put cursors on empty lines...

multi-cursor

FYI, emacs CUA rectangle selection shows the rect on all lines (even empty lines.) Delete only affects populated lines (obviously) and never deletes a CR. Inserting does affect blank lines (e.g. see the comment chars.) And I personally like to nav with arrows, not the mouse.

test

I can't use an editor seriously without this feature. Thanks for working on it!

@egamma, thank you for being so attentive to this issue. I saw your post on 1060 referring to this post as well :-) I wholeheartedly agree that the multiple cursors are more powerful...but sometimes "simpler" is what's needed. Is that not the heart and soul of Code in the first place? The current behavior, using "Insert Cursor Above/Below" yields ok-but-not-perfect results:

blockselectioncurrent

While I believe the desired behavior, some key combination (Alt seems traditional) and a mouse-drag is more flexible. EditPlus, like the several editors above, also displays this:

blockselectiondesired

I'd sure love to see this idea revisited as it's one of the hold-ups for my adoption of Code as well. Thank you again for all your hard work!

+1 for using Alt+Drag to select a rectangular area.

Plus, using multiple cursors is powerful in some situations, but the behaviour is very dependent on Codes word boundaries, which are odd imho.

At the very least, the selection crosses lines as demonstrated above in e.g. the @egamma post and I don't see how that would ever be useful or intended.

And I'm using Visual Studio Code along full Visual Studio most of the time. The key combinations are absolutely alien to me. I'm wondering why Visual Studio Code doesn't align with full Visual Studio - possibly after (or before) selecting a(nother) (built-in) keyboard configuration.

dvlsg commented

@alexandrudima The gif of your VSCode master example looks fantastic! Maybe perfect, depending on whether or not cursors should be placed on empty lines. I've never really thought about it before, to be honest, but I've never come across any issues when using editors that skip the empty lines when using column selection.

I would love to see Middle Click Drag without any key modifiers as one of the shortcuts (or the option to rebind to mouse buttons -- is this available?) for column selection so I can select columns without my keyboard. This matches one of the shortcuts sublime provides.

edit: Removed comments about multi cursor, they belong somewhere else.

I think ALT and click dragging should be implemented in the same way as VS. For this to work, VSCode needs to support virtual space, the idea is that you should be able to hold ALT and click anywhere in space and start typing. This will automatically insert spaces up to the cursor. Once this is supported it should make sense to be able to drag a box selection anywhere which will allow you to type characters all aligned to the same column position - regardless of what the lengths of the lines are.

Is this not a duplicate of #84?

As others has mentioned I think VS Code should allow the same behavior as VS does it (if that means supporting virtual space that is even better). "Insert Cursor Below" as it works today is only half-way there. To me this is very important.

+1

Notepad++ uses Alt+Drag, too.

Comes out in March

Any idea/hint how to use column selection in OSX ? :D
cmd+alt+arrows(u/d) works fine, but I cant figure how to use mouse to select block

This is not available yet, next release. (see above)

Tried the insiders code today. While I do think the column selection behavior is a major improvement over previous behavior IMHO the lack of virtual space is limiting the use. Will look if there's an issue for this.

I'm having some trouble getting it to work at all on OSX or Ubuntu 15.04 VM. I have tried several things. I quit Spectacle to make sure nothing was hijacking my keystrokes. I also tried it reinstalling it: Version 0.10.12-insider (0.10.12-insider). Do I need to set up keybindings for it in keybindings.json?

@groksrc I could not find anymore free keybindings on Linux by default, so on Linux, you'd need to bind them in your keybindings.json. E.g.:

{ "key": "ctrl+shift+alt+down",   "command": "cursorColumnSelectDown",
                                     "when": "editorTextFocus" },
{ "key": "ctrl+shift+alt+left",   "command": "cursorColumnSelectLeft",
                                     "when": "editorTextFocus" },
{ "key": "ctrl+shift+alt+pagedown", "command": "cursorColumnSelectPageDown",
                                     "when": "editorTextFocus" },
{ "key": "ctrl+shift+alt+pageup", "command": "cursorColumnSelectPageUp",
                                     "when": "editorTextFocus" },
{ "key": "ctrl+shift+alt+right",  "command": "cursorColumnSelectRight",
                                     "when": "editorTextFocus" },
{ "key": "ctrl+shift+alt+up",     "command": "cursorColumnSelectUp",
                                     "when": "editorTextFocus" },

Any suggestions for how to troubleshoot the keyboard shortcuts CTRL-ALT-UP and CTRL-ALT-DOWN on Windows? (Or key presses in general?) Add Cursor works fine from Command Palette so I probably have some weird keyboard thing going on.

Mac insiders build doesn't seem to have this feature? Am I missing something? (using alt drag)

Sorry, worked it out, alt+shift drag... Can I change this to alt+drag?

What was the final verdict for arrow keys, and for mouse? Not having luck in my build of master on Windows. Was hoping for alt+shift+arrows, but seeing ctrl+shift+alt+arrows in key bindings and that's not working. Not seeing way with mouse.

@JVimes Shift+Alt for mouse and ctrl+shift+alt+arrows for keyboard by default.

I've heard that those modifiers might not work on all installations. To bind them to something more familiar:

{ "key": "shift+alt+down",     "command": "cursorColumnSelectDown",
                                  "when": "editorTextFocus" },
{ "key": "shift+alt+left",     "command": "cursorColumnSelectLeft",
                                  "when": "editorTextFocus" },
{ "key": "shift+alt+pagedown", "command": "cursorColumnSelectPageDown",
                                  "when": "editorTextFocus" },
{ "key": "shift+alt+pageup",   "command": "cursorColumnSelectPageUp",
                                  "when": "editorTextFocus" },
{ "key": "shift+alt+right",    "command": "cursorColumnSelectRight",
                                  "when": "editorTextFocus" },
{ "key": "shift+alt+up",       "command": "cursorColumnSelectUp",
                                  "when": "editorTextFocus" }

@alexandrudima, Those shortcuts are good and work, but I expect them to be default on Windows. Mouse still doesn't work. Shift+Alt+drag ignores the location I started dragging at. Instead, it starts the box at the last cursor location.

I implemented what I have observed in Visual Studio (which was pointed in this thread as a good implementation of column selection):

  • Pressing Shift+Alt and then clicking will create a column selection anchored at the last cursor location going to the mouse location.
  • Clicking and then pressing Shift+Alt will create a column selection anchored at the click location going to the mouse location.

Regarding the default shortcuts, they would be better, but they conflict with other default shortcuts we have already shipped with and I cannot "steal" them without annoying existing folks used to them.

@alexandrudima, Oh, I see, we're discussing a slightly different feature than I thought. Visual Studio and Notepad++ also support Alt+drag to do a column select, which I often use. I think it would be a good feature to include in this story.

Wouldn't it be great to be able to set a standard key binding profile without having to construct it by editing keybindings.json - that's quite hard and tedious. keybindings.json would still override the defaults in the profile. So VSCode could ship with a Visual Studio key binding in the box for people to simply select. That'd allow you to modify that profile with the sole argument that it aligns with Visual Studio.

Key binding schemes would be great as extensions. Might be able to do that now by modifying the current key bindings, but it would be better to modify the underlying defaults like @ericwj described. Just need factory defaults to take back over when the extension is uninstalled.

is this implemented in the current stable vscode? or do i need to grab the latest from source?

dvlsg commented

I know it works in the insiders builds.

To add to what others above are saying, I would also love to see functionality that starts the column selection from the point where you clicked (alt + left click drag, rebindable to middle click drag?) make it in to vscode. I think the shift-alt-leftclick version does add value, but it feels awkward to me, since I typically intend to start the column selection where I click.

Tried column selection in VSCode 1.0. Well, rectangular selection does work, cutting and pasting back also works, but that's about it.
Cutting and pasting into a different part of the code does not work as expected. Both Notepad++ and VS remember that copied text was a rectangular block and paste it as a rectangular block.
VSCode treats copied block just like a regular text, so pasting it anywhere outside of the current multi-cursor context would create a mess.
It's good that the feature is being worked on, but it's not fully baked yet.

@JVimes @dvlsg I submitted #5402 for Alt+select behaviour.

Inori commented

mt
โ†‘ Input the regex text and the press Alt+Enter . No mouse operation.

How to select all the text matched by a regex search in column selection mode like sublime?

Is it possible to rebind the keys that go with click+dragging? I searched the keybindings.json but can't find one for that. Trying to rebind it to just alt rather than alt+shift

First a BIG THANK YOU to all of the contributors to this feature!!!!
@Aarilight did you figure out how to do change the binding to just Alt + drag? Alt+shit is very annoying : (

I like this feature as well

I agree with @seva0stapenko, I expected the same behavior that Visual Studio, which has been copied in Scintilla, thus in related editors like Notepad++ or SciTE.
When copying / cutting a rectangular selection, it puts a "MSDEVColumnSelect" empty flag (and a "Borland IDE Block Type" flag with byte 0x02) in the clipboard, so when pasting, each line of the block is pasted in a line of the destination.

2016-11-16_13-59-15

I made a Gif out of a manip in SciTE, showing cutting & pasting a column selection, and the reverse operation using drag'n'drop too.
Alas, I think VSCode still lacks even base D'n'D support... ๐Ÿ˜ž

scite-rectangularselection

I cannot get column selection to work for linux mint; alt+click doesn't do anything, in fact.

dvlsg commented

@PhiLhoSoft that functionality could be problematic for some of the copy/pasting I do with column selection. Sometimes I want to take pieces out and move them somewhere else, but if VSCode pasted into the lines following my cursor, instead of making a new line for each one that I had, I would have a huge mess of code.

If I'm understanding the suggestion, in order to make that work, I would have to enter in a bunch of blank lines (and I would have to know exactly how many before being able to paste) in order to make sure that part of my column selection doesn't end up getting pasted inside another line which already has code? That seems like a pretty big hassle to me. Or am I misunderstanding?

@dvlsg In Visual Studio, if you paste on a blank line (a line with no non-whitespace characters) it will insert new lines into the document to fit your clipboard. If you paste on a non-blank line, your clipboard lines will be inserted over the lines below your caret. This may be naive but I think it is what the user intends most of the time.

riclf commented

@IntelOrca is right, and it is intuitive for the user to control the intention. Another easy way is to provide both options, one performed by also holding down the Alt Key. Lets not pretend this is hard stuff. Both column pastes are necessary to have in an easy manner, either intuitive or by keystroke.

dvlsg commented

@IntelOrca that seems like a fair distinction to me. I agree that it feels a bit naive, but you're probably right that it's what the user intends in most cases. I was unsure of exactly how visual studio handles it, so thank you for the insight. I think I would have pressed ctrl+left arrow to move all the cursors in the gif example, then pasted them from the moved multi-cursors, but I can see how being able to click one position would potentially be useful.

To add some potentially relevant information, here's how a couple other editors appear to handle it:

  • Sublime
    • When N lines are copied
      • Paste with 1 cursor
        • all lines are pasted as is, including new lines, pushing text after the cursor down
      • Paste when M cursors
        • all N lines are pasted M times, following the functionality of pasting with 1 cursor
      • Paste when N cursors
        • each N line is pasted once, at each cursor corresponding to its line number

As far as I can tell (from the perspective of an end-user, anyways), sublime doesn't appear to distinguish between items copied from multiple cursors or single cursors stretched across multiple lines.

  • Atom
    • Seems to be the same as sublime, basing it on the number of cursors you have when pasting vs the number of lines you have copied

@dvlsg As you noted neither Sublime nor Atom supports the "correct" behavior but I heard that Emacs 24 does support it. Notepad++ and Powershell IDE (of all things) does it decently.

TKAB commented

For anyone searching: on Mac the default shortcut is Cmd+Shift+Click.

The behavior is a little different than in Sublime. You have to first click and then press Cmd+Shift, otherwise it will take the current cursor position as the origin.

Hi,

as far as I can see the shortcut with mouse is alt + shift + mouse. alt+cmd + arrow down works from keyboard.

Note that Alt+Shift+click doesn't work on Gnome 3 if mouse-button-modifier is set to Alt, which seems to be the default in some installations. https://bugs.launchpad.net/ubuntu/+source/mutter/+bug/1704580

To fix, run

gsettings set org.gnome.desktop.wm.preferences mouse-button-modifier "<Super>"

Or use Gnome Tweak Tool to change Windows -> Window Action Key.