Update Mode abstract class to properly return promises when calling HandleActivation and HandleKeyEvent

This commit is contained in:
Jason Poon 2015-12-04 08:53:10 -08:00
parent 9a834918c5
commit f74e887d4d
8 changed files with 99 additions and 92 deletions

View File

@ -3,17 +3,17 @@ import * as parser from "./parser";
import * as util from "../util";
// Shows the vim command line.
export function showCmdLine(initialText = "") {
export function showCmdLine(initialText = "") : Thenable<{}> {
if (!vscode.window.activeTextEditor) {
util.showInfo("No active document.");
return;
return util.showInfo("No active document.");
}
const options : vscode.InputBoxOptions = {
prompt: "Vim command line",
value: initialText
};
vscode.window.showInputBox(options).then(
return vscode.window.showInputBox(options).then(
runCmdLine,
vscode.window.showErrorMessage
);

View File

@ -33,7 +33,7 @@ export abstract class Mode {
abstract ShouldBeActivated(key : string, currentMode : ModeName) : boolean;
abstract HandleActivation(key : string) : Thenable<void> | void;
abstract HandleActivation(key : string) : Thenable<{}>;
abstract HandleKeyEvent(key : string) : void;
abstract HandleKeyEvent(key : string) : Thenable<{}>;
}

View File

@ -4,56 +4,56 @@ import TextEditor from './../textEditor';
import {Cursor} from './../motion/motion';
export default class InsertMode extends Mode {
private activationKeyHandler : { [ key : string] : (cursor : Cursor) => Thenable<void> | void; };
private cursor : Cursor = new Cursor();
private cursor : Cursor;
private activationKeyHandler : { [ key : string] : (cursor : Cursor) => Thenable<{}> } = {
"i" : () => {
// insert at cursor
return Promise.resolve({});
},
"I" : c => {
// insert at line beginning
return Promise.resolve(c.lineBegin().move());
},
"a" : c => {
// append after the cursor
return Promise.resolve(c.right().move());
},
"A" : c => {
// append at the end of the line
return Promise.resolve(c.lineEnd().move());
},
"o" : () => {
// open blank line below current line
return vscode.commands.executeCommand("editor.action.insertLineAfter");
},
"O" : () => {
// open blank line above current line
return vscode.commands.executeCommand("editor.action.insertLineBefore");
}
};
constructor() {
super(ModeName.Insert);
this.activationKeyHandler = {
// insert at cursor
"i" : (cursor) => {
// nothing
},
// insert at the beginning of the line
"I" : (cursor) => { cursor.lineBegin().move(); },
// append after the cursor
"a" : (cursor) => { cursor.right().move(); },
// append at the end of the line
"A" : (cursor) => { cursor.lineEnd().move(); },
// open blank line below current line
"o" : () => {
return vscode.commands.executeCommand("editor.action.insertLineAfter");
},
// open blank line above current line
"O" : () => {
return vscode.commands.executeCommand("editor.action.insertLineBefore");
}
};
this.cursor = new Cursor();
}
ShouldBeActivated(key : string, currentMode : ModeName) : boolean {
return key in this.activationKeyHandler;
}
HandleActivation(key : string) : Thenable<void> | void {
HandleActivation(key : string) : Thenable<{}> {
this.cursor.reset();
return this.activationKeyHandler[key](this.cursor);
}
HandleKeyEvent(key : string) : Thenable<boolean> {
HandleKeyEvent(key : string) : Thenable<{}> {
this.keyHistory.push(key);
var thenable = TextEditor.insert(this.ResolveKeyValue(key));
vscode.commands.executeCommand("editor.action.triggerSuggest");
return thenable;
return TextEditor
.insert(this.ResolveKeyValue(key))
.then(() => {
return vscode.commands.executeCommand("editor.action.triggerSuggest");
});
}
// Some keys have names that are different to their value.
@ -66,4 +66,4 @@ export default class InsertMode extends Mode {
return key;
}
}
}
}

View File

@ -4,62 +4,66 @@ import {ModeName, Mode} from './mode';
import {showCmdLine} from './../cmd_line/main';
import {Caret} from './../motion/motion';
export default class CommandMode extends Mode {
private keyHandler : { [key : string] : () => void; } = {};
private caret : Caret = new Caret();
export default class NormalMode extends Mode {
private caret : Caret;
private keyHandler : { [key : string] : (caret : Caret) => Thenable<{}>; } = {
":" : () => { return showCmdLine(); },
"u" : () => { return vscode.commands.executeCommand("undo"); },
"ctrl+r" : () => { return vscode.commands.executeCommand("redo"); },
"h" : c => { return Promise.resolve(c.left().move()); },
"j" : c => { return Promise.resolve(c.down().move()); },
"k" : c => { return Promise.resolve(c.up().move()); },
"l" : c => { return Promise.resolve(c.right().move()); },
"$" : c => { return Promise.resolve(c.lineEnd().move()); },
"^" : c => { return Promise.resolve(c.lineBegin().move()); },
"gg" : c => {return Promise.resolve(c.firstLineNonBlankChar().move()); },
"G" : c => { return Promise.resolve(c.lastLineNonBlankChar().move()); },
"w" : c => { return Promise.resolve(c.wordRight().move()); },
"b" : c => { return Promise.resolve(c.wordLeft().move()); },
">>" : () => { return vscode.commands.executeCommand("editor.action.indentLines"); },
"<<" : () => { return vscode.commands.executeCommand("editor.action.outdentLines"); },
"dd" : () => { return vscode.commands.executeCommand("editor.action.deleteLines"); },
"dw" : () => { return vscode.commands.executeCommand("deleteWordRight"); },
"db" : () => { return vscode.commands.executeCommand("deleteWordLeft"); },
// "x" : () => { this.CommandDelete(1); }
"esc": () => { return vscode.commands.executeCommand("workbench.action.closeMessages"); }
};
constructor() {
super(ModeName.Normal);
this.keyHandler = {
":" : () => { showCmdLine(); },
"u" : () => { vscode.commands.executeCommand("undo"); },
"ctrl+r" : () => { vscode.commands.executeCommand("redo"); },
"h" : () => { this.caret.left().move(); },
"j" : () => { this.caret.down().move(); },
"k" : () => { this.caret.up().move(); },
"l" : () => { this.caret.right().move(); },
"$" : () => { this.caret.lineEnd().move(); },
"^" : () => { this.caret.lineBegin().move(); },
"gg" : () => {this.caret.firstLineNonBlankChar().move(); },
"G" : () => { this.caret.lastLineNonBlankChar().move(); },
"w" : () => { this.caret.wordRight().move(); },
"b" : () => { this.caret.wordLeft().move(); },
">>" : () => { vscode.commands.executeCommand("editor.action.indentLines"); },
"<<" : () => { vscode.commands.executeCommand("editor.action.outdentLines"); },
"dd" : () => { vscode.commands.executeCommand("editor.action.deleteLines"); },
"dw" : () => { vscode.commands.executeCommand("deleteWordRight"); },
"db" : () => { vscode.commands.executeCommand("deleteWordLeft"); },
// "x" : () => { this.CommandDelete(1); }
"esc": () => { vscode.commands.executeCommand("workbench.action.closeMessages"); }
};
this.caret = new Caret();
}
ShouldBeActivated(key : string, currentMode : ModeName) : boolean {
return (key === 'esc' || key === 'ctrl+[');
}
HandleActivation(key : string) : void {
this.caret.reset().left().move();
HandleActivation(key : string) : Thenable<{}> {
return Promise.resolve(this.caret.reset().left().move());
}
HandleKeyEvent(key : string) : void {
HandleKeyEvent(key : string) : Thenable<{}> {
this.keyHistory.push(key);
let keyHandled = false;
return new Promise(resolve => {
let keyHandled = false;
let keysPressed : string;
for (let window = this.keyHistory.length; window > 0; window--) {
let keysPressed = _.takeRight(this.keyHistory, window).join('');
if (this.keyHandler[keysPressed] !== undefined) {
keyHandled = true;
this.keyHandler[keysPressed]();
break;
for (let window = this.keyHistory.length; window > 0; window--) {
keysPressed = _.takeRight(this.keyHistory, window).join('');
if (this.keyHandler[keysPressed] !== undefined) {
keyHandled = true;
break;
}
}
}
if (keyHandled) {
this.keyHistory = [];
}
if (keyHandled) {
this.keyHistory = [];
return this.keyHandler[keysPressed](this.caret);
}
resolve();
});
}
/*

View File

@ -10,11 +10,12 @@ export default class VisualMode extends Mode {
return (key === "v" || key === "V") && (currentMode === ModeName.Normal);
}
HandleActivation(key : string) : void {
// do nothing
HandleActivation(key : string) : Thenable<{}> {
return Promise.resolve({});
}
HandleKeyEvent(key : string) : void {
HandleKeyEvent(key : string) : Thenable<{}> {
this.keyHistory.push(key);
return Promise.resolve({});
}
}

View File

@ -19,6 +19,7 @@ abstract class Motion<T extends Motion<any>> {
line = currentPosition.line;
character = currentPosition.character;
}
this.prevColumn = character;
this.position = new vscode.Position(line, character);
}

View File

@ -6,27 +6,28 @@ export default class TextEditor {
position = vscode.window.activeTextEditor.selection.active;
}
return vscode.window.activeTextEditor.edit((editBuilder) => {
return vscode.window.activeTextEditor.edit(editBuilder => {
editBuilder.insert(position, text);
});
}
static delete(range: vscode.Range = null) : Thenable<boolean> {
if (range === null) {
// delete entire document
let start = new vscode.Position(0, 0);
let lastLine = vscode.window.activeTextEditor.document.lineCount - 1;
let end = vscode.window.activeTextEditor.document.lineAt(lastLine).range.end;
range = new vscode.Range(start, end);
}
return vscode.window.activeTextEditor.edit((editBuilder) => {
return vscode.window.activeTextEditor.edit(editBuilder => {
editBuilder.delete(range);
});
}
static replace(range: vscode.Range, text: string) : Thenable<boolean> {
return vscode.window.activeTextEditor.edit((editBuilder) => {
return vscode.window.activeTextEditor.edit(editBuilder => {
editBuilder.replace(range, text);
});
}

View File

@ -1,9 +1,9 @@
import * as vscode from 'vscode';
export function showInfo(message : string) : void {
vscode.window.showInformationMessage("Vim: " + message);
export function showInfo(message : string) : Thenable<{}> {
return vscode.window.showInformationMessage("Vim: " + message);
}
export function showError(message : string) : void {
vscode.window.showErrorMessage("Vim: " + message);
export function showError(message : string) : Thenable<{}> {
return vscode.window.showErrorMessage("Vim: " + message);
}