VSCodeVim / Vim

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

Fix going into visual mode when filling out snippets with adjacent placeholders etc #9239

Open semicube opened 2 months ago

semicube commented 2 months ago

What this PR does / why we need it:

Fixes going into visual mode on certain placeholders when you fill out vscode user snippets. Particularly this occurs when the placeholders are placed adjacent to each other (not seperated by a character, see Issue #9236), or when the snippet starts from a placeholder (see Issues #5969, #7068).

Note on the fix:

I noticed that in each of these placeholder cases where the cursor goes into visual mode, isSnippetSelectionChange() inside ModeHandler.handleSelectionChange() returns false even though it is a snippet selection.

Modifying isSnippetSelectionChange() to only consider the previous cursors that represent a selection (c.start and c.stop are not equal) when comparing with e.selections, seems to have fixed the issue.

Which issue(s) this PR fixes

Fixes #9236, #7068, #6465, #5969

Special notes for your reviewer:

HenryTSZ commented 2 months ago

add test case for this

https://github.com/VSCodeVim/Vim/blob/2cb95520f10f0b7fe439f4f3d97a9c7f214b3416/test/mode/modeInsert.test.ts#L712-L724

append after this

    test('handles snippet when filling out snippets with adjacent placeholder', async () => {
      await modeHandler.handleKeyEvent('i');
      await vscode.commands.executeCommand('editor.action.insertSnippet', {
        snippet: '${3:foo} ${1:bar}${2:baz}',
      });
      await modeHandler.handleMultipleKeyEvents(['o', 'n', 'e']);
      await vscode.commands.executeCommand('jumpToNextSnippetPlaceholder');
      assertEqualLines(['foo onebaz']);
      assert.strictEqual(modeHandler.currentMode, Mode.Insert);
    });

    test('handles snippet with multiple cursors and start with a placeholder', async () => {
      await modeHandler.handleKeyEvent('i');
      await vscode.commands.executeCommand('editor.action.insertSnippet', {
        snippet: '${1:bar} ${2:baz} $1',
      });
      assertEqualLines(['bar baz bar']);
      assert.strictEqual(modeHandler.currentMode, Mode.Insert);
    });