diff --git a/gulpfile.js b/gulpfile.js index 42cb321744c..abf7d9477da 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,8 +1,9 @@ -var gulp = require('gulp'); -var tslint = require('gulp-tslint'); -var tsd = require('gulp-tsd'); -var shell = require('gulp-shell'); -var mocha = require('gulp-mocha'); +var gulp = require('gulp'), + tslint = require('gulp-tslint'), + tsd = require('gulp-tsd'), + shell = require('gulp-shell'), + mocha = require('gulp-mocha'), + trimlines = require('gulp-trimlines'); var paths = { scripts_ts: "src/**/*.ts", @@ -21,11 +22,19 @@ gulp.task('tsd', function (callback) { }, callback)); }); -gulp.task('compile', shell.task([ +gulp.task('trim-whitespace', function() { + return gulp.src([paths.scripts_ts, paths.tests_ts], { base: "./" }) + .pipe(trimlines({ + leading: false + })) + .pipe(gulp.dest('./')); +}); + +gulp.task('compile', ['trim-whitespace'], shell.task([ 'node ./node_modules/vscode/bin/compile -p ./', ])); -gulp.task('tslint', function() { +gulp.task('tslint', ['trim-whitespace'], function() { return gulp.src([paths.scripts_ts, paths.tests_ts]) .pipe(tslint()) .pipe(tslint.report('prose', { @@ -44,4 +53,4 @@ gulp.task('test', ['compile'], function () { }); gulp.task('init', ['tsd']); -gulp.task('default', ['tslint', 'test']); +gulp.task('default', ['trim-whitespace', 'tslint', 'test']); diff --git a/package.json b/package.json index 99a2dfc0c30..0919a94bbb9 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,7 @@ "gulp-shell": "^0.5.1", "gulp-tsd": "0.0.4", "gulp-tslint": "^3.6.0", + "gulp-trimlines": "^1.0.0", "gulp-typescript": "^2.9.2", "tsd": "^0.6.5", "typescript": "^1.6.2", diff --git a/src/cmd_line/commands/quit.ts b/src/cmd_line/commands/quit.ts index 1b562a79864..e959eca1bd2 100644 --- a/src/cmd_line/commands/quit.ts +++ b/src/cmd_line/commands/quit.ts @@ -21,14 +21,14 @@ export class QuitCommand extends node.CommandBase { this._shortName = 'q'; this._arguments = args; } - + get arguments() : QuitCommandArguments { return this._arguments; } - + execute() : void { this.quit(); - } + } private quit() { // See https://github.com/Microsoft/vscode/issues/723 @@ -36,7 +36,7 @@ export class QuitCommand extends node.CommandBase { && !this.arguments.bang) { throw error.VimError.fromCode(error.ErrorCode.E37); } - + vscode.commands.executeCommand('workbench.action.closeActiveEditor'); }; } diff --git a/src/cmd_line/commands/write.ts b/src/cmd_line/commands/write.ts index 97bbe4f682f..26f101ad5d1 100644 --- a/src/cmd_line/commands/write.ts +++ b/src/cmd_line/commands/write.ts @@ -28,7 +28,7 @@ export class WriteCommand extends node.CommandBase { this._shortName = 'w'; this._arguments = args; } - + get arguments() : WriteCommandArguments { return this._arguments; } @@ -47,10 +47,10 @@ export class WriteCommand extends node.CommandBase { util.showError("Not implemented."); return; } - + if (this.activeTextEditor.document.isUntitled) { throw error.VimError.fromCode(error.ErrorCode.E32); - } + } fs.access(this.activeTextEditor.document.fileName, fs.W_OK, (accessErr) => { if (accessErr) { @@ -71,7 +71,7 @@ export class WriteCommand extends node.CommandBase { }); } - private save() { + private save() { this.activeTextEditor.document.save().then( (ok) => { if (ok) { @@ -82,5 +82,5 @@ export class WriteCommand extends node.CommandBase { }, (e) => util.showError(e) ); - } + } } diff --git a/src/cmd_line/main.ts b/src/cmd_line/main.ts index b56a7bb8475..13969869cd2 100644 --- a/src/cmd_line/main.ts +++ b/src/cmd_line/main.ts @@ -8,7 +8,7 @@ export function showCmdLine(initialText = "") { util.showInfo("No active document."); return; } - + const options : vscode.InputBoxOptions = { prompt: "Vim command line", value: initialText @@ -23,14 +23,14 @@ function runCmdLine(s : string) : void { if (!(s && s.trim())) { return; } - + try { var cmd = parser.parse(s); } catch (e) { util.showError(e); return; } - + if (cmd.isEmpty) { return; } @@ -44,7 +44,7 @@ function runCmdLine(s : string) : void { } catch (ee) { // ignore } - - util.showError(e); + + util.showError(e); } } diff --git a/src/cmd_line/node.ts b/src/cmd_line/node.ts index 4993036bd7e..e2ed083d827 100644 --- a/src/cmd_line/node.ts +++ b/src/cmd_line/node.ts @@ -101,16 +101,16 @@ export interface CommandArgs { } export abstract class CommandBase { - + protected get activeTextEditor() { return vscode.window.activeTextEditor; } - + get name() : string { return this._name; } protected _name : string; - + get shortName() : string { return this._shortName; } @@ -119,7 +119,7 @@ export abstract class CommandBase { get arguments() : CommandArgs { return this._arguments; } - protected _arguments : CommandArgs; - + protected _arguments : CommandArgs; + abstract execute() : void; } diff --git a/src/cmd_line/subparser.ts b/src/cmd_line/subparser.ts index 717f8263959..a49310e150a 100644 --- a/src/cmd_line/subparser.ts +++ b/src/cmd_line/subparser.ts @@ -3,10 +3,10 @@ import {parseWriteCommandArgs} from './subparsers/write'; // TODO: add type for this dict. // maps command names to parsers for said commands. -export const commandParsers = { +export const commandParsers = { 'w': parseWriteCommandArgs, 'write': parseWriteCommandArgs, - + 'quit': parseQuitCommandArgs, 'q': parseQuitCommandArgs }; diff --git a/src/cursor.ts b/src/cursor.ts index a8b95128a44..f8222fc4265 100644 --- a/src/cursor.ts +++ b/src/cursor.ts @@ -1,4 +1,4 @@ -import * as _ from "lodash"; +import * as _ from "lodash"; import * as vscode from "vscode"; import TextEditor from "./textEditor"; @@ -10,7 +10,7 @@ export default class Cursor { return; } let curPosition = this.currentPosition(); - + if (newPosition.line === curPosition.line) { this.prevColumn = newPosition.character; } @@ -31,7 +31,7 @@ export default class Cursor { column--; } - return new vscode.Position(pos.line, column); + return new vscode.Position(pos.line, column); } static right() : vscode.Position { @@ -52,7 +52,7 @@ export default class Cursor { if (!Cursor.isLastLine(pos)) { let nextLineMaxColumn = TextEditor.readLine(++line).length - 1; - + if (nextLineMaxColumn < 0) { nextLineMaxColumn = 0; } @@ -70,7 +70,7 @@ export default class Cursor { let line = pos.line; let column = this.prevColumn; - if (!this.isFirstLine(pos)) { + if (!this.isFirstLine(pos)) { let nextLineMaxColumn = TextEditor.readLine(--line).length - 1; if (nextLineMaxColumn < 0) { @@ -120,45 +120,45 @@ export default class Cursor { static lineEnd() : vscode.Position { let pos = this.currentPosition(); const lineLength = TextEditor.readLine(pos.line).length; - + return new vscode.Position(pos.line, lineLength); } - + static documentBegin() : vscode.Position { return new vscode.Position(0, 0); } - + static documentEnd() : vscode.Position { let line = vscode.window.activeTextEditor.document.lineCount - 1; if (line < 0) { line = 0; } - - let column = TextEditor.readLine(line).length; + + let column = TextEditor.readLine(line).length; return new vscode.Position(line, column); } - + private static isLineBeginning(position : vscode.Position) : boolean { return position.character === 0; - } - + } + private static isLineEnd(position : vscode.Position) : boolean { let lineEnd = TextEditor.readLine(position.line).length - 1; if (lineEnd < 0) { lineEnd = 0; } - + if (position.character > lineEnd) { throw new RangeError; } - + return position.character === lineEnd; } private static isFirstLine(position : vscode.Position) : boolean { return position.line === 0; } - + private static isLastLine(position : vscode.Position): boolean { return position.line === (vscode.window.activeTextEditor.document.lineCount - 1); } diff --git a/src/error.ts b/src/error.ts index 0fbc3241b48..189378fb7ac 100644 --- a/src/error.ts +++ b/src/error.ts @@ -18,36 +18,36 @@ const errors : VimErrors = { export class VimError extends Error { - + private _code : number; private _message : string; - + constructor(code : number, message : string) { super(); this._code = code; this._message = message; } - + static fromCode(code : ErrorCode) : VimError { if (errors[code]) { return new VimError(code, errors[code]); } - + throw new Error("unknown error code: " + code); } - + get code() : number { return this._code; } - + get message() : string { return this._message; } - + display() : void { util.showError(this.toString()); } - + toString() : string { return "E" + this.code.toString() + ": " + this.message; } diff --git a/src/mode/mode.ts b/src/mode/mode.ts index 565ce3338b4..83d33e75bac 100644 --- a/src/mode/mode.ts +++ b/src/mode/mode.ts @@ -26,7 +26,7 @@ export abstract class Mode { set IsActive(val : boolean) { this.isActive = val; } - + public HandleDeactivation() : void { this.keyHistory = []; } diff --git a/src/mode/modeHandler.ts b/src/mode/modeHandler.ts index f06c63521e6..6fc2b5229b1 100644 --- a/src/mode/modeHandler.ts +++ b/src/mode/modeHandler.ts @@ -39,19 +39,19 @@ export default class ModeHandler { handleKeyEvent(key : string) : void { var currentModeName = this.currentMode.Name; - + var nextMode : Mode; var inactiveModes = _.filter(this.modes, (m) => !m.IsActive); - + _.forEach(inactiveModes, (m, i) => { if (m.ShouldBeActivated(key, currentModeName)) { nextMode = m; - } + } }); - + if (nextMode) { this.currentMode.HandleDeactivation(); - + nextMode.HandleActivation(key); this.setCurrentModeByName(nextMode.Name); return; diff --git a/src/mode/modeInsert.ts b/src/mode/modeInsert.ts index 8e3a3bb315b..8451c69562d 100644 --- a/src/mode/modeInsert.ts +++ b/src/mode/modeInsert.ts @@ -5,50 +5,50 @@ import Cursor from './../cursor'; export default class InsertMode extends Mode { private activationKeyHandler : { [ key : string] : () => void; } = {}; - + constructor() { super(ModeName.Insert); - + this.activationKeyHandler = { // insert at cursor "i" : () => { Cursor.move(Cursor.currentPosition()); }, - - // insert at the beginning of the line + + // insert at the beginning of the line "I" : () => { Cursor.move(Cursor.lineBegin()); }, - - // append after the cursor + + // append after the cursor "a" : () => { Cursor.move(Cursor.right()); }, - - // append at the end of the line + + // append at the end of the line "A" : () => { Cursor.move(Cursor.lineEnd()); }, - - // open blank line below current line - "o" : () => { + + // open blank line below current line + "o" : () => { vscode.commands.executeCommand("editor.action.insertLineAfter"); }, - - // open blank line above current line - "O" : () => { + + // open blank line above current line + "O" : () => { vscode.commands.executeCommand("editor.action.insertLineBefore"); - } + } }; } ShouldBeActivated(key : string, currentMode : ModeName) : boolean { return key in this.activationKeyHandler; } - + HandleActivation(key : string) : void { this.activationKeyHandler[key](); } - + HandleKeyEvent(key : string) : void { this.keyHistory.push(key); TextEditor.insert(this.ResolveKeyValue(key)); vscode.commands.executeCommand("editor.action.triggerSuggest"); } - + // Some keys have names that are different to their value. // TODO: we probably need to put this somewhere else. private ResolveKeyValue(key : string) : string { diff --git a/src/mode/modeNormal.ts b/src/mode/modeNormal.ts index d10085c2815..ea633f73575 100644 --- a/src/mode/modeNormal.ts +++ b/src/mode/modeNormal.ts @@ -48,7 +48,7 @@ export default class CommandMode extends Mode { this.keyHistory.push(key); let keyHandled = false; - + for (let window = this.keyHistory.length; window > 0; window--) { let keysPressed = _.takeRight(this.keyHistory, window).join(''); if (this.keyHandler[keysPressed] !== undefined) { @@ -57,7 +57,7 @@ export default class CommandMode extends Mode { break; } } - + if (keyHandled) { this.keyHistory = []; } @@ -69,7 +69,7 @@ export default class CommandMode extends Mode { let range : vscode.Range = new vscode.Range(pos, end); TextEditor.delete(range).then(function() { let lineEnd = Cursor.lineEnd(); - + if (pos.character === lineEnd.character) { Cursor.move(Cursor.left()); } diff --git a/src/mode/modeVisual.ts b/src/mode/modeVisual.ts index c87a61ce404..01291e8017a 100644 --- a/src/mode/modeVisual.ts +++ b/src/mode/modeVisual.ts @@ -9,11 +9,11 @@ export default class VisualMode extends Mode { // TODO: improve this logic for "V". return (key === "v" || key === "V") && (currentMode === ModeName.Normal); } - + HandleActivation(key : string) : void { // do nothing } - + HandleKeyEvent(key : string) : void { this.keyHistory.push(key); } diff --git a/src/textEditor.ts b/src/textEditor.ts index d455f8ed750..4c1c7b5f862 100644 --- a/src/textEditor.ts +++ b/src/textEditor.ts @@ -1,11 +1,11 @@ import * as vscode from "vscode"; -export default class TextEditor { +export default class TextEditor { static insert(text: string, position: vscode.Position = null) : Thenable { if (position === null) { position = vscode.window.activeTextEditor.selection.active; } - + return vscode.window.activeTextEditor.edit((editBuilder) => { editBuilder.insert(position, text); }); @@ -16,26 +16,26 @@ export default class TextEditor { editBuilder.delete(range); }); } - + static replace(range: vscode.Range, text: string) : Thenable { return vscode.window.activeTextEditor.edit((editBuilder) => { editBuilder.replace(range, text); }); } - + static readLine(lineNo: number = null): string { if (lineNo === null) { lineNo = vscode.window.activeTextEditor.selection.active.line; } - + if (lineNo >= vscode.window.activeTextEditor.document.lineCount) { throw new RangeError(); } return vscode.window.activeTextEditor.document.lineAt(lineNo).text; } - + static getLineAt(position: vscode.Position): vscode.TextLine { return vscode.window.activeTextEditor.document.lineAt(position); } diff --git a/test/cmd_line/lexer.test.ts b/test/cmd_line/lexer.test.ts index 83fc19790ea..863dfcc1296 100644 --- a/test/cmd_line/lexer.test.ts +++ b/test/cmd_line/lexer.test.ts @@ -85,7 +85,7 @@ suite("command-line lexer", () => { var tokens = lexer.lex("q something"); assert.equal(tokens[0].content, new Token(TokenType.CommandName, "q").content); assert.equal(tokens[1].content, new Token(TokenType.CommandArgs, " something").content); - }); + }); test("can lex long command name and args", () => { var tokens = lexer.lex("write12 something here"); diff --git a/test/cmd_line/subparser.quit.test.ts b/test/cmd_line/subparser.quit.test.ts index 0a9b27ef02d..a7c364513be 100644 --- a/test/cmd_line/subparser.quit.test.ts +++ b/test/cmd_line/subparser.quit.test.ts @@ -4,9 +4,9 @@ import * as assert from 'assert'; import {commandParsers} from '../../src/cmd_line/subparser'; suite(":quit args parser", () => { - + test("has all aliases", () => { - assert.equal(commandParsers.quit.name, commandParsers.q.name); + assert.equal(commandParsers.quit.name, commandParsers.q.name); }); test("can parse empty args", () => { @@ -14,12 +14,12 @@ suite(":quit args parser", () => { assert.equal(args.arguments.bang, undefined); assert.equal(args.arguments.range, undefined); }); - + test("ignores trailing white space", () => { var args = commandParsers.quit(" "); assert.equal(args.arguments.bang, undefined); assert.equal(args.arguments.range, undefined); - }); + }); test("can parse !", () => { var args = commandParsers.quit("!"); @@ -37,8 +37,8 @@ suite(":quit args parser", () => { assert.equal(args.arguments.bang, true); assert.equal(args.arguments.range, undefined); }); - + test("throws if bad input", () => { assert.throws(() => commandParsers.quit("x")); - }); + }); }); diff --git a/test/cmd_line/subparser.test.ts b/test/cmd_line/subparser.test.ts index 88814efaf1c..672f4b8790a 100644 --- a/test/cmd_line/subparser.test.ts +++ b/test/cmd_line/subparser.test.ts @@ -4,9 +4,9 @@ import * as assert from 'assert'; import {commandParsers} from '../../src/cmd_line/subparser'; suite(":write args parser", () => { - + test("has all aliases", () => { - assert.equal(commandParsers.write.name, commandParsers.w.name); + assert.equal(commandParsers.write.name, commandParsers.w.name); }); test("can parse empty args", () => { @@ -51,7 +51,7 @@ suite(":write args parser", () => { assert.equal(args.arguments.optValue, undefined); assert.equal(args.arguments.range, undefined); }); - + test("can parse ' !cmd'", () => { var args = commandParsers.write(" !foo"); diff --git a/test/cursor.test.ts b/test/cursor.test.ts index 9bd55999038..0ba7c087147 100644 --- a/test/cursor.test.ts +++ b/test/cursor.test.ts @@ -207,7 +207,7 @@ suite("cursor", () => { assert.equal(wordLeft.line, 0); assert.equal(wordLeft.character, 0); }); - + test("wordRight on last word should stay on line at last character", () => { Cursor.move(new vscode.Position(0, 6)); @@ -219,7 +219,7 @@ suite("cursor", () => { assert.equal(pos.line, 0); assert.equal(pos.character, 8); }); - + test("wordRight on end of line should move to next word on next line", () => { Cursor.move(new vscode.Position(0, 8)); @@ -231,7 +231,7 @@ suite("cursor", () => { assert.equal(pos.line, 1); assert.equal(pos.character, 0); }); - + test("wordLeft on first word should move to previous line of end of line", () => { Cursor.move(new vscode.Position(2, 0)); diff --git a/test/error.test.ts b/test/error.test.ts index b3cb90e8180..8fb7f805942 100644 --- a/test/error.test.ts +++ b/test/error.test.ts @@ -30,6 +30,6 @@ suite("vimError", () => { e = VimError.fromCode(ErrorCode.E488); assert.equal(e.code, 488); - assert.equal(e.message, "Trailing characters"); - }); + assert.equal(e.message, "Trailing characters"); + }); }); \ No newline at end of file diff --git a/test/extension.test.ts b/test/extension.test.ts index 8b92343aedf..90732a208eb 100644 --- a/test/extension.test.ts +++ b/test/extension.test.ts @@ -6,7 +6,7 @@ suite("setup", () => { test("all keys have handlers", (done) => { let pkg = require(__dirname + '/../../package.json'); assert.ok(pkg); - + vscode.commands.getCommands() .then(registeredCommands => { let keybindings = pkg.contributes.keybindings; @@ -14,14 +14,14 @@ suite("setup", () => { for (let i = 0; i < keybindings.length; i++) { let keybinding = keybindings[i]; - + var found = registeredCommands.indexOf(keybinding.command) >= -1; assert.ok(found, "Missing handler for key=" + keybinding.key + ". Expected handler=" + keybinding.command); } }) .then(done, done); }); - + test("duplicate keybindings", () => { let pkg = require(__dirname + '/../../package.json'); assert.ok(pkg); @@ -30,7 +30,7 @@ suite("setup", () => { let duplicateKeys = _.filter(keys, function(x, i, array) { return _.includes(array, x, i + 1); }); - + assert.equal(duplicateKeys.length, 0, "Duplicate Keybindings: " + duplicateKeys.join(',')); }); }); diff --git a/test/index.ts b/test/index.ts index f94c09903cf..38729a564ee 100644 --- a/test/index.ts +++ b/test/index.ts @@ -1,9 +1,9 @@ -// -// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING +// +// PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING // // This file is providing the test runner to use when running extension tests. // By default the test runner in use is Mocha based. -// +// // You can provide your own test runner if you want to override it by exporting // a function run(testRoot: string, clb: (error:Error) => void) that the extension // host can call to run the tests. The test runner is expected to use console.log diff --git a/test/mode/modeHandler.test.ts b/test/mode/modeHandler.test.ts index 49d205dd13e..78cacffdb51 100644 --- a/test/mode/modeHandler.test.ts +++ b/test/mode/modeHandler.test.ts @@ -6,11 +6,11 @@ suite("Mode Handler", () => { test("ctor", () => { var modeHandler = new ModeHandler(); - + assert.equal(modeHandler.currentMode.Name, ModeName.Normal); assert.equal(modeHandler.currentMode.IsActive, true); }); - + test("can set current mode", () => { var modeHandler = new ModeHandler(); @@ -21,6 +21,6 @@ suite("Mode Handler", () => { assert.equal(modeHandler.currentMode.Name, ModeName.Insert); modeHandler.setCurrentModeByName(ModeName.Visual); - assert.equal(modeHandler.currentMode.Name, ModeName.Visual); + assert.equal(modeHandler.currentMode.Name, ModeName.Visual); }); }); diff --git a/test/mode/modeNormal.test.ts b/test/mode/modeNormal.test.ts index c1ddda037be..a2485e6eaaf 100644 --- a/test/mode/modeNormal.test.ts +++ b/test/mode/modeNormal.test.ts @@ -6,9 +6,9 @@ import {ModeName} from '../../src/mode/mode'; suite("Mode Normal", () => { test("can be activated", () => { let activationKeys = ['esc', 'ctrl+[']; - + let modeHandler = new ModeNormal(); - + for (let i = 0; i < activationKeys.length; i++) { let key = activationKeys[i]; assert.equal(modeHandler.ShouldBeActivated(key, ModeName.Insert), true, key); diff --git a/test/textEditor.test.ts b/test/textEditor.test.ts index 8ef25412998..e64b71c43e4 100644 --- a/test/textEditor.test.ts +++ b/test/textEditor.test.ts @@ -13,17 +13,17 @@ suite("text editor", () => { var range = new vscode.Range(Cursor.documentBegin(), Cursor.documentEnd()); TextEditor.delete(range).then(done()); }); - + test("insert 'Hello World'", done => { let expectedText = "Hello World"; - + TextEditor.insert(expectedText).then(x => { assert.equal(vscode.window.activeTextEditor.document.lineCount, 1); let actualText = TextEditor.readLine(0); assert.equal(actualText, expectedText); }).then(done, done); }); - + test("replace 'World' with 'Foo Bar'", done => { let newText = "Foo Bar"; let start = new vscode.Position(0, 6); @@ -37,7 +37,7 @@ suite("text editor", () => { assert.equal(actualText, "Hello Foo Bar"); }).then(done, done); }); - + test("delete `Hello`", done => { assert.equal(vscode.window.activeTextEditor.document.lineCount, 1); @@ -49,7 +49,7 @@ suite("text editor", () => { assert.equal(actualText, " Foo Bar"); }).then(done, done); }); - + test("delete the whole line", done => { assert.equal(vscode.window.activeTextEditor.document.lineCount, 1); @@ -60,7 +60,7 @@ suite("text editor", () => { assert.equal(actualText, ""); }).then(done, done); }); - + test("try to read lines that don't exist", () => { assert.equal(vscode.window.activeTextEditor.document.lineCount, 1); assert.throws(() => TextEditor.readLine(1), RangeError); diff --git a/tslint.json b/tslint.json index 62299a05c2e..faed56a1a36 100644 --- a/tslint.json +++ b/tslint.json @@ -35,7 +35,7 @@ "no-string-literal": true, "no-switch-case-fall-through": true, "no-trailing-comma": true, - "no-trailing-whitespace": false, + "no-trailing-whitespace": true, "no-unused-expression": true, "no-unused-variable": true, "no-unreachable": true, @@ -60,4 +60,4 @@ "check-type" ] } -} \ No newline at end of file +}