Open idleberg opened 8 years ago
This is intended, specifically for multi-caret pasting. If you have the same number of lines in your clipboard as you have selections, ST will insert one line for each selection/caret.
It has always been like this and I hardly doubt it will ever be changed.
Yes, this is one of the nicest features of multiple selections, and would be a huge functionality regression if changed.
I didn't know about that feature, it's a great one. However, I think it's a bad design decision to have one action behave differently depending on context. To someone who doesn't know about it (like me 9 hours ago), it feels erratic. Is there at least an option to override this, so one can still get the “expected result” as mentioned above?
Is there at least an option to override this, so one can still get the “expected result” as mentioned above?
You can use Replace… (in Find menu) to get the “expected result”.
I agree that feature is useful and removing it would be regression, but what about confirmation dialogue? I.e. if clipboard contains same amount of lines as view contains selections, then on paste it would ask Do you want to paste line per selection or the whole clipboard to each selection?
and there would be another setting to disable dialogue for old-skool-fellows.
I firmly believe that additional option/setting is not needed. There are two clearly distinct use cases, depending on the source of clipboard text [i.e. a way with/by which that text was placed into the clipboard]:
So, I would rather fix that @FichteFoll's statement: If you have the same number of lines in your clipboard as you have selections, ST will insert one line for each selection/caret. to something like this: If you have the same number of copied regions/texts in your clipboard as you have selections, ST will insert one copied region/text for each selection/caret.
I suppose that during the initial development of this feature [multi-caret pasting] a developer of SublimeText could not clearly decide what method for separating text regions of multiple selection should be used.
Moreover, as I can see this problem already have beed raised (here and here), and in solution proposed by @adzenith copied text from multiple [regions/]selections is stored in global array variable selection_strings
.
As an alternative, I would suggest to refuse global variable selection_strings
and use some special [ASCII or Unicode] character to separate copied regions (e.g. File Separator Character — "\x1C").
[For now in SublimeText [as it turns out] simple "\n" (Line Feed) character is used as such separator [of multiple copied text regions] character, so multi-line text [i.e. text which contains at least one "\n" character] breaks this "multi-caret pasting" feature.]
There are two clearly distinct use cases
The use cases are not necessarily distinct. The example given in my initial post was simplified for illustration purposes. Working with 20+ selections can be overwhelming (I actually had cases of hundreds of selections), making it hard to keep track. Predictable behaviour is desirable and to achieve that I'd be fine with any additional keystroke preceding the paste-command, e.g. AnyModifierKey, CmdV on macOS.
@idleberg By distinct I mean that your case is clearly distinct from what @FichteFoll is talking about. Because as I understand you copy single selection/region (possibly consisting of multiple lines) into many selections/carets.
The CopyEdit plugin you mentioned is indeed meant to fix this exact problem. I wrote the plugin because Sublime Text's behavior with multi-line, multi-selection is pretty broken compared to the single-line, multi-selection behavior (as you noted). The latter does exactly what you expect, and it's the behavior that I think @FichteFoll wants to preserve (?). The former does not do what you expect, and it sounds like that's what @idleberg wants to change. The plugin just makes both scenarios behave like the excellent single-line scenario.
To re-iterate on my earlier comment: The current behavior is so definitive that I hardly doubt it can be changed. It is very predictable once you understand it and follows a simple rule.
A setting could be added to change the behavior of copying and pasting, but a way more flexible way of changing the behavior would be to just write a plugin since the required functionality is made available through the API.
Imo, the only thing that could be worth adding to the default distribution is a command on a different key binding that does what OP expected.
@alextretyak Using something other than \n
for the separator would break integration with other programs.
@adzenith No, I don't believe anything is currently broken with regards to multiple selections. It may not do what you initially thought it would, but I do believe it is functioning as Jon intended.
In summary:
\n
separator for integration with other software on your machine.While I understand why you may want to add two line to the clipboard and then paste them in two places, changing the current implementation to achieve that would break the above use cases.
That isn't to say, like @FichteFoll suggests, that a new command could be implemented to support multi-line pasting when there are the same number of cursors and lines on the clipboard.
I would (generally) be opposed to prompting the user in such a situation. A prompt would be useful the first time, and a hindrance all subsequent times. Instead, I'd prefer to add official documentation about the details of multiple cursors and how the clipboard interacts with them.
Instead, I'd prefer to add official documentation about the details of multiple cursors and how the clipboard interacts with them.
If I had more time (or it was paid 😄 ), this would already be part of the unofficial docs, but there's a lot to do.
@wbond Have you tried the plugin? It works really well, even when copy-pasting to other programs. It puts the data on the clipboard with a \n
separator, but internally stores the selections separately. If you paste somewhere else it just works, like normal copying and pasting. That is to say, it meets both criteria that you put forward there.
The change is that it also meets the second criterion for selections with newlines in them. This allows you to actually batch-edit lines, instead of just batch-editing parts of lines. So it adds the feature that @idleberg wants without breaking either of the two features that it sounds like you want, if I'm understanding you correctly.
@adzenith No, I haven't tried the plugin, but then again, I haven't ever run into wanting to change the current behavior.
I would (generally) be opposed to prompting the user in such a situation. A prompt would be useful the first time, and a hindrance all subsequent times.
It would be a way to decide which behaviour you need at the moment without thinking about it beforehand. The thing is that user may need both of them in different cases. Currently it is like this: press ctrl+v, see that you got not what you need, press ctrl+z, paste content at each point with single selection or use Replace panel With dialogue it would be: press ctrl+v, see prompt, decide what you need and press Enter (or ctrl+v) for default or Escape for whole content into each selection.
@wbond
Using something other than \n for the separator would break integration with other programs.
I agree with that point (though I personally do not need copy/paste multi-region selections between different programs [because the only program on my machine which supports multi-selection is SublimeText ☺], I can easily imagine that this may be needed for some people working with multiple editors with multi-caret/multi-selection support [e.g. Atom and Sublime]).
@FichteFoll I see two advantages of fixing the default distribution:
As a basis solution for this issue I think that @adzenith's plug-in is practically acceptable (though need some polishing).
If you see places it needs some polishing feel free to open issues (or pull requests!).
In the best tradition of TDD, let's begin with writing some tests.
At my fork of @adzenith's CopyEdit I have added this file cut_copy_paste_tests.py, and [with the help of it] I have performed the following tests:
# | CopyEdit_9b68 | Sublime by default | cut_copy_one | |
---|---|---|---|---|
(1) | CORRECT | CORRECT | CORRECT | CORRECT |
(2) | CORRECT | CORRECT | CORRECT | CORRECT |
(3) | CORRECT | WRONG | WRONG | WRONG |
(4) | ALSO WRONG | WRONG | CORRECT | CORRECT |
(5) | CORRECT | CORRECT | CORRECT | CORRECT |
(6) | WRONG | CORRECT | CORRECT | CORRECT |
(7) | ALSO WRONG | WRONG | WRONG | INCORRECT |
(8) | INCORRECT | CORRECT | CORRECT | INCORRECT |
(9) | INCORRECT | INCORRECT | INCORRECT | INCORRECT |
P.S. cut_copy_one
is a simple [plugin/]command from that my comment with added just this EventListener code (to override Cut/Copy commands in all places, even in menu Edit:Cut/Copy):
class cut_copy_one_listener(sublime_plugin.EventListener):
def on_text_command(self, view, command_name, args):
if command_name in ["cut", "copy"]:
return ("cut_copy_one", {"command": command_name})
@alextretyak I read through the tests, however we seem to disagree about what is the correct and wrong/incorrect.
For number 4, IMO, Sublime Text is CORRECT here. If you copy multiple values, you should never throw one away.
For number 7 and 9, I can't see how we should assume when pasting contents with the cursor in the middle of a line that the values should instead be pasted at the beginning.
The only one that seems it would be unintuitive to me with the current Sublime Text implementation is number 3.
I have fixed behaivour of CopyEdit plugin to "correctly" pass all my tests and already added a pull request for it, but... looking at the comment of @wbond it seems that I was a bit hurried ☺.
@wbond Test (4) was added specifically to resolve this issue #1461 and has real practical application (simple refactoring/renaming some identifier via Alt+F3). Also I'd like to note that pasting single selection region into multiple cursor positions works correctly (and totally symmetrically) in this case, so I doesn't feel any problem with it. May be you have some real example when this behaviour is undesirable?
I can't see how we should assume when pasting contents with the cursor in the middle of a line that the values should instead be pasted at the beginning.
Just like how now Sublime assume/handle this for single caret case (I have already mentioned that under the hood Sublime already have some nontrivial logic to handle this correctly.)
Something similar has also been mentioned at https://github.com/SublimeTextIssues/Core/issues/173
This may be the default, but a way to use it "normally" would be welcome. Just because was designed that way does not mean it couldn't be extended for when you need a normal paste (CTRL+SHIFT+V or CTRL+ALT+V or whatever). I found this issue like a week ago.
Note that a custom command to ignore the selection-splitting behavior is as simple as this:
import sublime
import sublime_plugin
class PasteRawCommand(sublime_plugin.TextCommand):
def run(self, edit):
clip = sublime.get_clipboard()
for region in self.view.sel():
self.view.replace(edit, region, clip)
presumably you want to iterate the regions in reverse though
sublime.Selection
is a lazy iterable and updates live when iterated. Iterating in reverse is only necessary when you prefetch the regions and intend to change the contents later.
I wanna throw my two cents here - I'd really like there is a some form of command+option+control+shift+V which ignores multi-caret pasting and the rest is left as it is
I totally love the current behavior except when at times the number of lines copied doesn't match the number of selections into which it's pasted.
Following have been my usecases IIRC.
In the "most common" case, if the number of lines don't match, it accidentally results in the "almost never" case which becomes a mess. But it's possible to quickly recover from it by undoing.
The only issue for me is when the number of selections in the "most common" case is as large as 1000's of lines and it accidentally triggers the "almost never" case. Sublime Text freezes for a while since it explodes quadratically into a million lines. It'll be good if this is solved.
A confirmation alert I feel will make sense here. Because I think it's fair to assume that nobody would want to paste too many lines into too many places. At least not commonly so. Since it may be difficult to decide how many is too many it could be applied to even one newline if there's a consensus on the usecases perhaps.
Perhaps this warrants a separate issue since it potentially introduces a third behavior for the same action which is the opposite of the original issue in this thread which complains about the already existing two behaviors. About this complaint, I was tripped by it too, but that was years ago. And I feel it's just a small learning curve which is well worth it.
Yes, this is one of the nicest features of multiple selections, and would be a huge functionality regression if changed.
Haha. I regret upgrading to ST 4.
Would you mind clarifying on this? The behavior is unchanged in ST4 compared to ST3 (or ST2 for that matter).
Unless you meant to imply that it specifically hasn't been addressed.
I swear some things are not working in ST4 anymore that did work in ST3, tho I can't remember now what it was anymore.
Is this the same issue?, it IS indeed new and is very annoying, no idea if its an osx update or st4. on OSX If you copy into buffer, it gets overwritten constantly, if you select anything it goes into buffer, If i highlight something and find next
thats now in the buffer and my copy is gone, if I goto find and replace and click on something in there, now that! is in my paste buffer... oh and undo seems to also affect the copy buffer sometimes?
Summary
This is an odd bug and I find it hard to describe. Hopefully the steps to reproduce make it clearer.
When copy & pasting n lines of text into n selections, the result will differ from selections less or greater than n.
Steps to reproduce
1.) Consider the following YAML (just for illustration, can be any syntax)
2.) Copy two lines of text, e.g.
3.) In the YAML file select any of the of the sub-keys, e.g.
-two
4.) Press CmdD to select the next instance to
-two
(= two selections)6.) Paste the the two lines (or ”Paste and indent”)
Expected behavior
I'm expecting the YAML to look like this (comments added for emphasis)
I get the expected result when I select all instances of
-two
or only one (less or greater than number of lines pasted).Actual behavior
The YAML actually looks like this (comments added for emphasis)
This will always be the case when the selections match the number of lines copied
Environment