Skip to content

Commit

Permalink
Merge pull request #3320 from VSCodeVim/actually_fix_3295
Browse files Browse the repository at this point in the history
fix: Actually fix #3295.
  • Loading branch information
jpoon authored Jan 2, 2019
2 parents d4bea81 + 6b7c7c3 commit cb925ce
Showing 1 changed file with 66 additions and 73 deletions.
139 changes: 66 additions & 73 deletions src/configuration/remapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down

0 comments on commit cb925ce

Please sign in to comment.