mirror of
https://github.com/VSCodeVim/Vim.git
synced 2024-11-10 00:59:44 +03:00
Implements Global state (#1179)
* Made GlobalState hold search and . action values * Adds a test to check . action across editors * Added util helper that waits for tab changes * Added all global search history tests * Fixed global search tests, removed timeout, sleeps * Moved searchState and searchStateIndex to global * Tab change recalculates search ranges * Global . test to await tab change not timeouts * Moved getters, setters to globalState + cleanup * Fixed waitForTabChange case of synchronous tab change
This commit is contained in:
parent
ca7bef095b
commit
ac871462d1
@ -730,7 +730,7 @@ class CommandInsertRegisterContentInSearchMode extends BaseCommand {
|
||||
text += "\n";
|
||||
}
|
||||
|
||||
const searchState = vimState.searchState!;
|
||||
const searchState = vimState.globalState.searchState!;
|
||||
searchState.searchString += text;
|
||||
return vimState;
|
||||
}
|
||||
@ -882,8 +882,8 @@ class CommandEsc extends BaseCommand {
|
||||
}
|
||||
|
||||
if (vimState.currentMode === ModeName.SearchInProgressMode) {
|
||||
if (vimState.searchState) {
|
||||
vimState.cursorPosition = vimState.searchState.searchCursorStartPosition;
|
||||
if (vimState.globalState.searchState) {
|
||||
vimState.cursorPosition = vimState.globalState.searchState.searchCursorStartPosition;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1425,7 +1425,7 @@ class CommandInsertInSearchMode extends BaseCommand {
|
||||
|
||||
public async exec(position: Position, vimState: VimState): Promise<VimState> {
|
||||
const key = this.keysPressed[0];
|
||||
const searchState = vimState.searchState!;
|
||||
const searchState = vimState.globalState.searchState!;
|
||||
|
||||
// handle special keys first
|
||||
if (key === "<BS>" || key === "<shift+BS>") {
|
||||
@ -1435,55 +1435,56 @@ class CommandInsertInSearchMode extends BaseCommand {
|
||||
|
||||
// Repeat the previous search if no new string is entered
|
||||
if (searchState.searchString === "") {
|
||||
const prevSearchList = vimState.searchStatePrevious!;
|
||||
const prevSearchList = vimState.globalState.searchStatePrevious!;
|
||||
if (prevSearchList.length > 0) {
|
||||
searchState.searchString = prevSearchList[prevSearchList.length - 1].searchString;
|
||||
}
|
||||
}
|
||||
|
||||
// Store this search if different than previous
|
||||
if (vimState.searchStatePrevious.length !== 0) {
|
||||
if (searchState.searchString !== vimState.searchStatePrevious[vimState.searchStatePrevious.length - 1]!.searchString) {
|
||||
vimState.searchStatePrevious.push(searchState);
|
||||
if (vimState.globalState.searchStatePrevious.length !== 0) {
|
||||
let previousSearchState = vimState.globalState.searchStatePrevious;
|
||||
if (searchState.searchString !== previousSearchState[previousSearchState.length - 1]!.searchString) {
|
||||
previousSearchState.push(searchState);
|
||||
}
|
||||
} else {
|
||||
vimState.searchStatePrevious.push(searchState);
|
||||
vimState.globalState.searchStatePrevious.push(searchState);
|
||||
}
|
||||
|
||||
// Make sure search history does not exceed configuration option
|
||||
if (vimState.searchStatePrevious.length > Configuration.history) {
|
||||
vimState.searchStatePrevious.splice(0, 1);
|
||||
if (vimState.globalState.searchStatePrevious.length > Configuration.history) {
|
||||
vimState.globalState.searchStatePrevious.splice(0, 1);
|
||||
}
|
||||
|
||||
// Update the index to the end of the search history
|
||||
vimState.searchStateIndex = vimState.searchStatePrevious.length - 1;
|
||||
vimState.globalState.searchStateIndex = vimState.globalState.searchStatePrevious.length - 1;
|
||||
|
||||
// Move cursor to next match
|
||||
vimState.cursorPosition = searchState.getNextSearchMatchPosition(vimState.cursorPosition).pos;
|
||||
|
||||
return vimState;
|
||||
} else if (key === "<up>") {
|
||||
const prevSearchList = vimState.searchStatePrevious!;
|
||||
if (prevSearchList[vimState.searchStateIndex] !== undefined) {
|
||||
searchState.searchString = prevSearchList[vimState.searchStateIndex].searchString;
|
||||
vimState.searchStateIndex -= 1;
|
||||
const prevSearchList = vimState.globalState.searchStatePrevious!;
|
||||
if (prevSearchList[vimState.globalState.searchStateIndex] !== undefined) {
|
||||
searchState.searchString = prevSearchList[vimState.globalState.searchStateIndex].searchString;
|
||||
vimState.globalState.searchStateIndex -= 1;
|
||||
}
|
||||
} else if (key === "<down>") {
|
||||
const prevSearchList = vimState.searchStatePrevious!;
|
||||
if (prevSearchList[vimState.searchStateIndex] !== undefined) {
|
||||
searchState.searchString = prevSearchList[vimState.searchStateIndex].searchString;
|
||||
vimState.searchStateIndex += 1;
|
||||
const prevSearchList = vimState.globalState.searchStatePrevious!;
|
||||
if (prevSearchList[vimState.globalState.searchStateIndex] !== undefined) {
|
||||
searchState.searchString = prevSearchList[vimState.globalState.searchStateIndex].searchString;
|
||||
vimState.globalState.searchStateIndex += 1;
|
||||
}
|
||||
} else {
|
||||
searchState.searchString += this.keysPressed[0];
|
||||
}
|
||||
|
||||
// Clamp the history index to stay within bounds of search history length
|
||||
if (vimState.searchStateIndex > vimState.searchStatePrevious.length - 1) {
|
||||
vimState.searchStateIndex = vimState.searchStatePrevious.length - 1;
|
||||
if (vimState.globalState.searchStateIndex > vimState.globalState.searchStatePrevious.length - 1) {
|
||||
vimState.globalState.searchStateIndex = vimState.globalState.searchStatePrevious.length - 1;
|
||||
}
|
||||
if (vimState.searchStateIndex < 0) {
|
||||
vimState.searchStateIndex = 0;
|
||||
if (vimState.globalState.searchStateIndex < 0) {
|
||||
vimState.globalState.searchStateIndex = 0;
|
||||
}
|
||||
|
||||
return vimState;
|
||||
@ -1498,7 +1499,7 @@ class CommandEscInSearchMode extends BaseCommand {
|
||||
|
||||
public async exec(position: Position, vimState: VimState): Promise<VimState> {
|
||||
vimState.currentMode = ModeName.Normal;
|
||||
vimState.searchState = undefined;
|
||||
vimState.globalState.searchState = undefined;
|
||||
|
||||
return vimState;
|
||||
}
|
||||
@ -1511,7 +1512,7 @@ class CommandCtrlVInSearchMode extends BaseCommand {
|
||||
runsOnceForEveryCursor() { return this.keysPressed[0] === '\n'; }
|
||||
|
||||
public async exec(position: Position, vimState: VimState): Promise<VimState> {
|
||||
const searchState = vimState.searchState!;
|
||||
const searchState = vimState.globalState.searchState!;
|
||||
const textFromClipboard = await new Promise<string>((resolve, reject) =>
|
||||
clipboard.paste((err, text) => err ? reject(err) : resolve(text))
|
||||
);
|
||||
@ -1528,7 +1529,7 @@ class CommandCmdVInSearchMode extends BaseCommand {
|
||||
runsOnceForEveryCursor() { return this.keysPressed[0] === '\n'; }
|
||||
|
||||
public async exec(position: Position, vimState: VimState): Promise<VimState> {
|
||||
const searchState = vimState.searchState!;
|
||||
const searchState = vimState.globalState.searchState!;
|
||||
const textFromClipboard = await new Promise<string>((resolve, reject) =>
|
||||
clipboard.paste((err, text) => err ? reject(err) : resolve(text))
|
||||
);
|
||||
@ -1543,7 +1544,7 @@ class CommandNextSearchMatch extends BaseMovement {
|
||||
keys = ["n"];
|
||||
|
||||
public async execAction(position: Position, vimState: VimState): Promise<Position> {
|
||||
const searchState = vimState.searchState;
|
||||
const searchState = vimState.globalState.searchState;
|
||||
|
||||
if (!searchState || searchState.searchString === "") {
|
||||
return position;
|
||||
@ -1583,10 +1584,10 @@ class CommandStar extends BaseCommand {
|
||||
return vimState;
|
||||
}
|
||||
|
||||
vimState.searchState = new SearchState(SearchDirection.Forward, vimState.cursorPosition, currentWord);
|
||||
vimState.globalState.searchState = new SearchState(SearchDirection.Forward, vimState.cursorPosition, currentWord);
|
||||
|
||||
do {
|
||||
vimState.cursorPosition = vimState.searchState.getNextSearchMatchPosition(vimState.cursorPosition).pos;
|
||||
vimState.cursorPosition = vimState.globalState.searchState.getNextSearchMatchPosition(vimState.cursorPosition).pos;
|
||||
} while (TextEditor.getWord(vimState.cursorPosition) !== currentWord);
|
||||
|
||||
// Turn one of the highlighting flags back on (turned off with :nohl)
|
||||
@ -1609,13 +1610,13 @@ class CommandHash extends BaseCommand {
|
||||
return vimState;
|
||||
}
|
||||
|
||||
vimState.searchState = new SearchState(SearchDirection.Backward, vimState.cursorPosition, currentWord);
|
||||
vimState.globalState.searchState = new SearchState(SearchDirection.Backward, vimState.cursorPosition, currentWord);
|
||||
|
||||
do {
|
||||
// use getWordLeft() on position to start at the beginning of the word.
|
||||
// this ensures that any matches happen ounside of the word currently selected,
|
||||
// which are the desired semantics for this motion.
|
||||
vimState.cursorPosition = vimState.searchState.getNextSearchMatchPosition(vimState.cursorPosition.getWordLeft(true)).pos;
|
||||
vimState.cursorPosition = vimState.globalState.searchState.getNextSearchMatchPosition(vimState.cursorPosition.getWordLeft(true)).pos;
|
||||
} while (TextEditor.getWord(vimState.cursorPosition) !== currentWord);
|
||||
|
||||
// Turn one of the highlighting flags back on (turned off with :nohl)
|
||||
@ -1630,7 +1631,7 @@ class CommandPreviousSearchMatch extends BaseMovement {
|
||||
keys = ["N"];
|
||||
|
||||
public async execAction(position: Position, vimState: VimState): Promise<Position> {
|
||||
const searchState = vimState.searchState;
|
||||
const searchState = vimState.globalState.searchState;
|
||||
|
||||
if (!searchState || searchState.searchString === "") {
|
||||
return position;
|
||||
@ -1705,11 +1706,11 @@ export class CommandSearchForwards extends BaseCommand {
|
||||
isMotion = true;
|
||||
|
||||
public async exec(position: Position, vimState: VimState): Promise<VimState> {
|
||||
vimState.searchState = new SearchState(SearchDirection.Forward, vimState.cursorPosition, "", { isRegex: true });
|
||||
vimState.globalState.searchState = new SearchState(SearchDirection.Forward, vimState.cursorPosition, "", { isRegex: true });
|
||||
vimState.currentMode = ModeName.SearchInProgressMode;
|
||||
|
||||
// Reset search history index
|
||||
vimState.searchStateIndex = vimState.searchStatePrevious.length - 1;
|
||||
vimState.globalState.searchStateIndex = vimState.globalState.searchStatePrevious.length - 1;
|
||||
|
||||
Configuration.hl = true;
|
||||
|
||||
@ -1724,11 +1725,11 @@ export class CommandSearchBackwards extends BaseCommand {
|
||||
isMotion = true;
|
||||
|
||||
public async exec(position: Position, vimState: VimState): Promise<VimState> {
|
||||
vimState.searchState = new SearchState(SearchDirection.Backward, vimState.cursorPosition, "", { isRegex: true });
|
||||
vimState.globalState.searchState = new SearchState(SearchDirection.Backward, vimState.cursorPosition, "", { isRegex: true });
|
||||
vimState.currentMode = ModeName.SearchInProgressMode;
|
||||
|
||||
// Reset search history index
|
||||
vimState.searchStateIndex = vimState.searchStatePrevious.length - 1;
|
||||
vimState.globalState.searchStateIndex = vimState.globalState.searchStatePrevious.length - 1;
|
||||
|
||||
Configuration.hl = true;
|
||||
|
||||
|
@ -36,8 +36,8 @@ import { showCmdLine } from '../../src/cmd_line/main';
|
||||
import { Configuration } from '../../src/configuration/configuration';
|
||||
import { PairMatcher } from './../matching/matcher';
|
||||
import { Globals } from '../../src/globals';
|
||||
import { SearchState } from './../state/searchState';
|
||||
import { ReplaceState } from './../state/replaceState';
|
||||
import { GlobalState } from './../state/globalState';
|
||||
|
||||
export class ViewChange {
|
||||
public command: string;
|
||||
@ -88,12 +88,6 @@ export class VimState {
|
||||
|
||||
public lastMovementFailed: boolean = false;
|
||||
|
||||
/**
|
||||
* The keystroke sequence that made up our last complete action (that can be
|
||||
* repeated with '.').
|
||||
*/
|
||||
public previousFullAction: RecordedState | undefined = undefined;
|
||||
|
||||
public alteredHistory = false;
|
||||
|
||||
public isRunningDotCommand = false;
|
||||
@ -123,6 +117,8 @@ export class VimState {
|
||||
*/
|
||||
public currentFullAction: string[] = [];
|
||||
|
||||
public globalState: GlobalState = new GlobalState;
|
||||
|
||||
/**
|
||||
* The position the cursor will be when this action finishes.
|
||||
*/
|
||||
@ -168,18 +164,6 @@ export class VimState {
|
||||
|
||||
public cursorPositionJustBeforeAnythingHappened = [ new Position(0, 0) ];
|
||||
|
||||
public searchState: SearchState | undefined = undefined;
|
||||
|
||||
/**
|
||||
* Index used for navigating search history with <up> and <down> when searching
|
||||
*/
|
||||
public searchStateIndex: number = 0;
|
||||
|
||||
/**
|
||||
* Previous searches performed
|
||||
*/
|
||||
public searchStatePrevious: SearchState[] = [];
|
||||
|
||||
public isRecordingMacro: boolean = false;
|
||||
|
||||
public replaceState: ReplaceState | undefined = undefined;
|
||||
@ -861,7 +845,7 @@ export class ModeHandler implements vscode.Disposable {
|
||||
if (vimState.cursorPositionJustBeforeAnythingHappened.line !== prevPos.line ||
|
||||
vimState.cursorPositionJustBeforeAnythingHappened.character !== prevPos.character) {
|
||||
|
||||
vimState.previousFullAction = recordedState;
|
||||
vimState.globalState.previousFullAction = recordedState;
|
||||
vimState.historyTracker.finishCurrentStep();
|
||||
}
|
||||
}
|
||||
@ -931,7 +915,7 @@ export class ModeHandler implements vscode.Disposable {
|
||||
|
||||
// Record down previous action and flush temporary state
|
||||
if (ranRepeatableAction) {
|
||||
vimState.previousFullAction = vimState.recordedState;
|
||||
vimState.globalState.previousFullAction = vimState.recordedState;
|
||||
|
||||
if (recordedState.isInsertion) {
|
||||
Register.putByKey(recordedState, '.');
|
||||
@ -1324,15 +1308,15 @@ export class ModeHandler implements vscode.Disposable {
|
||||
break;
|
||||
|
||||
case "dot":
|
||||
if (!vimState.previousFullAction) {
|
||||
if (!vimState.globalState.previousFullAction) {
|
||||
return vimState; // TODO(bell)
|
||||
}
|
||||
|
||||
const clonedAction = vimState.previousFullAction.clone();
|
||||
const clonedAction = vimState.globalState.previousFullAction.clone();
|
||||
|
||||
await this.rerunRecordedState(vimState, vimState.previousFullAction);
|
||||
await this.rerunRecordedState(vimState, vimState.globalState.previousFullAction);
|
||||
|
||||
vimState.previousFullAction = clonedAction;
|
||||
vimState.globalState.previousFullAction = clonedAction;
|
||||
break;
|
||||
case "macro":
|
||||
let recordedMacro = (await Register.getByKey(command.register)).text as RecordedState;
|
||||
@ -1572,7 +1556,7 @@ export class ModeHandler implements vscode.Disposable {
|
||||
|
||||
// Scroll to position of cursor
|
||||
if (this._vimState.currentMode === ModeName.SearchInProgressMode) {
|
||||
const nextMatch = vimState.searchState!.getNextSearchMatchPosition(vimState.cursorPosition).pos;
|
||||
const nextMatch = vimState.globalState.searchState!.getNextSearchMatchPosition(vimState.cursorPosition).pos;
|
||||
|
||||
vscode.window.activeTextEditor.revealRange(new vscode.Range(nextMatch, nextMatch));
|
||||
} else {
|
||||
@ -1631,9 +1615,9 @@ export class ModeHandler implements vscode.Disposable {
|
||||
|
||||
if (
|
||||
(Configuration.incsearch && this.currentMode.name === ModeName.SearchInProgressMode) ||
|
||||
((Configuration.hlsearch && Configuration.hl) && vimState.searchState)) {
|
||||
((Configuration.hlsearch && Configuration.hl) && vimState.globalState.searchState)) {
|
||||
|
||||
const searchState = vimState.searchState!;
|
||||
const searchState = vimState.globalState.searchState!;
|
||||
|
||||
searchRanges.push.apply(searchRanges, searchState.matchRanges);
|
||||
|
||||
@ -1656,7 +1640,7 @@ export class ModeHandler implements vscode.Disposable {
|
||||
this.vimState.postponedCodeViewChanges = [];
|
||||
|
||||
if (this.currentMode.name === ModeName.SearchInProgressMode) {
|
||||
this.setStatusBarText(`Searching for: ${ this.vimState.searchState!.searchString }`);
|
||||
this.setStatusBarText(`Searching for: ${ this.vimState.globalState.searchState!.searchString }`);
|
||||
} else if (this.currentMode.name === ModeName.EasyMotionMode) {
|
||||
// Update all EasyMotion decorations
|
||||
this._vimState.easyMotion.updateDecorations();
|
||||
@ -1680,7 +1664,7 @@ export class ModeHandler implements vscode.Disposable {
|
||||
}
|
||||
|
||||
if (this._vimState.currentMode === ModeName.SearchInProgressMode) {
|
||||
currentCommandText = ` ${ this._vimState.searchState!.searchString }`;
|
||||
currentCommandText = ` ${ this._vimState.globalState.searchState!.searchString }`;
|
||||
}
|
||||
|
||||
this.setStatusBarText(`${ modeText }${ currentCommandText }${ macroText }`);
|
||||
|
63
src/state/globalState.ts
Normal file
63
src/state/globalState.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import { SearchState } from './searchState';
|
||||
import { RecordedState } from '../mode/modeHandler';
|
||||
|
||||
/**
|
||||
* State which stores global state (across editors)
|
||||
*/
|
||||
export class GlobalState {
|
||||
/**
|
||||
* The keystroke sequence that made up our last complete action (that can be
|
||||
* repeated with '.').
|
||||
*/
|
||||
private static _previousFullAction: RecordedState | undefined = undefined;
|
||||
|
||||
/**
|
||||
* Previous searches performed
|
||||
*/
|
||||
private static _searchStatePrevious: SearchState[] = [];
|
||||
|
||||
/**
|
||||
* Last search state for running n and N commands
|
||||
*/
|
||||
private static _searchState: SearchState | undefined = undefined;
|
||||
|
||||
/**
|
||||
* Index used for navigating search history with <up> and <down> when searching
|
||||
*/
|
||||
private static _searchStateIndex: number = 0;
|
||||
|
||||
/**
|
||||
* Getters and setters for changing global state
|
||||
*/
|
||||
public get searchStatePrevious(): SearchState[]{
|
||||
return GlobalState._searchStatePrevious;
|
||||
}
|
||||
|
||||
public set searchStatePrevious(states: SearchState[]) {
|
||||
GlobalState._searchStatePrevious = GlobalState._searchStatePrevious.concat(states);
|
||||
}
|
||||
|
||||
public get previousFullAction(): RecordedState | undefined {
|
||||
return GlobalState._previousFullAction;
|
||||
}
|
||||
|
||||
public set previousFullAction(state : RecordedState | undefined) {
|
||||
GlobalState._previousFullAction = state;
|
||||
}
|
||||
|
||||
public get searchState(): SearchState | undefined {
|
||||
return GlobalState._searchState;
|
||||
}
|
||||
|
||||
public set searchState(state : SearchState | undefined) {
|
||||
GlobalState._searchState = state;
|
||||
}
|
||||
|
||||
public get searchStateIndex(): number {
|
||||
return GlobalState._searchStateIndex;
|
||||
}
|
||||
|
||||
public set searchStateIndex(state : number) {
|
||||
GlobalState._searchStateIndex = state;
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ export class SearchState {
|
||||
}
|
||||
|
||||
private _cachedDocumentVersion: number;
|
||||
private _cachedDocumentName: String;
|
||||
private _searchDirection: SearchDirection = SearchDirection.Forward;
|
||||
private isRegex: boolean;
|
||||
|
||||
@ -52,9 +53,13 @@ export class SearchState {
|
||||
|
||||
if (search === "") { return; }
|
||||
|
||||
if (this._cachedDocumentVersion !== TextEditor.getDocumentVersion() || forceRecalc) {
|
||||
// checking if the tab that is worked on has changed, or the file version has changed
|
||||
const shouldRecalculate = (this._cachedDocumentName !== TextEditor.getDocumentName()) ||
|
||||
(this._cachedDocumentVersion !== TextEditor.getDocumentVersion()) || forceRecalc;
|
||||
if (shouldRecalculate) {
|
||||
// Calculate and store all matching ranges
|
||||
this._cachedDocumentVersion = TextEditor.getDocumentVersion();
|
||||
this._cachedDocumentName = TextEditor.getDocumentName();
|
||||
this._matchRanges = [];
|
||||
|
||||
/*
|
||||
|
@ -56,6 +56,10 @@ export class TextEditor {
|
||||
return vscode.window.activeTextEditor.document.version;
|
||||
}
|
||||
|
||||
static getDocumentName(): String {
|
||||
return vscode.window.activeTextEditor.document.fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all text in the entire document.
|
||||
*/
|
||||
|
18
src/util.ts
18
src/util.ts
@ -30,6 +30,24 @@ export async function waitForCursorUpdatesToHappen(): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the tabs to change after a command like 'gt' or 'gT' is run.
|
||||
* Sometimes it is not immediate, so we must busy wait
|
||||
* On certain versions, the tab changes are synchronous
|
||||
* For those, a timeout is given
|
||||
*/
|
||||
export async function waitForTabChange(): Promise<void> {
|
||||
await new Promise((resolve, reject) => {
|
||||
setTimeout(resolve, 100);
|
||||
|
||||
const disposer = vscode.window.onDidChangeActiveTextEditor((textEditor) => {
|
||||
disposer.dispose();
|
||||
|
||||
resolve(textEditor);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function allowVSCodeToPropagateCursorUpdatesAndReturnThem(): Promise<Range[]> {
|
||||
await waitForCursorUpdatesToHappen();
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
import { setupWorkspace, cleanUpWorkspace, setTextEditorOptions } from './../../testUtils';
|
||||
import { setupWorkspace, cleanUpWorkspace, setTextEditorOptions, assertEqualLines } from './../../testUtils';
|
||||
import { ModeHandler } from '../../../src/mode/modeHandler';
|
||||
import { waitForTabChange } from '../../../src/util';
|
||||
import * as assert from 'assert';
|
||||
import { getTestingFunctions } from '../../testSimplifier';
|
||||
|
||||
suite("Dot Operator", () => {
|
||||
@ -19,6 +21,28 @@ suite("Dot Operator", () => {
|
||||
|
||||
teardown(cleanUpWorkspace);
|
||||
|
||||
test('repeats actions across editors ', async () => {
|
||||
// setting the content of the first 2 tabs
|
||||
const firstTabContent = 'some\ntest\nabc\nend';
|
||||
const secondTabContent = 'another\ntest\ndef\nend';
|
||||
const firstTabKeys = ['<Esc>', 'a'].concat(firstTabContent.split(''));
|
||||
const secondTabKeys = ['<Esc>', 'a'].concat(secondTabContent.split(''));
|
||||
await setupWorkspace();
|
||||
setTextEditorOptions(5, false);
|
||||
await modeHandler.handleMultipleKeyEvents(firstTabKeys.concat(['<Esc>']));
|
||||
await modeHandler.handleMultipleKeyEvents(['<Esc>', 'g', 'T']);
|
||||
await waitForTabChange();
|
||||
await modeHandler.handleMultipleKeyEvents(secondTabKeys.concat(['<Esc>']));
|
||||
|
||||
// running an action in second tab and repeating in first tab
|
||||
await modeHandler.handleMultipleKeyEvents(['g', 'g', 'd' , 'd']);
|
||||
await assertEqualLines(['test', 'def', 'end']);
|
||||
await modeHandler.handleMultipleKeyEvents(['g', 't']);
|
||||
await waitForTabChange();
|
||||
await modeHandler.handleMultipleKeyEvents(['<Esc>', 'g', 'g', '.']);
|
||||
await assertEqualLines(['test', 'abc', 'end']);
|
||||
});
|
||||
|
||||
newTest({
|
||||
title: "Can repeat '~' with <num>",
|
||||
start: ['|teXt'],
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
import { setupWorkspace, cleanUpWorkspace } from './../../testUtils';
|
||||
import { ModeHandler } from '../../../src/mode/modeHandler';
|
||||
import { getTestingFunctions } from '../../testSimplifier';
|
||||
import { getTestingFunctions, testIt } from '../../testSimplifier';
|
||||
import { waitForTabChange } from '../../../src/util';
|
||||
|
||||
suite("Motions in Normal Mode", () => {
|
||||
let modeHandler: ModeHandler = new ModeHandler();
|
||||
@ -277,6 +278,52 @@ suite("Motions in Normal Mode", () => {
|
||||
end: ['one two |two two'],
|
||||
});
|
||||
|
||||
test('Remembers a forward search from another editor', async function() {
|
||||
// adding another editor
|
||||
await setupWorkspace();
|
||||
|
||||
await testIt(modeHandler, {
|
||||
title: "",
|
||||
start: ['|one two two two'],
|
||||
keysPressed: '/two\n',
|
||||
end: ['one |two two two'],
|
||||
});
|
||||
|
||||
await modeHandler.handleMultipleKeyEvents(['g', 'T', '<Esc>']);
|
||||
|
||||
await waitForTabChange();
|
||||
|
||||
await testIt(modeHandler, {
|
||||
title: "",
|
||||
start: ['|three four two one'],
|
||||
keysPressed: '<Esc>n',
|
||||
end: ['three four |two one'],
|
||||
});
|
||||
});
|
||||
|
||||
test('Shares forward search history from another editor', async () => {
|
||||
// adding another editor
|
||||
await setupWorkspace();
|
||||
|
||||
await testIt(modeHandler, {
|
||||
title: "",
|
||||
start: ['|one two two two'],
|
||||
keysPressed: '/two\n',
|
||||
end: ['one |two two two'],
|
||||
});
|
||||
|
||||
await modeHandler.handleMultipleKeyEvents(['g', 'T', '<Esc>']);
|
||||
|
||||
await waitForTabChange();
|
||||
|
||||
await testIt(modeHandler, {
|
||||
title: "",
|
||||
start: ['|three four two one'],
|
||||
keysPressed: '/\n',
|
||||
end: ['three four |two one'],
|
||||
});
|
||||
});
|
||||
|
||||
newTest({
|
||||
title: "Can run a reverse search",
|
||||
start: ['one two thre|e'],
|
||||
@ -291,6 +338,53 @@ suite("Motions in Normal Mode", () => {
|
||||
end: ['one |two two three'],
|
||||
});
|
||||
|
||||
test('Remembers a reverse search from another editor', async () => {
|
||||
// adding another editor
|
||||
await setupWorkspace();
|
||||
|
||||
await testIt(modeHandler, {
|
||||
title: "",
|
||||
start: ['one two two two|'],
|
||||
keysPressed: '?two\n',
|
||||
end: ['one two two |two'],
|
||||
});
|
||||
|
||||
await modeHandler.handleMultipleKeyEvents(['g', 'T', '<Esc>']);
|
||||
|
||||
await waitForTabChange();
|
||||
|
||||
await testIt(modeHandler, {
|
||||
title: "",
|
||||
start: ['three four two one|'],
|
||||
keysPressed: '<Esc>n',
|
||||
end: ['three four |two one'],
|
||||
});
|
||||
});
|
||||
|
||||
test('Shares reverse search history from another editor', async () => {
|
||||
// adding another editor
|
||||
await setupWorkspace();
|
||||
|
||||
await testIt(modeHandler, {
|
||||
title: "",
|
||||
start: ['one two two two|'],
|
||||
keysPressed: '?two\n',
|
||||
end: ['one two two |two'],
|
||||
});
|
||||
|
||||
await modeHandler.handleMultipleKeyEvents(['g', 'T', '<Esc>']);
|
||||
|
||||
await waitForTabChange();
|
||||
|
||||
await testIt(modeHandler, {
|
||||
title: "",
|
||||
start: ['three four two one|'],
|
||||
keysPressed: '?\n',
|
||||
end: ['three four |two one'],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
newTest({
|
||||
title: "maintains column position correctly",
|
||||
start: ['|one one one', 'two', 'three'],
|
||||
|
Loading…
Reference in New Issue
Block a user