Skip to content

Commit

Permalink
Change :w to be non-blocking write
Browse files Browse the repository at this point in the history
This changes the :w behavior to write in background to unfreeze the VS Code UI when the user is using VS Code Remote while allowing operation like wq and wa to work in VS Code
  • Loading branch information
stevenguh committed Aug 29, 2019
1 parent c425da3 commit 4013234
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 24 deletions.
52 changes: 30 additions & 22 deletions src/cmd_line/commands/write.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as fs from 'fs';
import * as node from '../node';
import * as path from 'path';
import * as util from 'util';
import * as vscode from 'vscode';
import { promisify } from 'util';
import { Logger } from '../../util/logger';
import { StatusBar } from '../../statusBar';
import { VimState } from '../../state/vimState';
Expand All @@ -15,6 +15,7 @@ export interface IWriteCommandArguments extends node.ICommandArgs {
file?: string;
append?: boolean;
cmd?: string;
bgWrite?: boolean;
}

//
Expand Down Expand Up @@ -52,42 +53,49 @@ export class WriteCommand extends node.CommandBase {

// defer saving the file to vscode if file is new (to present file explorer) or if file is a remote file
if (vimState.editor.document.isUntitled || vimState.editor.document.uri.scheme !== 'file') {
await vscode.commands.executeCommand('workbench.action.files.save');
await this.background(vscode.commands.executeCommand('workbench.action.files.save'));
return;
}

try {
await util.promisify(fs.access)(vimState.editor.document.fileName, fs.constants.W_OK);
await promisify(fs.access)(vimState.editor.document.fileName, fs.constants.W_OK);
return this.save(vimState);
} catch (accessErr) {
if (this.arguments.bang) {
fs.chmod(vimState.editor.document.fileName, 666, e => {
if (!e) {
return this.save(vimState);
}
try {
await promisify(fs.chmod)(vimState.editor.document.fileName, 666);
return this.save(vimState);
} catch (e) {
StatusBar.Set(e.message, vimState.currentMode, vimState.isRecordingMacro, true);
return;
});
}
} else {
StatusBar.Set(accessErr.message, vimState.currentMode, vimState.isRecordingMacro, true);
}
}
}

private async save(vimState: VimState): Promise<void> {
await vimState.editor.document.save().then(
() => {
let text =
'"' +
path.basename(vimState.editor.document.fileName) +
'" ' +
vimState.editor.document.lineCount +
'L ' +
vimState.editor.document.getText().length +
'C written';
StatusBar.Set(text, vimState.currentMode, vimState.isRecordingMacro, true);
},
e => StatusBar.Set(e, vimState.currentMode, vimState.isRecordingMacro, true)
await this.background(
vimState.editor.document.save().then(
() => {
let text =
'"' +
path.basename(vimState.editor.document.fileName) +
'" ' +
vimState.editor.document.lineCount +
'L ' +
vimState.editor.document.getText().length +
'C written';
StatusBar.Set(text, vimState.currentMode, vimState.isRecordingMacro, true);
},
e => StatusBar.Set(e, vimState.currentMode, vimState.isRecordingMacro, true)
)
);
}

private async background(fn: Thenable<void>): Promise<void> {
if (!this._arguments.bgWrite) {
await fn;
}
}
}
4 changes: 2 additions & 2 deletions src/cmd_line/subparsers/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { Scanner } from '../scanner';

export function parseWriteCommandArgs(args: string): WriteCommand {
if (!args) {
return new WriteCommand({});
return new WriteCommand({ bgWrite: true });
}
const scannedArgs: IWriteCommandArguments = {};
const scannedArgs: IWriteCommandArguments = { bgWrite: true };
const scanner = new Scanner(args);
while (true) {
scanner.skipWhiteSpace();
Expand Down

0 comments on commit 4013234

Please sign in to comment.