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

Multiple cursor support #5

Closed
montanaflynn opened this issue Apr 18, 2016 · 33 comments
Closed

Multiple cursor support #5

montanaflynn opened this issue Apr 18, 2016 · 33 comments

Comments

@montanaflynn
Copy link

After using sublime and atom I can't go back to not having multiple cursor support. Any plans to introduce this into micro? Even just select all and select next would be amazing as that covers 90% of my usage.

@bentranter
Copy link

Hey @zyedidia, if you're not currently working on this, I'd love to take a stab at implementing it

@zyedidia
Copy link
Owner

Sure, go for it!

@mholt
Copy link
Contributor

mholt commented Sep 9, 2016

@bentranter FWIW, I'm a huge fan of the PR you've started. 👍

@techtonik
Copy link
Contributor

@montanaflynn can you record a video of this feature to make it clear for the rest of us?

@bentranter
Copy link

Thanks @mholt! I always wanted to finish implementing this but could never find the time, and then eventually gave up. It looks like people still want this feature, so I'll give it another stab over the weekend (unless you're actively working on this @zyedidia).

@zyedidia
Copy link
Owner

zyedidia commented Sep 9, 2016

No I'm not :).

@montanaflynn
Copy link
Author

@techtonik here you go:

https://gifs.com/player/G6m3vQ

@ahoarau
Copy link

ahoarau commented May 26, 2017

is there any new development on this ?

@zyedidia
Copy link
Owner

No unfortunately not.

@zyedidia
Copy link
Owner

There has been a new development! I have implemented multiple cursors. It's currently sitting on the multiple-cursors branch.

The bindings are

"Alt-n": "SpawnMultiCursor",
"Alt-p": "RemoveMultiCursor",
"Alt-c": "RemoveAllMultiCursors",
"Alt-x": "SkipMultiCursor",

I'm not sure if it's bug free yet so I haven't merged it into master.

Since the only multiple cursors I have used is the vim-multiple-cursors emulation, I've based it off of that but I'm not sure if sublime text does more complex things.

Let me know if you find any bugs.

@ahoarau
Copy link

ahoarau commented Jun 12, 2017

That's great, I'll try to test it soon.

Since the only multiple cursors I have used is the vim-multiple-cursors emulation, I've based it off of that but I'm not sure if sublime text does more complex things.

There's a pretty multi-selection/multi-cursor in sublime/atom. Basically you select something, press ctrl+d and it selects the next corresponding selection in the text. Then you can move around with those newly created multi-cursors. Useful for refactoring !

@zyedidia
Copy link
Owner

zyedidia commented Jun 12, 2017

Alright that's the behavior that my implementation has but with different keybindings. I'm also open to using different default keybindings but since you can easily rebind them it doesn't really matter.

@DanielPower
Copy link
Contributor

@zyedidia in addition to the keyboard shortcuts you've implemented for it, it would also be nice to be able to Ctrl+Click a location to spawn a new cursor there. This is the behaviour in Atom.

I have not tested your new branch yet, so I'm not sure if this is the case or not in your current code.

@zyedidia
Copy link
Owner

zyedidia commented Jun 12, 2017

Ok I have just added support for that (see 340cfb8 for details). If you are using macOS though you will need to rebind it to another mouse button because Ctrl-Click is used as an alternate right click.

@DanielPower
Copy link
Contributor

DanielPower commented Jun 12, 2017

Thanks for the update. I have found a few issues, but it's a strong start. The implementation is good once the bugs are worked out.

Issue 1: When backspacing at the beginning of a line with multiple cursors, the extra cursors do not reposition themselves correctly.
Issue 2: When multiple cursors are on the same line and you backspace, the second cursor only moves back one space, instead of two. (It should move back two, one for the character the first cursor deleted, and one for the character it deleted)

Example of issues 1 & 2:
Imgur

Issue 3: Backspacing with 3 or more cursors causes unpredictable crashes.
Example:
Imgur

Issue 4: Clicking without holding Ctrl should cancel the multiple cursors, leaving just the main cursor.
Example:
Imgur

Completely unrelated issue that I found while testing this. Clicking in one location and then quickly clicking in another is detected as a double click to select a word. A double click should only be detected if the user clicks the same location twice in a row.
Example:
Imgur

@zyedidia
Copy link
Owner

Issues 1-3 all boil down to the same issue which is that the cursors don't know about the line being modified so they don't move. This might require some more thought to fix because I think it means changing where cursors are stored.

zyedidia added a commit that referenced this issue Jun 15, 2017
This changes the behavior of cursor movement so that all cursors are
adjusted when a change is made to the buffer. Cursors don't have to be
manually moved after calling Insert or Remove, those functions will move
the cursor properly on their own.

This should fix issues 1-3 mentioned in the multiple cursors discussion.

Ref #5
@DanielPower
Copy link
Contributor

Thanks for the fix. This is working pretty well now. I've found one more issue just by playing around with it. I haven't used this in production yet, just did some quick tests. So there very well may be edge cases I have not found.

The remaining issue is that if you delete characters until two cursors end up occupying the same space, they get stacked and basically double input / output. The expected behaviour is that these cursors should merge (All but one are removed)

Example:
Imgur

@zyedidia
Copy link
Owner

Yup I came across that problem. I've also found some other issues (with undo and selections) so this still needs some more work.

@zyedidia zyedidia mentioned this issue Jun 17, 2017
5 tasks
@zyedidia
Copy link
Owner

zyedidia commented Jun 17, 2017

I have merged the pull request so multiple cursors should be in master now. If you can't build from source you'll be able to get the nightly tonight and try it out.

@lucmos
Copy link

lucmos commented Dec 24, 2018

@ahoarau @zyedidia I just wanted to expand a little bit on this:

There's a pretty multi-selection/multi-cursor in sublime/atom. Basically you select something, press ctrl+d and it selects the next corresponding selection in the text. Then you can move around with those newly created multi-cursors. Useful for refactoring !

Actually they (sublime and vscode, not sure about atom) do something slightly different, that I find very useful:

  • If the cursor is at the start, in the middle or at the end of a word, ctrl+d expands the selection to the whole word and, if pressed again, places another cursor to the next match "whole word" that it finds.
  • If there is a selection of characters (even whitespaces), ctrl+d places another cursor to the exact next match.

Moreover the match can be case sensitive or not, depending on the current configuration on the search function.

e.g
Starting from: |test or test| or te|st
image
image
image

Starting from: test and pressing ctrl+d four times
image

@techtonik
Copy link
Contributor

These multiple cursors look like a limited version of macro recording abilities. Record a macro in Far Manager and replay it dozen times looks easier than wrapping the head around this feature.

@AndydeCleyre
Copy link

@techtonik As a Sublime Text and Micro user, I'm not familiar with macros, but would love behavior as Luca described. Especially if, as it sounds, macros require a separate "recording" stage, which would kill the interactive, immediate feedback workflow that I'm productive with.

@techtonik
Copy link
Contributor

@AndydeCleyre with macros I do ctrl-. instead of alt-n to start recording, and once I complete my operation correctly, I hit ctrl-. again, press a key to assign macro and just hit that key as many times as I need. This is more productive as it doesn't require mouseclicking for multi cursor positioning.

@lucmos
Copy link

lucmos commented Dec 28, 2018

@techtonik I never use the mouse to place multi cursors.

Whole word matching is useful to do refactoring where you want.

I personally use the exact match in this way:

  • Find a pattern in the lines you want to modify
  • Select the pattern (shift+arrows)
  • Place multiple cursors in the needed occurrences of the pattern
  • Use the home/end keys and ctrl+arrows to position the arrows maintaining the sync
  • Perform the changes

I have no idea on how to use the macros in sublime, but I don't think I could be more productive with them

Another very useful shortcut is the split line: select some contiguos lines, you can place a cursor in each one of them

@techtonik
Copy link
Contributor

Ok, there is no mouse clicking, but there is a lot of cursor moving. With macros you just chain the search for the next pattern at the end of your edit.

For sublime press ctrl-q to start recording macros, ctrl-qto stop andctrl-shift-q` to replay. http://docs.sublimetext.info/en/latest/extensibility/macros.html

@lucmos
Copy link

lucmos commented Dec 28, 2018

I get that the macros can be useful, expecially if you are used to them from experience of vim or similar.

I think that the multi cursor approach has a big advantage: you have an immediate feedback, and if you do something wrong, you can simply ctrl+z it. If you forget something in the macro, maybe beacause you didn't notice some differences in the row... You have to redo all from scratch, and you can't know that the macro is wrong until you use it.

I have the feel to be much more in control of the situation if I have feedback on what I'm doing.

Moreover what if I don't know in which line I want to do some changes, or they are too many? I'm under the impression that, while it can surely be done using macros, it becomes messy. With cursor you just have to identify a pattern in the line, place cursors on all the lines, and modify the lines maintaining the cursor in sync. it is easier to do that than to say it

@montanaflynn
Copy link
Author

I use multiple cursors multiple times a day for everything from refactoring, editing json, creating new arrays, etc... in atom and previously sublime, and I've never used macros in sublime or atom.

This issue is for multiple cursors, not macros.

@techtonik
Copy link
Contributor

@lucamoschella when you recording macro you are doing edits as usual and see the feedback. When playing you see the result. ctr-z rollbacks the whole macro sequence. It is the same as cursors, just sequential autmation, not parallel.

@lucmos
Copy link

lucmos commented Dec 29, 2018

Yeah, I meant that you get feedback from all the lines (immediately if all fit the screen).
If only the last N lines don't work with the macros, you have to get there to understand it. With cursors it is immediate, even more so since you can see where the cursor are placed before starting to modify the lines.

@techtonik
Copy link
Contributor

techtonik commented Dec 29, 2018

Macros are especially good if there are many lines or multiple places over the file that you can not see in one screen. As I said - at the beginning of a macro or at the end you can invoke find function to place cursor to the place that will be the starting position for the next macro invocation. How do you do that with cursors if content is not at the same screen?

@lucmos
Copy link

lucmos commented Dec 29, 2018

Macros are especially good if there are many lines or multiple places over the file that you can not see in one screen. As I said - at the beginning of a macro or at the end you can invoke find function to place cursor to the place that will be the starting position for the next macro invocation. How do you do that with cursors if content is not at the same screen?

This is exactly what sublime and the others do in a smarter way.
The "methods" to place cursors (whole word or exact match, my first comment) can be seen as a search for where your cursors must appear in the file.

If you are referring to multiple files, yes cursors are local to a single file

@techtonik
Copy link
Contributor

techtonik commented Dec 29, 2018

Queries for automated cursor placement make sense. This way the cursor feature can be more useful than macros. Is there a way to place cursors to keywords from static analysis? For renaming methods, variables limited to the current program scope?

@lucmos
Copy link

lucmos commented Dec 29, 2018

Like the "refactor" function of some IDE?
Maybe with some plugins in sublime, in Code some languages support the refactoring, but it must be a known programming language.

I often use the multiple cursors to format nicely something that I copied in the clipboard.
I think the best refactoring we can get on plain text is to place cursor on all occurrences of the "whole word", with the possibility to skip the next occurrence ( ctrl+k ctrl+d) and undo the last cursor placement (shift+ctrl+d).
It would be interesting a regular expression to place cursors, but I think the "simple" approach (with an extremely low learning curve) should be the main approach. Most of the time I don't need a regular expression, it's quite easy to look at the text and identify an adequate sequence of characters that most of the time appears only in the desired targets

If the refactoring is supported, it's more powerful than cursors, since it accounts for scopes and name clashes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants