<commit_before>import * as fs from 'fs';
import * as path from 'path';
import * as util from 'util';
import * as vscode from 'vscode';

import { VimState } from '../../state/vimState';
import { StatusBar } from '../../statusBar';
import { Message } from '../../util/message';
import * as node from '../node';

export interface IWriteCommandArguments extends node.ICommandArgs {
  opt?: string;
  optValue?: string;
  bang?: boolean;
  range?: node.LineRange;
  file?: string;
  append?: boolean;
  cmd?: string;
}

//
//  Implements :write
//  http://vimdoc.sourceforge.net/htmldoc/editing.html#:write
//
export class WriteCommand extends node.CommandBase {
  protected _arguments: IWriteCommandArguments;

  constructor(args: IWriteCommandArguments) {
    super();
    this._name = 'write';
    this._arguments = args;
  }

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

  async execute(vimState: VimState): Promise<void> {
    if (this.arguments.opt) {
      Message.ShowError('Not implemented.');
      return;
    } else if (this.arguments.file) {
      Message.ShowError('Not implemented.');
      return;
    } else if (this.arguments.append) {
      Message.ShowError('Not implemented.');
      return;
    } else if (this.arguments.cmd) {
      Message.ShowError('Not implemented.');
      return;
    }

    if (vimState.editor.document.isUntitled || vimState.editor.document.uri.scheme !== 'file') {
      await vscode.commands.executeCommand('workbench.action.files.save');
      return;
    }

    try {
      await util.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);
          }
          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 =
          '"' +<commit_msg>Update write.ts<commit_after>import * as fs from 'fs';
import * as path from 'path';
import * as util from 'util';
import * as vscode from 'vscode';

import { VimState } from '../../state/vimState';
import { StatusBar } from '../../statusBar';
import { Message } from '../../util/message';
import * as node from '../node';

export interface IWriteCommandArguments extends node.ICommandArgs {
  opt?: string;
  optValue?: string;
  bang?: boolean;
  range?: node.LineRange;
  file?: string;
  append?: boolean;
  cmd?: string;
}

//
//  Implements :write
//  http://vimdoc.sourceforge.net/htmldoc/editing.html#:write
//
export class WriteCommand extends node.CommandBase {
  protected _arguments: IWriteCommandArguments;

  constructor(args: IWriteCommandArguments) {
    super();
    this._name = 'write';
    this._arguments = args;
  }

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

  async execute(vimState: VimState): Promise<void> {
    if (this.arguments.opt) {
      Message.ShowError('Not implemented.');
      return;
    } else if (this.arguments.file) {
      Message.ShowError('Not implemented.');
      return;
    } else if (this.arguments.append) {
      Message.ShowError('Not implemented.');
      return;
    } else if (this.arguments.cmd) {
      Message.ShowError('Not implemented.');
      return;
    }
    
    // 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');
      return;
    }

    try {
      await util.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);
          }
          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 =
          '"' +
{'fraction_non_alphanumeric': 0.138894815446981, 'fraction_numerical': 0.0012801365478984424, 'mean_word_length': 2.8207008964955174, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3843092', 'n_tokens_mistral': 1461, 'n_tokens_neox': 1445, 'n_words': 320}