Skip to content

Commit

Permalink
Fix bugs with a remapped <Esc> in insert mode (#4829)
Browse files Browse the repository at this point in the history
- Fix DotCommand deleting extra character when used after a remapped <Esc> in insert mode
Fixes #4817
Fixes #4814

- Fix remapped <Esc> leaving trailing character when used with multiple cursors
Fixes #4811

Co-authored-by: Jason Fields <jasonfields4@gmail.com>
  • Loading branch information
berknam and J-Fields committed May 12, 2020
1 parent 357dc89 commit 67cde57
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 10 deletions.
29 changes: 19 additions & 10 deletions src/history/historyTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,16 +609,25 @@ export class HistoryTracker {
this.currentContentChanges.length - n,
this.currentContentChanges.length
);
const firstRemovedChange = removedChanges[0];

// Remove the characters from the editor.
await vscode.window.activeTextEditor?.edit((edit) =>
edit.delete(
new vscode.Range(
firstRemovedChange!.range.start,
firstRemovedChange!.range.end.translate(0, n)
)
)

// Remove the characters from the editor in reverse order otherwise the characters
// position would change.
await vscode.window.activeTextEditor?.edit((edit) => {
for (const removedChange of removedChanges.reverse()) {
edit.delete(
new vscode.Range(
removedChange.range.start,
removedChange.range.end.translate({ characterDelta: 1 })
)
);
}
});

// Remove the previous deletions from currentContentChanges otherwise the DotCommand
// or a recorded macro will be deleting a character that wasn't typed.
this.currentContentChanges.splice(
this.currentContentChanges.length - removedChanges.length,
removedChanges.length
);

// We can't ignore the change, because that would mean that addChange() doesn't run.
Expand Down
39 changes: 39 additions & 0 deletions test/mode/normalModeTests/dot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,42 @@ suite('Repeat content change', () => {
end: ['\tonecb', 'tw|co'],
});
});

suite('Dot Operator repeat with remap', () => {
const { newTest, newTestOnly } = getTestingFunctions();

setup(async () => {
const configuration = new Configuration();
configuration.insertModeKeyBindings = [
{
before: ['j', 'j', 'k'],
after: ['<esc>'],
},
];
configuration.normalModeKeyBindings = [
{
before: ['<leader>', 'w'],
after: ['d', 'w'],
},
];
configuration.leader = ' ';

await setupWorkspace(configuration);
});

teardown(cleanUpWorkspace);

newTest({
title: "Can repeat content change using 'jjk' mapped to '<Esc>' without trailing characters",
start: ['on|e', 'two'],
keysPressed: 'ciwfoojjkj.',
end: ['foo', 'fo|o'],
});

newTest({
title: "Can repeat '<leader>w' when mapped to 'dw'",
start: ['|one two three'],
keysPressed: ' w.',
end: ['|three'],
});
});
27 changes: 27 additions & 0 deletions test/multicursor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as assert from 'assert';
import { getAndUpdateModeHandler } from '../extension';
import { ModeHandler } from '../src/mode/modeHandler';
import { assertEqualLines, cleanUpWorkspace, setupWorkspace } from './testUtils';
import { getTestingFunctions } from './testSimplifier';
import { Configuration } from './testConfiguration';

suite('Multicursor', () => {
let modeHandler: ModeHandler;
Expand Down Expand Up @@ -103,3 +105,28 @@ suite('Multicursor', () => {
assert.strictEqual(modeHandler.vimState.cursors.length, 2);
});
});

suite('Multicursor with remaps', () => {
const { newTest, newTestOnly } = getTestingFunctions();

setup(async () => {
const configuration = new Configuration();
configuration.insertModeKeyBindings = [
{
before: ['j', 'j', 'k'],
after: ['<esc>'],
},
];

await setupWorkspace(configuration);
});

teardown(cleanUpWorkspace);

newTest({
title: "Using 'jjk' mapped to '<Esc>' doesn't leave trailing characters",
start: ['o|ne', 'two'],
keysPressed: '<C-v>jAfoojjk<Esc>',
end: ['onfo|oe', 'twfooo'],
});
});

0 comments on commit 67cde57

Please sign in to comment.