Repository: spyder-ide/spyder

Issue:
Duplicate line down has changed behavior with Duplicate line up
Previously when you `duplicate line down` the newly created line was also selected. This is imo prefered behaviour because you could immediately move the newly copied lines with `move line down`. 

In Spyder 4.1.1 this has changed and the original lines stay selected, which is the old `duplicate line up` behaviour. Thus, one has to move the original lines through the newly copied ones and then to the location where you want them.

Maybe this is the wanted behaviour, so I'm not sure about reporting it, and there's an easy workaround - switch the current shortcuts between the two commands to retain the old behaviour :smile: 


Discussion:
Thoughts on this @spyder-ide/core-developers ?
I'm unsure if we changed that behavior intentionally. Just in case, as far as I know, the last PR changing something regarding the duplicate lines functionality was PR #11122 (although I think that only changes the shortcuts names)
Yeah, I think this could have been changed by @jnsebgosselin in that PR.
If I'm thinking about this correctly there is no difference between copy line up or down except where the select line ends up after the completion of the task. This is a question like whether "natural" scrolling is more intuitive. I can make both ways make sense in my mind.

If a compare this operation to duplicating in graphics software(which is where I got the duplicate name idea) the duplicate is usually selected after the operation to allow editing on the duplicate not the origional. So we would have it backward in this case.
Yes I think I inverted things by mistake. I can submit a PR that will switch this back to the original behaviour, this is very simple to achieve.

I just need to inverse the `after_current_line`  argument in `self.__duplicate_line_or_selection` calls and update the tests probably.
Thanks for your help with that @jnsebgosselin!

Resolving patch:
diff --git a/spyder/plugins/editor/widgets/base.py b/spyder/plugins/editor/widgets/base.py
--- a/spyder/plugins/editor/widgets/base.py
+++ b/spyder/plugins/editor/widgets/base.py
@@ -637,14 +637,14 @@ def duplicate_line_down(self):
         Copy current line or selected text and paste the duplicated text
         *after* the current line or selected text.
         """
-        self.__duplicate_line_or_selection(after_current_line=True)
+        self.__duplicate_line_or_selection(after_current_line=False)
 
     def duplicate_line_up(self):
         """
         Copy current line or selected text and paste the duplicated text
         *before* the current line or selected text.
         """
-        self.__duplicate_line_or_selection(after_current_line=False)
+        self.__duplicate_line_or_selection(after_current_line=True)
 
     def __move_line_or_selection(self, after_current_line=True):
         """Move current line or selected text"""


Test patch:
diff --git a/spyder/plugins/editor/widgets/tests/test_editor.py b/spyder/plugins/editor/widgets/tests/test_editor.py
--- a/spyder/plugins/editor/widgets/tests/test_editor.py
+++ b/spyder/plugins/editor/widgets/tests/test_editor.py
@@ -256,7 +256,7 @@ def test_copy_lines_down_up(editor_bot, mocker, qtbot):
     # Copy lines down.
     editor.duplicate_line_down()
     qtbot.wait(100)
-    assert editor.get_cursor_line_column() == (2, 0)
+    assert editor.get_cursor_line_column() == (4, 0)
     assert editor.textCursor().selection().toPlainText() == 'a = 1\nprint(a)\n'
     assert editor.toPlainText() == 'a = 1\nprint(a)\n' * 2 + '\nx = 2\n'