<commit_before>var ArgsParser = require('./args-parser');
var FS = require('./fs');
var File = require('./file');
var stream = require('stream');

var CommandManager = {
  commands: {},
  aliases: {},
};

CommandManager.isValid = function (cmd) {
  return !!(this.commands[cmd] || this.aliases[cmd]);
};

CommandManager.autocomplete = function (cmd) {
  var matches = [];
  cmd = cmd.toLowerCase();

  (Object.keys(this.commands).concat(Object.keys(this.aliases))).forEach(function (command) {
    if (command.substr(0, cmd.length).toLowerCase() === cmd) {
      matches.push(command);
    }
  });

  return matches;
};
CommandManager.parse = function (cmd) {
  if (~cmd.indexOf('|')) {
    cmd = cmd.split('|');
    cmd.forEach(CommandManager.parse);
  }

  cmd = cmd.split(' ');
  var command = cmd.shift();
  var args = cmd.join(' ');
  var stdin = Terminal.stdin;
  var stdout = Terminal.stdout;
  var stderr = Terminal.stderr;
  var next = function () {
    Terminal.prompt();
  };

  var index;

  if (~(index = args.indexOf('>'))) {
    var prev = args[index-1];
    var append = args[index+1] === '>';
    var init = index;

    if (~(['1','2','&']).indexOf(prev)) {
      init--;
    }
    
    var _args = args.substr(0, init);
    args = args.substr(index+append+1).split(' ').filter(String);
    var path = args.shift();
    args = _args + args.join(' ');

    if (!path) {
      stdout.write('zsh: parse error near `\\n\'');
      return;
    }

    var file = new File(path);

    if (!file.parentExists()) {
      stdout.write('zsh: no such file or directory: ' + file.path);
      return;
    } else if (!file.isValid()) {
      stdout.write('zsh: not a directory: ' + file.path);
      return;
    } else if (file.isDir()) {
      stdout.write('zsh: is a directory: ' + file.path);
      return;
    }

    if (!append) {
      file.clear();
    }

    stdout = new stream.PassThrough();
    stdout.on('data', function(data) {
      file.write(data + '\n', true, true);
    });

    if (prev === '2' || prev === '&') {
      stderr = stdout;
    }

    var _next = next;
    next = function () {
      FS.writeFS();
      _next();
    };
  }

  CommandManager.exec(command, args, stdin, stdout, stderr, next);
};

CommandManager.exec = function (cmd, args, stdin, stdout, stderr, next) {
  if (this.aliases[cmd]) {
    var line = (this.aliases[cmd] + ' ' + args).trim().split(' ');
    return this.exec(line.shift(), line.join(' '), stdin, stdout, stderr, next);
  }
<commit_msg>fix: allow to redirect only stderr<commit_after>var ArgsParser = require('./args-parser');
var FS = require('./fs');
var File = require('./file');
var stream = require('stream');

var CommandManager = {
  commands: {},
  aliases: {},
};

CommandManager.isValid = function (cmd) {
  return !!(this.commands[cmd] || this.aliases[cmd]);
};

CommandManager.autocomplete = function (cmd) {
  var matches = [];
  cmd = cmd.toLowerCase();

  (Object.keys(this.commands).concat(Object.keys(this.aliases))).forEach(function (command) {
    if (command.substr(0, cmd.length).toLowerCase() === cmd) {
      matches.push(command);
    }
  });

  return matches;
};
CommandManager.parse = function (cmd) {
  if (~cmd.indexOf('|')) {
    cmd = cmd.split('|');
    cmd.forEach(CommandManager.parse);
  }

  cmd = cmd.split(' ');
  var command = cmd.shift();
  var args = cmd.join(' ');
  var stdin = Terminal.stdin;
  var stdout = Terminal.stdout;
  var stderr = Terminal.stderr;
  var next = function () {
    Terminal.prompt();
  };

  var index;

  if (~(index = args.indexOf('>'))) {
    var prev = args[index-1];
    var append = args[index+1] === '>';
    var init = index;

    if (~(['1','2','&']).indexOf(prev)) {
      init--;
    }
    
    var _args = args.substr(0, init);
    args = args.substr(index+append+1).split(' ').filter(String);
    var path = args.shift();
    args = _args + args.join(' ');

    if (!path) {
      stdout.write('zsh: parse error near `\\n\'');
      return;
    }

    var file = new File(path);

    if (!file.parentExists()) {
      stdout.write('zsh: no such file or directory: ' + file.path);
      return;
    } else if (!file.isValid()) {
      stdout.write('zsh: not a directory: ' + file.path);
      return;
    } else if (file.isDir()) {
      stdout.write('zsh: is a directory: ' + file.path);
      return;
    }

    if (!append) {
      file.clear();
    }

    var _stdout = new stream.PassThrough();
    _stdout.on('data', function(data) {
      file.write(data + '\n', true, true);
    });

    if (prev !== '2') {
      stdout = _stdout;
    }

    if (prev === '2' || prev === '&') {
      stderr = _stdout;
    }

    var _next = next;
    next = function () {
      FS.writeFS();
      _next();
    };
  }

  CommandManager.exec(command, args, stdin, stdout, stderr, next);
};

CommandManager.exec = function (cmd, args, stdin, stdout, stderr, next) {
  if (this.aliases[cmd]) {
    var line = (this.aliases[cmd] + ' ' + args).trim().split(' ');
    return this.exec(line.shift(), line.join(' '), stdin, stdout, stderr, next);
  }

{'fraction_non_alphanumeric': 0.19625615763546797, 'fraction_numerical': 0.003349753694581281, 'mean_word_length': 2.7739776951672863, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '3195928', 'n_tokens_mistral': 1765, 'n_tokens_neox': 1716, 'n_words': 389}