<commit_before>/**
 * @license
 * readline-async 0.0.1 - An asynchronous readline interface for Node.js.
 * Copyright 2015-2016 <NAME>
 * Available under MIT license <http://opensource.org/licenses/MIT>
 */

var readline = require('readline')
var childProcess = require('child_process')
var util = require('dantil')

// Instantiate a readline `Interface`.
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  completer: function (line) {
    // Find all command names that can follow input.
    var matches = rl.commandNames.filter(function (commandName) {
      return commandName.indexOf(line) === 0
    })

    // Show nothing if no completions found.
    return [ matches, line ]
  },
})

// Used by 'line' event listener to execute commands when invoked via input.
rl.commands = {}

// Used by `rl.completer` for `<tab>` autocompletion of the names of `rl.commands`.
rl.commandNames = []

// Used to map command names to strings of the command name and associated argument names, if any, for display in the usage screen.
rl.commandDisplayNames = {}

// Used for display in the usage screen.
rl.commandDescriptions = {}

// The usage screen used by `rl._printUsage()`.
rl.usage = ''

// Used by 'SIGINT' event listener to prompt the user to confirm before closing the RLI instance.
rl.sawSIGINT = false

/**
 * Spawns a new process within the readline `Interface` (RLI) to asynchronously run `command` with `args`.
 *
 * Runs the child process within the user's shell (i.e., `$SHELL`), enabling `args` to contain pipes (e.g., `test | pbcopy`), IO redirection (e.g., `test > file`), globs (e.g., `*.js`), et cetera.
 *
 * Executes `command` as an asynchronous child process, leaving the event loop unblocked, but with the appearance of running synchronously. I.e., the user can not enter input (e.g., commands) during the process, but can terminate the process with `^C` and return to the RLI. In contrast, Node's default RLI blocks the event loop, requiring processes to complete before accepting any input; i.e., the user must externally kill the entire RLI process.
 *
 * Temporarily disables the RLI's `stdio` (input and output) while the child is processing, except for `^C` (`SIGINT`) to terminate the child. Restores the RLI `stdio` when the child exits or terminates.
 *
 * @memberOf rl
 * @param {string} command The command to run as a child process.
 * @param {string[]} args The command line arguments for `command`.
 * @param {string|*[]} [stdio=[ 'ignore', process.stdout, process.stderr ]] The optional child process's `stdio` configuration.
 * @param {Function} [callback] The optional function to execute after the child process exits and before returning control to the RLI.
 * @returns {ChildProcess} Returns the spawned `ChildProcess`.
 * @example
 *
 * rl.addCommands({
 *   name: 'test',
 *   description: 'Run \'myTest.js\' as terminable asynchronous child process.',
 *   func: function () {
 *     rl.spawnAsyncProcess('node', [ './myTest.js' ])
 *   }
 * })
 * ```
 * ```
 * ❯ .test
 * ...executing stuff in 'myTest.js'...
 * ...
 * → user sends `^C` from command line
 * Error: Child process terminated due to receipt of signal SIGINT
 * ❯ .test | grep "Danny" | pbcopy
 * ...executing 'myTest.js' and piping output...
 */
rl.spawnAsyncProcess = function (command, args, stdio, callback) {
  // Check arity.
  if (typeof stdio === 'function') {
    callback = stdio
    stdio = null
  }

  // Prevent printing prompt when executing child process, but continue processing input such as `^C` for `SIGINT` (which `rl.pause()` would prevent).
  this.paused = true

  // Launches a new process with `command` and the command line arguments in `args`. This child process avoids blocking the event loop. Unless `stdio` is provided as an argument, the child process ignores input and inherits `stdout` and `stderr`.
  var child = childProcess.spawn(command, args, {
    stdio: stdio || [ 'ignore', process.stdout, process.stderr ],
    // Run process inside in a shell to enable pipes (e.g., `test | pbcopy`), IO redirection (e.g., `test > file`), et cetera, inside `args`.
    // Define `shell` as `process.env.SHELL` (which uses `$SHELL`) instead of `true` (which uses `sh` on UNIX) to enable IO redirection (i.e., `<` and `>`) and globs (e.g., `ls *.js`), which are unavailable in `sh`, and logging shell history.
    shell: process.env.SHELL,
  })

  // Disable output from RLI while child is processing.
  var origStdoutWrite = this.output.write
  this.output.write = function () {}

  // Temporarily remove RLI `line` event listener(s) (when the user hits `enter`).
  var lineListeners = this.listeners('line')
  this.removeAllListeners('line')

  // Send `SIGINT` to child process when received by the RLI.
  function killChild() {
    child.kill('SIGINT')
  }

  // Temporarily replace existing RLI `SIGINT` event listener(s).
  var SIGINTListeners = this.listeners('SIGINT')
  this.removeAllListeners('SIGINT')
  this.on('SIGINT', killChild)

  child.on('error', function (err) {
    util.log()
    util.logError('Failed to start child process:', err.code)
  })

  var self = this

  // The 'exit' event is emitted when the child process ends.
  child.on('exit', function (code, signal) {
    // Restore `stdout`.
    self.output.write = origStdoutWrite

    // Restore `SIGINT` event listeners(s).
    self.removeListener('SIGINT', killChild)
    SIGINTListeners.forEach(function (listener) {
      self.on('SIGINT', listener)
    })

    if (signal) {
      // `child` was killed (most often is due to `SIGINT` sent by the RLI).
      util.log()
      util.logError('Child process terminated due to receipt of signal', signal)
    } else if (code !== 0) {
      // `child` exited with a 'failure' code (most often after an exception is thrown).
      util.log()
      util.logError('Child process exited with code', code)
    } else if (callback) {
      // `child` exited normally. Execute `callback` before returning control to the RLI.<commit_msg>Tweak error message styling<commit_after>/**
 * @license
 * readline-async 0.0.1 - An asynchronous readline interface for Node.js.
 * Copyright 2015-2016 <NAME>
 * Available under MIT license <http://opensource.org/licenses/MIT>
 */

var readline = require('readline')
var childProcess = require('child_process')
var util = require('dantil')

// Instantiate a readline `Interface`.
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  completer: function (line) {
    // Find all command names that can follow input.
    var matches = rl.commandNames.filter(function (commandName) {
      return commandName.indexOf(line) === 0
    })

    // Show nothing if no completions found.
    return [ matches, line ]
  },
})

// Used by 'line' event listener to execute commands when invoked via input.
rl.commands = {}

// Used by `rl.completer` for `<tab>` autocompletion of the names of `rl.commands`.
rl.commandNames = []

// Used to map command names to strings of the command name and associated argument names, if any, for display in the usage screen.
rl.commandDisplayNames = {}

// Used for display in the usage screen.
rl.commandDescriptions = {}

// The usage screen used by `rl._printUsage()`.
rl.usage = ''

// Used by 'SIGINT' event listener to prompt the user to confirm before closing the RLI instance.
rl.sawSIGINT = false

/**
 * Spawns a new process within the readline `Interface` (RLI) to asynchronously run `command` with `args`.
 *
 * Runs the child process within the user's shell (i.e., `$SHELL`), enabling `args` to contain pipes (e.g., `test | pbcopy`), IO redirection (e.g., `test > file`), globs (e.g., `*.js`), et cetera.
 *
 * Executes `command` as an asynchronous child process, leaving the event loop unblocked, but with the appearance of running synchronously. I.e., the user can not enter input (e.g., commands) during the process, but can terminate the process with `^C` and return to the RLI. In contrast, Node's default RLI blocks the event loop, requiring processes to complete before accepting any input; i.e., the user must externally kill the entire RLI process.
 *
 * Temporarily disables the RLI's `stdio` (input and output) while the child is processing, except for `^C` (`SIGINT`) to terminate the child. Restores the RLI `stdio` when the child exits or terminates.
 *
 * @memberOf rl
 * @param {string} command The command to run as a child process.
 * @param {string[]} args The command line arguments for `command`.
 * @param {string|*[]} [stdio=[ 'ignore', process.stdout, process.stderr ]] The optional child process's `stdio` configuration.
 * @param {Function} [callback] The optional function to execute after the child process exits and before returning control to the RLI.
 * @returns {ChildProcess} Returns the spawned `ChildProcess`.
 * @example
 *
 * rl.addCommands({
 *   name: 'test',
 *   description: 'Run \'myTest.js\' as terminable asynchronous child process.',
 *   func: function () {
 *     rl.spawnAsyncProcess('node', [ './myTest.js' ])
 *   }
 * })
 * ```
 * ```
 * ❯ .test
 * ...executing stuff in 'myTest.js'...
 * ...
 * → user sends `^C` from command line
 * Error: Child process terminated due to receipt of signal SIGINT
 * ❯ .test | grep "Danny" | pbcopy
 * ...executing 'myTest.js' and piping output...
 */
rl.spawnAsyncProcess = function (command, args, stdio, callback) {
  // Check arity.
  if (typeof stdio === 'function') {
    callback = stdio
    stdio = null
  }

  // Prevent printing prompt when executing child process, but continue processing input such as `^C` for `SIGINT` (which `rl.pause()` would prevent).
  this.paused = true

  // Launches a new process with `command` and the command line arguments in `args`. This child process avoids blocking the event loop. Unless `stdio` is provided as an argument, the child process ignores input and inherits `stdout` and `stderr`.
  var child = childProcess.spawn(command, args, {
    stdio: stdio || [ 'ignore', process.stdout, process.stderr ],
    // Run process inside in a shell to enable pipes (e.g., `test | pbcopy`), IO redirection (e.g., `test > file`), et cetera, inside `args`.
    // Define `shell` as `process.env.SHELL` (which uses `$SHELL`) instead of `true` (which uses `sh` on UNIX) to enable IO redirection (i.e., `<` and `>`) and globs (e.g., `ls *.js`), which are unavailable in `sh`, and logging shell history.
    shell: process.env.SHELL,
  })

  // Disable output from RLI while child is processing.
  var origStdoutWrite = this.output.write
  this.output.write = function () {}

  // Temporarily remove RLI `line` event listener(s) (when the user hits `enter`).
  var lineListeners = this.listeners('line')
  this.removeAllListeners('line')

  // Send `SIGINT` to child process when received by the RLI.
  function killChild() {
    child.kill('SIGINT')
  }

  // Temporarily replace existing RLI `SIGINT` event listener(s).
  var SIGINTListeners = this.listeners('SIGINT')
  this.removeAllListeners('SIGINT')
  this.on('SIGINT', killChild)

  child.on('error', function (err) {
    util.log()
    util.logError('Failed to start child process:', err.code)
  })

  var self = this

  // The 'exit' event is emitted when the child process ends.
  child.on('exit', function (code, signal) {
    // Restore `stdout`.
    self.output.write = origStdoutWrite

    // Restore `SIGINT` event listeners(s).
    self.removeListener('SIGINT', killChild)
    SIGINTListeners.forEach(function (listener) {
      self.on('SIGINT', listener)
    })

    if (signal) {
      // `child` was killed (most often is due to `SIGINT` sent by the RLI).
      util.log()
      util.logError('Child process terminated due to receipt of signal', util.colors.yellow(signal))
    } else if (code !== 0) {
      // `child` exited with a 'failure' code (most often after an exception is thrown).
      util.log()
      util.logError('Child process exited with code', code)
    } else if (callback) {
      // `child` exited normally. Execute `callback` before returning control to the RLI.
{'fraction_non_alphanumeric': 0.12576636288318144, 'fraction_numerical': 0.0021541010770505385, 'mean_word_length': 3.5482290881688017, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, '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': '1152012', 'n_tokens_mistral': 3666, 'n_tokens_neox': 3539, 'n_words': 1404}