Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WriteQuit #354

Merged
merged 4 commits into from
Jul 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/cmd_line/commands/writequit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"use strict";

import * as vscode from "vscode";
import * as node from "../node";
import * as error from "../../error";
import {ModeHandler} from "../../mode/modeHandler";

//
// Implements :writequit
// http://vimdoc.sourceforge.net/htmldoc/editing.html#write-quit
//
export interface IWriteQuitCommandArguments extends node.ICommandArgs {
// arguments
// [++opt]
opt? : string;
optValue? : string;
// wq! [++opt]
bang? : boolean;
// wq [++opt] {file}
file? : string;
// wq! [++opt] {file}
// [range]wq[!] [++opt] [file]
range?: node.LineRange;
}

export class WriteQuitCommand extends node.CommandBase {
protected _arguments : IWriteQuitCommandArguments;

constructor(args : IWriteQuitCommandArguments) {
super();
this._name = "writequit";
this._shortName = "wq";
this._arguments = args;
}

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

// Writing command. Taken as a basis from the "write.ts" file.
execute(modeHandler : ModeHandler) : void {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside from lines 69, 77, this is the same as what's in write.ts. Any way we can just call that function instead? Maybe we can change the execute signature to a bool to indicate a success and if the write access was successful, go on and do the quit side of things?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come we can't just use vscode.commands.executeCommand("workbench.action.files.save")?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use this to save the file or to save a new file?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Save. Maybe there's another one for save as?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use workbench.action.files.saveAs command.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could that then be used to save the file as a specific name?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When this command is triggered, a pop up window will show up for user to type file name and location, so we don't need to pass file name to it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can try it by adding below binding to your keybinding configuration.

{
        "key": "ctrl+0",
        "command": "workbench.action.files.saveAs",
        "when": ""
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome thanks man. I'll take a look tomorrow. Actually just installing Manjaro on my desktop on a different hard drive tonight. Giving i3wm a shot

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

var filename : RegExp = new RegExp("Untitled-[0-9]*");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this approach is tightly coupled to how VSCode names untitled documents - if they ever change, then saving will break. Is there any other way to check this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was one of the ways I found right through the API. I don't know where else I could get it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also it’s how we use it in src/cmd_line/commands/write.ts as well

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, if there's really no other way, we can just merge it. It's not that bad.

if (!this.activeTextEditor.document.isDirty) {
if (filename.test(this.activeTextEditor.document.fileName)) {
vscode.commands.executeCommand("workbench.action.files.saveAs");
} else {
vscode.commands.executeCommand("workbench.action.files.save");
}
vscode.commands.executeCommand('workbench.action.closeActiveEditor');
} else {
throw error.VimError.fromCode(error.ErrorCode.E208);
}
}
}
4 changes: 2 additions & 2 deletions src/cmd_line/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function parseCommand(state : ParserState, commandLine : node.CommandLine) : IPa
case token.TokenType.CommandName:
var commandParser = (commandParsers as any)[tok.content];
if (!commandParser) {
throw new Error("not implemented or not a valid command");
throw new Error("Not implemented or not a valid command");
}
// TODO: Pass the args, but keep in mind there could be multiple
// commands, not just one.
Expand All @@ -60,7 +60,7 @@ function parseCommand(state : ParserState, commandLine : node.CommandLine) : IPa
commandLine.command = commandParser(args);
return null;
default:
throw new Error("not implemented");
throw new Error("Not implemented");
}
}
if (!state.isAtEof) {
Expand Down
4 changes: 4 additions & 0 deletions src/cmd_line/subparser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import {parseQuitCommandArgs} from './subparsers/quit';
import {parseWriteCommandArgs} from './subparsers/write';
import {parseWriteQuitCommandArgs} from './subparsers/writequit';
import * as tabCmd from './subparsers/tab';
import * as fileCmd from './subparsers/file';

Expand All @@ -13,6 +14,9 @@ export const commandParsers = {
quit: parseQuitCommandArgs,
q: parseQuitCommandArgs,

wq: parseWriteQuitCommandArgs,
writequit: parseWriteQuitCommandArgs,

tabn: tabCmd.parseTabNCommandArgs,
tabnext: tabCmd.parseTabNCommandArgs,

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

import {WriteQuitCommand, IWriteQuitCommandArguments} from '../commands/writequit';
import {Scanner} from '../scanner';

export function parseWriteQuitCommandArgs(args : string) : WriteQuitCommand {
if (!args) {
return new WriteQuitCommand({});
}
var scannedArgs : IWriteQuitCommandArguments = {};
var scanner = new Scanner(args);
while (true) {
scanner.skipWhiteSpace();
if (scanner.isAtEof) {
break;
}
let c = scanner.next();
switch (c) {
case '!':
// :writequit!
scannedArgs.bang = true;
scanner.ignore();
continue;
case '+':
// :writequit ++opt=value
scanner.expect('+');
scanner.ignore();
scanner.expectOneOf(['bin', 'nobin', 'ff', 'enc']);
scannedArgs.opt = scanner.emit();
scanner.expect('=');
scanner.ignore();
while (!scanner.isAtEof) {
let c = scanner.next();
if (c !== ' ' || c !== '\t') {
continue;
}
scanner.backup();
continue;
}
let value = scanner.emit();
if (!value) {
throw new Error("Expected value for option.");
}
scannedArgs.optValue = value;
continue;
default:
throw new Error("Not implemented");
}
}
// TODO: parse the stuff (it's really not).
// ++bin ++nobin ++ff ++enc =VALUE
return new WriteQuitCommand(scannedArgs);
}
2 changes: 2 additions & 0 deletions src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ interface IVimErrors {
export enum ErrorCode {
E37 = 37,
E32 = 32,
E208 = 208,
E488 = 488
}

const errors : IVimErrors = {
32: "No file name",
37: "No write since last change (add ! to override)",
208: "Error writing to file",
488: "Trailing characters"
};

Expand Down