mirror of
https://github.com/VSCodeVim/Vim.git
synced 2024-10-26 12:06:48 +03:00
parent
7a148f519d
commit
5f6ef5fada
@ -355,8 +355,8 @@ moving around:
|
|||||||
| :white_check_mark: | g~{motion} | switch case for the text that is moved over with {motion} |
|
| :white_check_mark: | g~{motion} | switch case for the text that is moved over with {motion} |
|
||||||
| :white_check_mark: | gu{motion} | make the text that is moved over with {motion} lowercase |
|
| :white_check_mark: | gu{motion} | make the text that is moved over with {motion} lowercase |
|
||||||
| :white_check_mark: | gU{motion} | make the text that is moved over with {motion} uppercase |
|
| :white_check_mark: | gU{motion} | make the text that is moved over with {motion} uppercase |
|
||||||
| :arrow_down: | {visual}g? | perform rot13 encoding on highlighted text |
|
| :white_check_mark: | {visual}g? | perform rot13 encoding on highlighted text |
|
||||||
| :arrow_down: | g?{motion} | perform rot13 encoding on the text that is moved over with {motion} |
|
| :white_check_mark: | g?{motion} | perform rot13 encoding on the text that is moved over with {motion} |
|
||||||
| :white_check_mark: | :1234: CTRL-A | add N to the number at or after the cursor |
|
| :white_check_mark: | :1234: CTRL-A | add N to the number at or after the cursor |
|
||||||
| :white_check_mark: | :1234: CTRL-X | subtract N from the number at or after the cursor |
|
| :white_check_mark: | :1234: CTRL-X | subtract N from the number at or after the cursor |
|
||||||
| :white_check_mark: | :1234: <{motion} | move the lines that are moved over with {motion} one shiftwidth left |
|
| :white_check_mark: | :1234: <{motion} | move the lines that are moved over with {motion} one shiftwidth left |
|
||||||
|
@ -1397,6 +1397,13 @@ export class CommandSearchBackwards extends BaseCommand {
|
|||||||
isMotion = true;
|
isMotion = true;
|
||||||
isJump = true;
|
isJump = true;
|
||||||
|
|
||||||
|
public doesActionApply(vimState: VimState, keysPressed: string[]): boolean {
|
||||||
|
// Prevent collision with `g?` (rot13 operator)
|
||||||
|
return (
|
||||||
|
super.doesActionApply(vimState, keysPressed) && vimState.recordedState.operator === undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public async exec(position: Position, vimState: VimState): Promise<VimState> {
|
public async exec(position: Position, vimState: VimState): Promise<VimState> {
|
||||||
globalState.searchState = new SearchState(
|
globalState.searchState = new SearchState(
|
||||||
SearchDirection.Backward,
|
SearchDirection.Backward,
|
||||||
|
@ -3,7 +3,7 @@ import * as vscode from 'vscode';
|
|||||||
import { Position, PositionDiff } from './../common/motion/position';
|
import { Position, PositionDiff } from './../common/motion/position';
|
||||||
import { Range } from './../common/motion/range';
|
import { Range } from './../common/motion/range';
|
||||||
import { configuration } from './../configuration/configuration';
|
import { configuration } from './../configuration/configuration';
|
||||||
import { Mode } from './../mode/mode';
|
import { Mode, isVisualMode } from './../mode/mode';
|
||||||
import { Register, RegisterMode } from './../register/register';
|
import { Register, RegisterMode } from './../register/register';
|
||||||
import { VimState } from './../state/vimState';
|
import { VimState } from './../state/vimState';
|
||||||
import { TextEditor } from './../textEditor';
|
import { TextEditor } from './../textEditor';
|
||||||
@ -783,6 +783,59 @@ export class CommentOperator extends BaseOperator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RegisterAction
|
||||||
|
export class ROT13Operator extends BaseOperator {
|
||||||
|
public keys = ['g', '?'];
|
||||||
|
public modes = [Mode.Normal, Mode.Visual, Mode.VisualLine, Mode.VisualBlock];
|
||||||
|
|
||||||
|
public async run(vimState: VimState, start: Position, end: Position): Promise<VimState> {
|
||||||
|
let selections: vscode.Selection[];
|
||||||
|
if (isVisualMode(vimState.currentMode)) {
|
||||||
|
selections = vimState.editor.selections;
|
||||||
|
} else if (vimState.currentRegisterMode === RegisterMode.LineWise) {
|
||||||
|
selections = [new vscode.Selection(start.getLineBegin(), end.getLineEnd())];
|
||||||
|
} else {
|
||||||
|
selections = [new vscode.Selection(start, end.getRight())];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const range of selections) {
|
||||||
|
const original = TextEditor.getText(range);
|
||||||
|
vimState.recordedState.transformations.push({
|
||||||
|
type: 'replaceText',
|
||||||
|
text: ROT13Operator.rot13(original),
|
||||||
|
start: Position.FromVSCodePosition(range.start),
|
||||||
|
end: Position.FromVSCodePosition(range.end),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return vimState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://en.wikipedia.org/wiki/ROT13
|
||||||
|
*/
|
||||||
|
public static rot13(str: string) {
|
||||||
|
return str
|
||||||
|
.split('')
|
||||||
|
.map((char: string) => {
|
||||||
|
let charCode = char.charCodeAt(0);
|
||||||
|
|
||||||
|
if (char >= 'a' && char <= 'z') {
|
||||||
|
const a = 'a'.charCodeAt(0);
|
||||||
|
charCode = ((charCode - a + 13) % 26) + a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char >= 'A' && char <= 'Z') {
|
||||||
|
const A = 'A'.charCodeAt(0);
|
||||||
|
charCode = ((charCode - A + 13) % 26) + A;
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.fromCharCode(charCode);
|
||||||
|
})
|
||||||
|
.join('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RegisterAction
|
@RegisterAction
|
||||||
export class CommentBlockOperator extends BaseOperator {
|
export class CommentBlockOperator extends BaseOperator {
|
||||||
public keys = ['g', 'C'];
|
public keys = ['g', 'C'];
|
||||||
|
@ -49,7 +49,8 @@ export class SneakForward extends BaseMovement {
|
|||||||
|
|
||||||
const ignorecase =
|
const ignorecase =
|
||||||
configuration.sneakUseIgnorecaseAndSmartcase &&
|
configuration.sneakUseIgnorecaseAndSmartcase &&
|
||||||
configuration.ignorecase && !(configuration.smartcase && /[A-Z]/.test(searchString));
|
configuration.ignorecase &&
|
||||||
|
!(configuration.smartcase && /[A-Z]/.test(searchString));
|
||||||
|
|
||||||
// Check for matches
|
// Check for matches
|
||||||
if (ignorecase) {
|
if (ignorecase) {
|
||||||
@ -112,7 +113,8 @@ export class SneakBackward extends BaseMovement {
|
|||||||
|
|
||||||
const ignorecase =
|
const ignorecase =
|
||||||
configuration.sneakUseIgnorecaseAndSmartcase &&
|
configuration.sneakUseIgnorecaseAndSmartcase &&
|
||||||
configuration.ignorecase && !(configuration.smartcase && /[A-Z]/.test(searchString));
|
configuration.ignorecase &&
|
||||||
|
!(configuration.smartcase && /[A-Z]/.test(searchString));
|
||||||
|
|
||||||
// Check for matches
|
// Check for matches
|
||||||
if (ignorecase) {
|
if (ignorecase) {
|
||||||
|
@ -45,10 +45,7 @@ class VimrcImpl {
|
|||||||
const mappings = (() => {
|
const mappings = (() => {
|
||||||
switch (remap.keyRemappingType) {
|
switch (remap.keyRemappingType) {
|
||||||
case 'map':
|
case 'map':
|
||||||
return [
|
return [config.normalModeKeyBindings, config.visualModeKeyBindings];
|
||||||
config.normalModeKeyBindings,
|
|
||||||
config.visualModeKeyBindings,
|
|
||||||
];
|
|
||||||
case 'nmap':
|
case 'nmap':
|
||||||
return [config.normalModeKeyBindings];
|
return [config.normalModeKeyBindings];
|
||||||
case 'vmap':
|
case 'vmap':
|
||||||
|
@ -113,11 +113,11 @@ export class RecordedState {
|
|||||||
*/
|
*/
|
||||||
public get operator(): BaseOperator {
|
public get operator(): BaseOperator {
|
||||||
let list = this.actionsRun.filter(a => a instanceof BaseOperator).reverse();
|
let list = this.actionsRun.filter(a => a instanceof BaseOperator).reverse();
|
||||||
return list[0] as any;
|
return list[0] as BaseOperator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get operators(): BaseOperator[] {
|
public get operators(): BaseOperator[] {
|
||||||
return this.actionsRun.filter(a => a instanceof BaseOperator).reverse() as any;
|
return this.actionsRun.filter(a => a instanceof BaseOperator).reverse() as BaseOperator[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +128,7 @@ export class RecordedState {
|
|||||||
|
|
||||||
// TODO - disregard <Esc>, then assert this is of length 1.
|
// TODO - disregard <Esc>, then assert this is of length 1.
|
||||||
|
|
||||||
return list[0] as any;
|
return list[0] as BaseCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get hasRunAMovement(): boolean {
|
public get hasRunAMovement(): boolean {
|
||||||
@ -167,7 +167,8 @@ export class RecordedState {
|
|||||||
mode !== Mode.SearchInProgressMode &&
|
mode !== Mode.SearchInProgressMode &&
|
||||||
mode !== Mode.CommandlineInProgress &&
|
mode !== Mode.CommandlineInProgress &&
|
||||||
(this.hasRunAMovement ||
|
(this.hasRunAMovement ||
|
||||||
mode === Mode.Visual || mode === Mode.VisualLine ||
|
mode === Mode.Visual ||
|
||||||
|
mode === Mode.VisualLine ||
|
||||||
(this.operators.length > 1 &&
|
(this.operators.length > 1 &&
|
||||||
this.operators.reverse()[0].constructor === this.operators.reverse()[1].constructor))
|
this.operators.reverse()[0].constructor === this.operators.reverse()[1].constructor))
|
||||||
);
|
);
|
||||||
|
@ -21,7 +21,11 @@ suite('Horizontal split', () => {
|
|||||||
await commandLine.Run(cmd, modeHandler.vimState);
|
await commandLine.Run(cmd, modeHandler.vimState);
|
||||||
await WaitForEditorsToClose(2);
|
await WaitForEditorsToClose(2);
|
||||||
|
|
||||||
assert.strictEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
|
assert.strictEqual(
|
||||||
|
vscode.window.visibleTextEditors.length,
|
||||||
|
2,
|
||||||
|
'Editor did not split in 1 sec'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -21,7 +21,11 @@ suite('Vertical split', () => {
|
|||||||
await commandLine.Run(cmd, modeHandler.vimState);
|
await commandLine.Run(cmd, modeHandler.vimState);
|
||||||
await WaitForEditorsToClose(2);
|
await WaitForEditorsToClose(2);
|
||||||
|
|
||||||
assert.strictEqual(vscode.window.visibleTextEditors.length, 2, 'Editor did not split in 1 sec');
|
assert.strictEqual(
|
||||||
|
vscode.window.visibleTextEditors.length,
|
||||||
|
2,
|
||||||
|
'Editor did not split in 1 sec'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
56
test/operator/rot13.test.ts
Normal file
56
test/operator/rot13.test.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import * as assert from 'assert';
|
||||||
|
|
||||||
|
import { getTestingFunctions } from '../testSimplifier';
|
||||||
|
|
||||||
|
import { setupWorkspace, cleanUpWorkspace } from '../testUtils';
|
||||||
|
import { ROT13Operator } from '../../src/actions/operator';
|
||||||
|
|
||||||
|
suite('rot13 operator', () => {
|
||||||
|
const { newTest, newTestOnly, newTestSkip } = getTestingFunctions();
|
||||||
|
|
||||||
|
setup(async () => {
|
||||||
|
await setupWorkspace();
|
||||||
|
});
|
||||||
|
|
||||||
|
teardown(cleanUpWorkspace);
|
||||||
|
|
||||||
|
test('rot13() unit test', () => {
|
||||||
|
const testCases = [
|
||||||
|
['abcdefghijklmnopqrstuvwxyz', 'nopqrstuvwxyzabcdefghijklm'],
|
||||||
|
['ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'NOPQRSTUVWXYZABCDEFGHIJKLM'],
|
||||||
|
['!@#$%^&*()', '!@#$%^&*()'],
|
||||||
|
['âéü', 'âéü'],
|
||||||
|
];
|
||||||
|
for (const [input, output] of testCases) {
|
||||||
|
assert.strictEqual(ROT13Operator.rot13(input), output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newTest({
|
||||||
|
title: 'g?j works',
|
||||||
|
start: ['a|bc', 'def', 'ghi'],
|
||||||
|
keysPressed: 'g?j',
|
||||||
|
end: ['n|op', 'qrs', 'ghi'],
|
||||||
|
});
|
||||||
|
|
||||||
|
newTest({
|
||||||
|
title: 'g? in visual mode works',
|
||||||
|
start: ['a|bc', 'def', 'ghi'],
|
||||||
|
keysPressed: 'vj$g?',
|
||||||
|
end: ['a|op', 'qrs', 'ghi'],
|
||||||
|
});
|
||||||
|
|
||||||
|
newTest({
|
||||||
|
title: 'g? in visual line mode works',
|
||||||
|
start: ['a|bc', 'def', 'ghi'],
|
||||||
|
keysPressed: 'Vj$g?',
|
||||||
|
end: ['|nop', 'qrs', 'ghi'],
|
||||||
|
});
|
||||||
|
|
||||||
|
newTest({
|
||||||
|
title: 'g? in visual block mode works',
|
||||||
|
start: ['a|bc', 'def', 'ghi'],
|
||||||
|
keysPressed: '<C-v>j$g?',
|
||||||
|
end: ['a|op', 'drs', 'ghi'],
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user