diff --git a/src/configuration/remapper.ts b/src/configuration/remapper.ts index ca0c2f40871..a6583d5df5f 100644 --- a/src/configuration/remapper.ts +++ b/src/configuration/remapper.ts @@ -102,68 +102,12 @@ export class Remapper implements IRemapper { vimState.isCurrentlyPerformingRemapping = true; } - const numCharsToRemove = remapping.before.length - 1; - // Revert previously inserted characters - // (e.g. jj remapped to esc, we have to revert the inserted "jj") - if (vimState.currentMode === ModeName.Insert) { - // Revert every single inserted character. - // We subtract 1 because we haven't actually applied the last key. - await vimState.historyTracker.undoAndRemoveChanges( - Math.max(0, numCharsToRemove * vimState.allCursors.length) - ); - vimState.allCursors = vimState.allCursors.map(x => - x.withNewStop(x.stop.getLeft(numCharsToRemove)) - ); - } - - // We need to remove the keys that were remapped into different keys - // from the state. - vimState.recordedState.actionKeys = vimState.recordedState.actionKeys.slice( - 0, - -numCharsToRemove - ); - vimState.keyHistory = vimState.keyHistory.slice(0, -numCharsToRemove); - - if (remapping.after) { - const count = vimState.recordedState.count || 1; - vimState.recordedState.count = 0; - - for (let i = 0; i < count; i++) { - await modeHandler.handleMultipleKeyEvents(remapping.after); - } + try { + await this.handleRemapping(remapping, vimState, modeHandler); + } finally { + vimState.isCurrentlyPerformingRemapping = false; } - if (remapping.commands) { - for (const command of remapping.commands) { - // Check if this is a vim command by looking for : - let commandString: string; - let commandArgs: string[]; - - if (typeof command === 'string') { - commandString = command; - commandArgs = []; - } else { - commandString = command.command; - commandArgs = command.args; - } - - if (commandString.slice(0, 1) === ':') { - await commandLine.Run( - commandString.slice(1, commandString.length), - modeHandler.vimState - ); - await modeHandler.updateView(modeHandler.vimState); - } else { - if (commandArgs) { - await vscode.commands.executeCommand(commandString, commandArgs); - } else { - await vscode.commands.executeCommand(commandString); - } - } - } - } - - vimState.isCurrentlyPerformingRemapping = false; return true; } @@ -178,6 +122,64 @@ export class Remapper implements IRemapper { return false; } + private async handleRemapping( + remapping: IKeyRemapping, + vimState: VimState, + modeHandler: ModeHandler + ) { + const numCharsToRemove = remapping.before.length - 1; + // Revert previously inserted characters + // (e.g. jj remapped to esc, we have to revert the inserted "jj") + if (vimState.currentMode === ModeName.Insert) { + // Revert every single inserted character. + // We subtract 1 because we haven't actually applied the last key. + await vimState.historyTracker.undoAndRemoveChanges( + Math.max(0, numCharsToRemove * vimState.allCursors.length) + ); + vimState.allCursors = vimState.allCursors.map(x => + x.withNewStop(x.stop.getLeft(numCharsToRemove)) + ); + } + // We need to remove the keys that were remapped into different keys from the state. + vimState.recordedState.actionKeys = vimState.recordedState.actionKeys.slice( + 0, + -numCharsToRemove + ); + vimState.keyHistory = vimState.keyHistory.slice(0, -numCharsToRemove); + + if (remapping.after) { + const count = vimState.recordedState.count || 1; + vimState.recordedState.count = 0; + for (let i = 0; i < count; i++) { + await modeHandler.handleMultipleKeyEvents(remapping.after); + } + } + + if (remapping.commands) { + for (const command of remapping.commands) { + let commandString: string; + let commandArgs: string[]; + if (typeof command === 'string') { + commandString = command; + commandArgs = []; + } else { + commandString = command.command; + commandArgs = command.args; + } + + if (commandString.slice(0, 1) === ':') { + // Check if this is a vim command by looking for : + await commandLine.Run(commandString.slice(1, commandString.length), modeHandler.vimState); + await modeHandler.updateView(modeHandler.vimState); + } else if (commandArgs) { + await vscode.commands.executeCommand(commandString, commandArgs); + } else { + await vscode.commands.executeCommand(commandString); + } + } + } + } + private _getRemappings(): { [key: string]: IKeyRemapping } { // Create a null object so that there is no __proto__ let remappings: { [key: string]: IKeyRemapping } = Object.create(null); @@ -208,16 +210,14 @@ export class Remapper implements IRemapper { if (!configurationValidator.isCommandValid(cmd)) { debugMsg += ` Command does not exist.`; isCommandValid = false; - break; } } } if (!remapping.after && !remapping.commands) { logger.error( - `Remapper: ${ - this._configKey - }. Invalid configuration. Missing 'after' key or 'command'. ${debugMsg}` + `Remapper: ${this._configKey}. + Invalid configuration. Missing 'after' key or 'command'. ${debugMsg}` ); continue; } @@ -228,15 +228,8 @@ export class Remapper implements IRemapper { continue; } - if (!isCommandValid) { - logger.warn( - `Remapper: ${this._configKey}. - ${debugMsg} - If you are referencing a command from an extension that has not yet been activated, this message can be ignored.` - ); - } - - logger.debug(`Remapper: ${this._configKey}. loaded: ${debugMsg}`); + let log = (msg: string) => (isCommandValid ? logger.debug(msg) : logger.warn(msg)); + log(`Remapper: ${this._configKey}. ${debugMsg}`); remappings[keys] = remapping; }