VSCodeVim / Vim

:star: Vim for Visual Studio Code
http://aka.ms/vscodevim
MIT License
13.73k stars 1.31k forks source link

There is a bug in the paste and mark commands when using macros #9156

Open INSSRumia opened 1 month ago

INSSRumia commented 1 month ago

Describe the bug

If I use yy command to yank some lines, then I use p(paste) and m(mark) commands in macro, such as pma.

When I play marco, the mark a will be set at the end of next line of paste content.

To Reproduce

Steps to reproduce the behavior:

  1. Please copy the following text to your VSC.
line 1 **********
line 2 **********
line 3 **********

paste line ******
paste line ******
  1. Use 2yy command to yank the paste line ******.
  2. Move your cursor to the line 1 **********.
  3. Please type qapmaq in normal mode.
  4. The text will become like this, type `a, the cursor will jump to the beginning of paste content. This is correct situation.
    
    line 1 **********
    paste line ******      <-- Mark a at beginning of this line.
    paste line ******
    line 2 **********
    line 3 **********

paste line ** paste line **

6.  Please move your cursor to the `line 2 **********`, and type `@a` to play marco.
7.  The text will become like this, type `a,

    the cursor will jump to the end of `line 3 **********`,

line 1 ** paste line ** paste line ** line 2 ** paste line ** paste line ** line 3 ** <-- Mark a at end of this line.

paste line ** paste line **


9.  I test this procedure in Vim and VsVim, they don't exist this problem.
And I invite my friend to test this bug in his VSC, he can reproduce it.

**Environment (please complete the following information):**

- Extension (VsCodeVim) version: 12.7.3
- VSCode version: 1.91.1
- OS: Windows 11
s-kai273 commented 1 week ago

I reproduced the same behavior..

s-kai273 commented 1 week ago

I determined the cause: it lies in a function that updates the mark position in finishCurrentStep. This update is necessary when the marked line is affected by edits to surrounding lines.

Typically, a new mark is added to the current history step in the undoStack, and its isFinished property is expected to be true. However, during macro replay, the isFinished property remains false because all operations within the re cording macro should be combined into a single step in the undoStack. As a result, the property stays false, triggering the execution of the finishCurrentStep method....