From 7374061d9dc8c93bf45ca69d7c9c7d6cd3d4fd58 Mon Sep 17 00:00:00 2001 From: Jason Poon Date: Thu, 27 Dec 2018 14:52:31 -0800 Subject: [PATCH] fix: ignore remappings with non-existent commands. fixes #3295 --- extension.ts | 3 +- src/configuration/configurationValidator.ts | 21 ++++++++++ src/configuration/remapper.ts | 43 +++++++++++++++++---- 3 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 src/configuration/configurationValidator.ts diff --git a/extension.ts b/extension.ts index 6030cddb1aa3..114b981b3acc 100644 --- a/extension.ts +++ b/extension.ts @@ -22,6 +22,7 @@ import { StatusBar } from './src/statusBar'; import { VsCodeContext } from './src/util/vscode-context'; import { commandLine } from './src/cmd_line/commandLine'; import { configuration } from './src/configuration/configuration'; +import { configurationValidator } from './src/configuration/configurationValidator'; import { logger } from './src/util/logger'; import { taskQueue } from './src/taskQueue'; @@ -311,8 +312,8 @@ export async function activate(context: vscode.ExtensionContext) { } await commandLine.load(); - // Initialize the search history await globalState.loadSearchHistory(); + await configurationValidator.initialize(); // This is called last because getAndUpdateModeHandler() will change cursor toggleExtension(configuration.disableExt, compositionState); diff --git a/src/configuration/configurationValidator.ts b/src/configuration/configurationValidator.ts new file mode 100644 index 000000000000..cc7574d57d36 --- /dev/null +++ b/src/configuration/configurationValidator.ts @@ -0,0 +1,21 @@ +import * as vscode from 'vscode'; + +class ConfigurationValidator { + private map: Map; + + public async initialize(): Promise { + this.map = new Map( + (await vscode.commands.getCommands(true)).map(x => [x, true] as [string, boolean]) + ); + } + + public isCommandValid(command: string): boolean { + if (command.startsWith(':')) { + return true; + } + + return this.map.get(command) || false; + } +} + +export let configurationValidator = new ConfigurationValidator(); diff --git a/src/configuration/remapper.ts b/src/configuration/remapper.ts index 3f71a7f91330..a8617e238e25 100644 --- a/src/configuration/remapper.ts +++ b/src/configuration/remapper.ts @@ -1,13 +1,14 @@ import * as _ from 'lodash'; import * as vscode from 'vscode'; -import { commandLine } from '../cmd_line/commandLine'; -import { configuration } from '../configuration/configuration'; -import { ModeName } from '../mode/mode'; +import { IKeyRemapping } from './iconfiguration'; import { ModeHandler } from '../mode/modeHandler'; +import { ModeName } from '../mode/mode'; import { VimState } from './../state/vimState'; -import { IKeyRemapping } from './iconfiguration'; +import { configuration } from '../configuration/configuration'; +import { configurationValidator } from './configurationValidator'; import { logger } from '../util/logger'; +import { commandLine } from '../cmd_line/commandLine'; interface IRemapper { /** @@ -81,8 +82,11 @@ export class Remapper implements IRemapper { const userDefinedRemappings = this._getRemappings(); + logger.debug( + `Remapper: find matching remap. keys=${keys}. mode=${ModeName[vimState.currentMode]}.` + ); let remapping: IKeyRemapping | undefined = Remapper._findMatchingRemap( - userDefinedRemappings, + await userDefinedRemappings, keys, vimState.currentMode ); @@ -177,6 +181,7 @@ export class Remapper implements IRemapper { private _getRemappings(): { [key: string]: IKeyRemapping } { // Create a null object so that there is no __proto__ let remappings: { [key: string]: IKeyRemapping } = Object.create(null); + for (let remapping of configuration[this._configKey] as IKeyRemapping[]) { let debugMsg = `before=${remapping.before}. `; @@ -184,12 +189,25 @@ export class Remapper implements IRemapper { debugMsg += `after=${remapping.after}. `; } + let isCommandValid = true; if (remapping.commands) { for (const command of remapping.commands) { + let cmd: string; + let args: any[]; + if (typeof command === 'string') { - debugMsg += `command=${command}. args=.`; + cmd = command; + args = []; } else { - debugMsg += `command=${command.command}. args=${command.args}.`; + cmd = command.command; + args = command.args; + } + + debugMsg += `command=${cmd}. args=${args}.`; + + if (!configurationValidator.isCommandValid(cmd)) { + isCommandValid = false; + break; } } } @@ -203,13 +221,22 @@ export class Remapper implements IRemapper { continue; } + if (!isCommandValid) { + logger.error( + `Remapper: ${ + this._configKey + }. Invalid configuration. Command does not exist. ${debugMsg}.` + ); + continue; + } + const keys = remapping.before.join(''); if (keys in remappings) { logger.error(`Remapper: ${this._configKey}. Duplicate configuration. ${debugMsg}`); continue; } - logger.debug(`Remapper: ${this._configKey}. ${debugMsg}`); + logger.debug(`Remapper: ${this._configKey}. loaded: ${debugMsg}`); remappings[keys] = remapping; }