Skip to content

Commit

Permalink
feat: implements usage of insert to toggle between modes (as per #1787
Browse files Browse the repository at this point in the history
) (#2356)

* feat: closes #1787. uses insert as toggle between insert and replace modes
* tests: add tests for activating replace mode with insert
  • Loading branch information
jpoon authored Feb 26, 2018
1 parent 0b6dec0 commit d66a2db
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 12 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@
"command": "extension.vim_end",
"when": "editorTextFocus && vim.active && !inDebugRepl && vim.mode != 'Insert'"
},
{
"key": "Insert",
"command": "extension.vim_insert",
"when": "editorTextFocus && vim.active && !inDebugRepl"
},
{
"key": "cmd+left",
"command": "extension.vim_cmd+left",
Expand Down
32 changes: 28 additions & 4 deletions src/actions/commands/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,17 @@ class CommandEscReplaceMode extends BaseCommand {
}
}

@RegisterAction
class CommandInsertReplaceMode extends BaseCommand {
modes = [ModeName.Replace];
keys = ['<insert>'];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
vimState.currentMode = ModeName.Insert;
return vimState;
}
}

abstract class CommandEditorScroll extends BaseCommand {
modes = [ModeName.Normal, ModeName.Visual, ModeName.VisualLine, ModeName.VisualBlock];
runsOnceForEachCountPrefix = false;
Expand Down Expand Up @@ -653,7 +664,7 @@ class CommandMoveHalfPageUp extends CommandEditorScroll {
@RegisterAction
export class CommandInsertAtCursor extends BaseCommand {
modes = [ModeName.Normal];
keys = ['i'];
keys = [['i'], ['<insert>']];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
vimState.currentMode = ModeName.Insert;
Expand All @@ -679,10 +690,24 @@ export class CommandInsertAtCursor extends BaseCommand {
}

@RegisterAction
class CommandReplaceAtCursor extends BaseCommand {
class CommandReplaceAtCursorFromNormalMode extends BaseCommand {
modes = [ModeName.Normal];
keys = ['R'];
runsOnceForEachCountPrefix = false;

public async exec(position: Position, vimState: VimState): Promise<VimState> {
let timesToRepeat = vimState.recordedState.count || 1;

vimState.currentMode = ModeName.Replace;
vimState.replaceState = new ReplaceState(position, timesToRepeat);

return vimState;
}
}

@RegisterAction
class CommandReplaceAtCursorFromInsertMode extends BaseCommand {
modes = [ModeName.Insert];
keys = ['<insert>'];

public async exec(position: Position, vimState: VimState): Promise<VimState> {
let timesToRepeat = vimState.recordedState.count || 1;
Expand Down Expand Up @@ -750,7 +775,6 @@ class CommandReplaceInReplaceMode extends BaseCommand {
replaceState.newChars.push(char);
}

vimState.currentMode = ModeName.Replace;
return vimState;
}
}
Expand Down
7 changes: 4 additions & 3 deletions test/mode/modeInsert.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ suite('Mode Insert', () => {
teardown(cleanUpWorkspace);

test('can be activated', async () => {
let activationKeys = ['o', 'I', 'i', 'O', 'a', 'A'];
let activationKeys = ['o', 'I', 'i', 'O', 'a', 'A', '<insert>'];

for (let key of activationKeys) {
await modeHandler.handleKeyEvent('<Esc>');
assertEqual(modeHandler.currentMode.name, ModeName.Normal);

await modeHandler.handleKeyEvent(key);
assertEqual(modeHandler.currentMode.name, ModeName.Insert);

await modeHandler.handleKeyEvent('<Esc>');
}
});

Expand Down
2 changes: 1 addition & 1 deletion test/mode/modeNormal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ suite('Mode Normal', () => {

teardown(cleanUpWorkspace);

test('can be activated', async () => {
test('Can be activated', async () => {
let activationKeys = ['<Esc>', '<C-[>'];

for (let key of activationKeys) {
Expand Down
35 changes: 32 additions & 3 deletions test/mode/modeReplace.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getTestingFunctions } from '../testSimplifier';
import { cleanUpWorkspace, setupWorkspace } from './../testUtils';
import { ModeName } from '../../src/mode/mode';

suite('Mode Replace', () => {
let { newTest, newTestOnly } = getTestingFunctions();
Expand All @@ -10,87 +11,115 @@ suite('Mode Replace', () => {

teardown(cleanUpWorkspace);

newTest({
title: 'Can activate with <insert> from Insert mode',
start: ['|'],
keysPressed: 'ia<insert>',
end: ['a|'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can activate with R from Normal mode',
start: ['123|456'],
keysPressed: 'R',
end: ['123|456'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can handle R',
start: ['123|456'],
keysPressed: 'Rab',
end: ['123ab|6'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can handle R',
title: 'Can handle R past current line',
start: ['123|456'],
keysPressed: 'Rabcd',
end: ['123abcd|'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can handle R and quit Replace Mode',
title: 'Can handle R and exit Replace Mode',
start: ['|123456'],
keysPressed: 'Rabc<Esc>',
end: ['ab|c456'],
endMode: ModeName.Normal,
});

newTest({
title: 'Can handle R across lines',
start: ['123|456', '789'],
keysPressed: 'Rabcd\nefg',
end: ['123abcd', 'efg|', '789'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can handle R across lines and quit Replace Mode',
title: 'Can handle R across lines and exit Replace Mode',
start: ['123|456', '789'],
keysPressed: 'Rabcd\nefg<Esc>',
end: ['123abcd', 'ef|g', '789'],
endMode: ModeName.Normal,
});

newTest({
title: 'Can handle R with {count}',
start: ['123|456', '789'],
keysPressed: '3Rabc\ndef<Esc>',
end: ['123abc', 'defabc', 'defabc', 'de|f', '789'],
endMode: ModeName.Normal,
});

newTest({
title: 'Can handle backspace',
start: ['123|456'],
keysPressed: 'Rabc<BS><BS><BS>',
end: ['123|456'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can handle backspace',
start: ['123|456'],
keysPressed: 'Rabcd<BS><BS><BS><BS><BS>',
end: ['12|3456'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can handle backspace across lines',
start: ['123|456'],
keysPressed: 'Rabcd\nef<BS><BS><BS><BS><BS>',
end: ['123ab|6'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can handle arrows',
start: ['123|456'],
keysPressed: 'Rabc<left><BS><BS>',
end: ['123|abc'],
endMode: ModeName.Replace,
});

newTest({
title: 'Can handle .',
start: ['123|456', '123456'],
keysPressed: 'Rabc<Esc>j0.',
end: ['123abc', 'ab|c456'],
endMode: ModeName.Normal,
});

newTest({
title: 'Can handle . across lines',
start: ['123|456', '123456'],
keysPressed: 'Rabc\ndef<Esc>j0.',
end: ['123abc', 'def', 'abc', 'de|f'],
endMode: ModeName.Normal,
});
});
2 changes: 1 addition & 1 deletion test/motion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Position } from './../src/common/motion/position';
import { TextEditor } from './../src/textEditor';
import { cleanUpWorkspace, setupWorkspace } from './testUtils';

suite('old motion tests', () => {
suite('basic motion', () => {
let text: string[] = ['mary had', 'a', 'little lamb', ' whose fleece was '];

suiteSetup(async () => {
Expand Down

0 comments on commit d66a2db

Please sign in to comment.