Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: slightly improve perf by caching vscode context #3293

Merged
merged 3 commits into from
Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ import './src/actions/include-all';
import * as _ from 'lodash';
import * as vscode from 'vscode';

import { configuration } from './src/configuration/configuration';
import { commandLine } from './src/cmd_line/commandLine';
import { Position } from './src/common/motion/position';
import { CompositionState } from './src/state/compositionState';
import { EditorIdentity } from './src/editorIdentity';
import { Globals } from './src/globals';
import { GlobalState } from './src/state/globalState';
import { Globals } from './src/globals';
import { Jump } from './src/jumps/jump';
import { ModeName } from './src/mode/mode';
import { ModeHandler } from './src/mode/modeHandler';
import { ModeHandlerMap } from './src/mode/modeHandlerMap';
import { ModeName } from './src/mode/mode';
import { Notation } from './src/configuration/notation';
import { Position } from './src/common/motion/position';
import { StatusBar } from './src/statusBar';
import { taskQueue } from './src/taskQueue';
import { ModeHandlerMap } from './src/mode/modeHandlerMap';
import { VsCodeContext } from './src/util/vscode-context';
import { commandLine } from './src/cmd_line/commandLine';
import { configuration } from './src/configuration/configuration';
import { logger } from './src/util/logger';
import { CompositionState } from './src/state/compositionState';
import { taskQueue } from './src/taskQueue';

const globalState = new GlobalState();
let extensionContext: vscode.ExtensionContext;
Expand Down Expand Up @@ -191,7 +192,7 @@ export async function activate(context: vscode.ExtensionContext) {
if (vscode.window.activeTextEditor !== undefined) {
const mh: ModeHandler = await getAndUpdateModeHandler(true);

await mh.updateVimModeForKeybindings(mh.vimState.currentMode);
await VsCodeContext.Set('vim.mode', this.vimState.currentMode);

await mh.updateView(mh.vimState, { drawSelection: false, revealRange: false });

Expand Down Expand Up @@ -324,7 +325,7 @@ export async function activate(context: vscode.ExtensionContext) {
* @param isDisabled if true, sets VSCodeVim to Disabled mode; else sets to enabled mode
*/
async function toggleExtension(isDisabled: boolean, compositionState: CompositionState) {
await vscode.commands.executeCommand('setContext', 'vim.active', !isDisabled);
await VsCodeContext.Set('vim.active', !isDisabled);
if (!vscode.window.activeTextEditor) {
// This was happening in unit tests.
// If activate was called and no editor window is open, we can't properly initialize.
Expand Down
13 changes: 5 additions & 8 deletions src/configuration/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import * as vscode from 'vscode';

import { Globals } from '../globals';
import { taskQueue } from '../taskQueue';
import { Notation } from './notation';
import { taskQueue } from '../taskQueue';
import {
IConfiguration,
IKeyRemapping,
IModeSpecificStrings,
IAutoSwitchInputMethod,
IDebugConfiguration,
} from './iconfiguration';
import { VsCodeContext } from '../util/vscode-context';

const packagejson: {
contributes: {
Expand Down Expand Up @@ -159,15 +160,11 @@ class Configuration implements IConfiguration {
}
}

vscode.commands.executeCommand('setContext', `vim.use${boundKey.key}`, useKey);
VsCodeContext.Set(`vim.use${boundKey.key}`, useKey);
}

vscode.commands.executeCommand('setContext', 'vim.overrideCopy', this.overrideCopy);
vscode.commands.executeCommand(
'setContext',
'vim.overrideCtrlC',
this.overrideCopy || this.useCtrlKeys
);
VsCodeContext.Set('vim.overrideCopy', this.overrideCopy);
VsCodeContext.Set('vim.overrideCtrlC', this.overrideCopy || this.useCtrlKeys);
}

unproxify(obj: Object): Object {
Expand Down
66 changes: 22 additions & 44 deletions src/mode/modeHandler.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,45 @@
import * as vscode from 'vscode';
import * as modes from './modes';

import { commandLine } from '../cmd_line/commandLine';
import { configuration } from '../configuration/configuration';
import { Actions, BaseAction, KeypressState } from './../actions/base';
import { BaseMovement, isIMovement } from './../actions/motion';
import { CommandInsertInInsertMode, CommandInsertPreviousText } from './../actions/commands/insert';
import { Decoration } from '../configuration/decoration';
import { Remappers } from '../configuration/remapper';
import { Globals } from '../globals';
import { Jump } from '../jumps/jump';
import { Mode, ModeName, VSCodeVimCursorType } from './mode';
import { PairMatcher } from './../common/matching/matcher';
import { Position, PositionDiff } from './../common/motion/position';
import { Range } from './../common/motion/range';
import { RecordedState } from './../state/recordedState';
import { Register, RegisterMode } from './../register/register';
import { Remappers } from '../configuration/remapper';
import { StatusBar } from '../statusBar';
import { TextEditor } from './../textEditor';
import { VimState } from './../state/vimState';
import { VsCodeContext } from '../util/vscode-context';
import { commandLine } from '../cmd_line/commandLine';
import { configuration } from '../configuration/configuration';
import { getCursorsAfterSync } from '../util/util';
import { Actions, BaseAction, KeypressState } from './../actions/base';
import { logger } from '../util/logger';
import { taskQueue } from './../taskQueue';
import {
BaseCommand,
CommandQuitRecordMacro,
DocumentContentChangeAction,
} from './../actions/commands/actions';
import { CommandInsertInInsertMode, CommandInsertPreviousText } from './../actions/commands/insert';
import { BaseMovement, isIMovement } from './../actions/motion';
import { PairMatcher } from './../common/matching/matcher';
import { Position, PositionDiff } from './../common/motion/position';
import { Range } from './../common/motion/range';
import { Register, RegisterMode } from './../register/register';
import { RecordedState } from './../state/recordedState';
import { VimState } from './../state/vimState';
import { taskQueue } from './../taskQueue';
import { TextEditor } from './../textEditor';
import {
areAnyTransformationsOverlapping,
isTextTransformation,
TextTransformations,
} from './../transformations/transformations';
import { Mode, ModeName, VSCodeVimCursorType } from './mode';
import { logger } from '../util/logger';
import { Neovim } from '../neovim/neovim';
import { Jump } from '../jumps/jump';


export class ModeHandler implements vscode.Disposable {
private _disposables: vscode.Disposable[] = [];
private _modes: Mode[];
private _remappers: Remappers;

/**
* Last vim.mode sent to vscode, for updating keybindings.
* It is static, as the context applies across editors.
*/
private static _lastVimModeSetForKeybindings: ModeName;

public vimState: VimState;

get currentMode(): Mode {
Expand Down Expand Up @@ -542,12 +537,12 @@ export class ModeHandler implements vscode.Disposable {
this.IsModeWhereCmdVIsOverriden(vimState.currentMode) &&
!this.IsModeWhereCmdVIsOverriden(prevState)
) {
await vscode.commands.executeCommand('setContext', 'vim.overrideCmdV', true);
VsCodeContext.Set('vim.overrideCmdV', true);
} else if (
this.IsModeWhereCmdVIsOverriden(prevState) &&
!this.IsModeWhereCmdVIsOverriden(vimState.currentMode)
) {
await vscode.commands.executeCommand('setContext', 'vim.overrideCmdV', false);
VsCodeContext.Set('vim.overrideCmdV', false);
}

if (recordedState.operatorReadyToExecute(vimState.currentMode)) {
Expand Down Expand Up @@ -1434,24 +1429,7 @@ export class ModeHandler implements vscode.Disposable {

this._renderStatusBar();

await this.updateVimModeForKeybindings(this.vimState.currentMode);
}

/**
* Let vscode know what our current mode is by setting vim.mode.
* This is used to determine keybindings, as seen in package.json.
* Applies across editors.
* @param mode New (current) mode
*/
public async updateVimModeForKeybindings(mode: ModeName): Promise<void> {
// This can be an expensive operation (sometimes taking 40-60ms),
// so we only want to send it when it actually changes, which should
// include key events as well as changing or opening tabs.
if (ModeHandler._lastVimModeSetForKeybindings !== mode) {
await vscode.commands.executeCommand('setContext', 'vim.mode', ModeName[mode]);
// There doesn't seem to be a "getContext" available to extensions, so track ourselves.
ModeHandler._lastVimModeSetForKeybindings = mode;
}
await VsCodeContext.Set('vim.mode', this.vimState.currentMode);
}

private _renderStatusBar(): void {
Expand Down
19 changes: 19 additions & 0 deletions src/util/vscode-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as vscode from 'vscode';

export class VsCodeContextImpl {
contextMap: { [key: string]: any } = {};

public async Set(key: string, value: any): Promise<void> {
const prev = this.Get(key);
if (!prev || prev !== value) {
this.contextMap[key] = value;
return vscode.commands.executeCommand('setContext', key, value);
}
}

public Get(key: string): any {
return this.contextMap[key];
}
}

export let VsCodeContext = new VsCodeContextImpl();