Skip to content

Commit

Permalink
Merge pull request #1665 from mspaulding06/close-command-support
Browse files Browse the repository at this point in the history
Add :close support based on :quit
  • Loading branch information
johnfn authored May 7, 2017
2 parents 508d7f5 + a64336a commit 257004e
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 0 deletions.
45 changes: 45 additions & 0 deletions src/cmd_line/commands/close.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"use strict";

import * as vscode from "vscode";
import * as node from "../node";
import * as error from '../../error';

export interface ICloseCommandArguments extends node.ICommandArgs {
bang?: boolean;
range?: node.LineRange;
quitAll?: boolean;
}

//
// Implements :close
// http://vimdoc.sourceforge.net/htmldoc/windows.html#:close
//
export class CloseCommand extends node.CommandBase {
protected _arguments : ICloseCommandArguments;

constructor(args : ICloseCommandArguments) {
super();
this._name = 'close';
this._arguments = args;
}

get arguments() : ICloseCommandArguments {
return this._arguments;
}

async execute() : Promise<void> {
if (this.activeTextEditor!.document.isDirty && !this.arguments.bang) {
throw error.VimError.fromCode(error.ErrorCode.E37);
}

if (vscode.window.visibleTextEditors.length === 1) {
throw error.VimError.fromCode(error.ErrorCode.E444);
}

let oldViewColumn = this.activeTextEditor!.viewColumn;
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');

if (vscode.window.activeTextEditor !== undefined && vscode.window.activeTextEditor.viewColumn === oldViewColumn) {
await vscode.commands.executeCommand('workbench.action.previousEditor');
}
}}
4 changes: 4 additions & 0 deletions src/cmd_line/subparser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { parseReadCommandArgs } from './subparsers/read';
import { parseRegisterCommandArgs } from './subparsers/register';
import { parseDeleteRangeLinesCommandArgs } from './subparsers/deleteRange';
import { parseSortCommandArgs } from './subparsers/sort';
import { parseCloseCommandArgs } from './subparsers/close';

// maps command names to parsers for said commands.
export const commandParsers = {
Expand All @@ -27,6 +28,9 @@ export const commandParsers = {
noh: parseNohlCommandArgs,
nohl: parseNohlCommandArgs,

close: parseCloseCommandArgs,
clo: parseCloseCommandArgs,

quit: parseQuitCommandArgs,
q: parseQuitCommandArgs,

Expand Down
25 changes: 25 additions & 0 deletions src/cmd_line/subparsers/close.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use strict";

import * as node from "../commands/close";
import {Scanner} from '../scanner';
import {VimError, ErrorCode} from '../../error';

export function parseCloseCommandArgs(args : string) : node.CloseCommand {
if (!args) {
return new node.CloseCommand({});
}
var scannedArgs : node.ICloseCommandArguments = {};
var scanner = new Scanner(args);
const c = scanner.next();
if (c === '!') {
scannedArgs.bang = true;
scanner.ignore();
} else if (c !== ' ') {
throw VimError.fromCode(ErrorCode.E488);
}
scanner.skipWhiteSpace();
if (!scanner.isAtEof) {
throw VimError.fromCode(ErrorCode.E488);
}
return new node.CloseCommand(scannedArgs);
}
2 changes: 2 additions & 0 deletions src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export enum ErrorCode {
E32 = 32,
E208 = 208,
E348 = 348,
E444 = 444,
E488 = 488
}

Expand All @@ -19,6 +20,7 @@ const errors : IVimErrors = {
37: "No write since last change (add ! to override)",
208: "Error writing to file",
348: "No string under cursor",
444: "Cannot close last window",
488: "Trailing characters"
};

Expand Down
46 changes: 46 additions & 0 deletions test/cmd_line/subparser.close.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"use strict";

// The module 'assert' provides assertion methods from node
import * as assert from 'assert';

import {commandParsers} from '../../src/cmd_line/subparser';

suite(":close args parser", () => {

test("has all aliases", () => {
assert.equal(commandParsers.close.name, commandParsers.clo.name);
});

test("can parse empty args", () => {
var args = commandParsers.close("");
assert.equal(args.arguments.bang, undefined);
assert.equal(args.arguments.range, undefined);
});

test("ignores trailing white space", () => {
var args = commandParsers.close(" ");
assert.equal(args.arguments.bang, undefined);
assert.equal(args.arguments.range, undefined);
});

test("can parse !", () => {
var args = commandParsers.close("!");
assert.ok(args.arguments.bang);
assert.equal(args.arguments.range, undefined);
});

test("throws if space before !", () => {
assert.throws(() => commandParsers.close(" !"));
});

test("ignores space after !", () => {

var args = commandParsers.close("! ");
assert.equal(args.arguments.bang, true);
assert.equal(args.arguments.range, undefined);
});

test("throws if bad input", () => {
assert.throws(() => commandParsers.close("x"));
});
});
5 changes: 5 additions & 0 deletions test/error.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ suite("ErrorCode", () => {
assert.equal(ErrorCode.E37, 37);
assert.equal(ErrorCode.E208, 208);
assert.equal(ErrorCode.E348, 348);
assert.equal(ErrorCode.E444, 444);
assert.equal(ErrorCode.E488, 488);
});
});
Expand All @@ -29,6 +30,10 @@ suite("vimError", () => {
assert.equal(e.code, 37);
assert.equal(e.message, "No write since last change (add ! to override)");

e = VimError.fromCode(ErrorCode.E444);
assert.equal(e.code, 444);
assert.equal(e.message, "Cannot close last window");

e = VimError.fromCode(ErrorCode.E488);
assert.equal(e.code, 488);
assert.equal(e.message, "Trailing characters");
Expand Down

0 comments on commit 257004e

Please sign in to comment.