From cac36627aabbcdff99d0df18cc85890e7fa6672f Mon Sep 17 00:00:00 2001 From: Matt Ellis <m.t.ellis@gmail.com> Date: Fri, 12 Apr 2024 18:54:35 -0700 Subject: [PATCH] Support 0 in copy command to copy to top of file --- .../commands/CopyCommandTest.kt | 167 +++++++++++++++++- .../model/commands/CopyTextCommand.kt | 37 ++-- 2 files changed, 192 insertions(+), 12 deletions(-) diff --git a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/CopyCommandTest.kt b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/CopyCommandTest.kt index 66ef776ae..2ea407441 100644 --- a/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/CopyCommandTest.kt +++ b/src/test/java/org/jetbrains/plugins/ideavim/ex/implementation/commands/CopyCommandTest.kt @@ -32,5 +32,170 @@ class CopyCommandTest : VimTestCase() { """.trimIndent()) } - // TODO: Add another test with 'nostartofline'. This should maintain the cursor column + @VimBehaviorDiffers( + originalVimAfter = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Nunc tincidunt viverra ligula non ${c}scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """, + description = "Caret placement is wrong", + shouldBeFixed = true + ) + @Test + fun `test duplicate line below with 'nostartofline'`() { + doTest( + exCommand("copy ."), + """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non ${c}scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """.trimIndent(), + """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + ${c}Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """.trimIndent(), + ) { + enterCommand("set nostartofline") + } + } + + @VimBehaviorDiffers( + originalVimAfter = """ + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + ${c}accumsan vitae, facilisis ac nulla. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """, + description = "Caret placement is incorrect", + shouldBeFixed = true + ) + @Test + fun `test copy range to above first line`() { + doTest( + exCommand("3,4copy 0"), + """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ${c}ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """.trimIndent(), + """ + ${c}Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """.trimIndent(), + ) + } + + @VimBehaviorDiffers( + originalVimAfter = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + ${c}accumsan vitae, facilisis ac nulla. + """, + description = "Caret placement is incorrect", + shouldBeFixed = true + ) + @Test + fun `test copy range to below last line`() { + doTest( + exCommand("3,4copy $"), + """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ${c}ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """.trimIndent(), + """ + |Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + |Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + |Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + |accumsan vitae, facilisis ac nulla. + |${c}Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + |accumsan vitae, facilisis ac nulla. + |""".trimMargin(), + ) + } + + @VimBehaviorDiffers( + originalVimAfter = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + ${c}accumsan vitae, facilisis ac nulla. + """, + description = "Caret placement is incorrect", + shouldBeFixed = true + ) + @Test + fun `test copy with no space between command and address`() { + doTest( + exCommand("3,4copy$"), + """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ${c}ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """.trimIndent(), + """ + |Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + |Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + |Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + |accumsan vitae, facilisis ac nulla. + |${c}Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + |accumsan vitae, facilisis ac nulla. + |""".trimMargin(), + ) + assertPluginError(false) + } + + @VimBehaviorDiffers( + originalVimAfter = """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + ${c}accumsan vitae, facilisis ac nulla. + """, + description = "Caret placement is wrong", + shouldBeFixed = true + ) + @Test + fun `test copy to below first address of range with no errors`() { + doTest( + exCommand("3,4copy 4,1,2,.,0"), + """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ${c}ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """.trimIndent(), + """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas efficitur nec odio vel malesuada. + Nunc tincidunt viverra ligula non scelerisque. Aliquam erat volutpat. Praesent in fermentum orci. + ${c}Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + Fusce sit amet mi ut purus volutpat vulputate vitae sed tortor. Aliquam felis neque, varius eu + accumsan vitae, facilisis ac nulla. + """.trimIndent(), + ) + assertPluginError(false) + } } diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/CopyTextCommand.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/CopyTextCommand.kt index def41bfeb..811845472 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/CopyTextCommand.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/vimscript/model/commands/CopyTextCommand.kt @@ -14,9 +14,9 @@ import com.maddyhome.idea.vim.api.VimEditor import com.maddyhome.idea.vim.api.getText import com.maddyhome.idea.vim.api.injector import com.maddyhome.idea.vim.command.OperatorArguments -import com.maddyhome.idea.vim.state.mode.SelectionType import com.maddyhome.idea.vim.ex.ranges.Range import com.maddyhome.idea.vim.put.PutData +import com.maddyhome.idea.vim.state.mode.SelectionType import com.maddyhome.idea.vim.vimscript.model.ExecutionResult /** @@ -41,16 +41,31 @@ public data class CopyTextCommand(val range: Range, val argument: String) : Comm val transferableData = injector.clipboardManager.getTransferableData(editor, range, text) val textData = PutData.TextData(text, SelectionType.LINE_WISE, transferableData, null) - val putData = PutData( - textData, - null, - 1, - insertTextBeforeCaret = false, - rawIndent = true, - caretAfterInsertedText = false, - putToLine = address1 - 1, - ) - injector.put.putTextForCaret(editor, caret, context, putData) + var mutableCaret = caret + val putData = if (address1 == 0) { + // TODO: This should maintain current column location + mutableCaret = mutableCaret.moveToOffset(0) + PutData( + textData, + null, + 1, + insertTextBeforeCaret = true, + rawIndent = true, + caretAfterInsertedText = false, + ) + } + else { + PutData( + textData, + null, + 1, + insertTextBeforeCaret = false, + rawIndent = true, + caretAfterInsertedText = false, + putToLine = address1 - 1 + ) + } + injector.put.putTextForCaret(editor, mutableCaret, context, putData) } return ExecutionResult.Success }