Bug 211251

Summary: Change behaviour when pasting and having something block-selected
Product: [Applications] kate Reporter: Marco Poletti <poletti.marco>
Component: generalAssignee: KWrite Developers <kwrite-bugs-null>
Status: RESOLVED DUPLICATE    
Severity: wishlist CC: a.matveyakin
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In: 4.12

Description Marco Poletti 2009-10-20 21:34:03 UTC
Version:            (using KDE 4.3.1)
OS:                Linux
Installed from:    SuSE RPMs

Type the following in Kate:

foo(0,1,2);
foo(0,1,2);
foo(0,1,2);

Then switch to block-selection mode, select the 2s, press Ctrl+C, select the 3s and press Ctrl+V.

Current result:

foo(1,2,);
foo(1,2,);
foo(1,2,2);
        2
        2

Expected result:

foo(1,2,2);
foo(1,2,2);
foo(1,2,2);

Explaination:

When you paste in block selection mode, you actually do 3 things:

1) Move cursor to end of selected text
2) Delete selected text
3) Paste

This is not useful IMHO.
I'd rather do something like this:

------CODE-------
n = heightOfCurrentSelection();
m = heightOfPastedSelection();

if (m!=0)
    for (int i=0; i<n; i++) {
        
        int k = (i % m);
        
        ... // Replace the i-th row of the selection
        ... // with the k-th row of the pasted text
    }

clearSelection();
------END-CODE-------

If n==m, you get what you expect (however, not current behaviour).
With the mod, you even get interesting results when n!=m.
If n<m, the additional rows pasted are ignored (not sure what should we do in this case).

If n>m, the pasted rows are repeated to fill the selected rows. So if you have this:

foo(1,1);
foo(1,2);
foo(1,3);

and have «,2)» selected, you can add the argument «2» to all calls by selecting the «)» column and pasting.
Comment 1 Marco Poletti 2009-10-20 22:00:38 UTC
*** Bug 211254 has been marked as a duplicate of this bug. ***
Comment 2 Marco Poletti 2009-10-20 22:07:07 UTC
Sorry, two typos: (1) the first code snippet should be

foo(1,2,3);
foo(1,2,3);
foo(1,2,3);

instead of

foo(0,1,2);
foo(0,1,2);
foo(0,1,2);

And (2): at the end, I said "and have «,2)» selected" but I wanted to write  "and have «,2)» in the clipboard"
Comment 3 Pascal Létourneau 2009-10-21 01:02:45 UTC
SVN commit 1038272 by pletourn:

Always paste at the start of the selection

BUG:211251


 M  +5 -4      katedocument.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1038272
Comment 4 Marco Poletti 2009-10-21 08:00:15 UTC
That fixes the first part of the wish (n==m) and behaves good also when n<m.
The case n>m is not changed, so the last example I gave doesn't work:

Write this:

foo(1,1);
foo(1,2);
foo(1,3);

Put «,2)» in the clipboard
Select with block-selection the «)» column.
Paste.

Current behavior (with your patch):

foo(1,1,2);
foo(1,2);
foo(1,3);

Expected behavior (I expect all the selected rows to be replaced with rows from the clipboard, repeating if necessary):

foo(1,1,2);
foo(1,2,2);
foo(1,3,2);


You can make this more consistent like this:

cursorTmp = cursor;
do {
    pasteClipboardAt(cursorTmp);
    cursorTmp.y += clipboard.height;
} while (notCoveredAllLines());


So you paste all of the clipboard at each step, handling all the cases (n<m, n>m, n==m) well IMHO.
Comment 5 Dominik Haumann 2011-08-30 20:12:38 UTC
And what should happen, if the clipboard contains multiple lines?
Then your suggestion does not make sense. Should we fall back to the current behavior then?
Comment 6 Marco Poletti 2011-08-30 22:01:08 UTC
I don't really know.
My original idea was to do something like this:

Selection:
,1)
,2)
,3)

Text (all of the ")" column is selected):
foo(a);
foo(b);
foo(c);
foo(d);
foo(e);
foo(f);
foo(g);

After pasting:
foo(a,1);
foo(b,2);
foo(c,3);
foo(d,1);
foo(e,2);
foo(f,3);
foo(g,1);


But note that this is just a suggestion.
If someone has another idea, please suggest!
I would like this bug to be more like a discussion.

In fact, as you said we could also use the current behavior in this case.
I'm not sure.
Comment 7 Andrey Matveyakin 2013-08-07 20:41:19 UTC
I've implemented a simplier logic (commit 7dc070ed3d1b3e6c6e2b901b252b5b25c9d50dfb). In fact, it was what Dominik proposed: when clipboard contains exactly one line, its contents is replicated for each block row; otherwise the block is pasted as is. I thought the algorithm you've proposed is somewhat too smart and might be confusing. But if you can provide real use cases when it comes in handy, we can switch to your variant.
Comment 8 Marco Poletti 2013-08-07 23:04:17 UTC
Nice!

Well, I tried proposing a complicated version to cover more use-cases, but what you implemented is good enough for 99% of the cases IMO and will be much easier to understand for the user.

So kudos for the good work!
Comment 9 Dominik Haumann 2013-08-08 08:52:27 UTC
Fixed by Andrey in commit http://commits.kde.org/kate/7dc070ed3d1b3e6c6e2b901b252b5b25c9d50dfb

@Andrey: you forgot the ':' after BUG :-) Thanks for the cool patch, btw! Keep it coming :-)
Comment 10 Dominik Haumann 2013-09-10 08:34:57 UTC
Resolve as duplicate of bug #56935, since this one exists since 2003 (10 years ago!).

*** This bug has been marked as a duplicate of bug 56935 ***