All files / lib index.js

98.63% Statements 144/146
73.81% Branches 31/42
100% Functions 0/0
98.63% Lines 144/146

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 1461x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x     4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 2x 2x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 1x 1x 2x 2x 2x 2x 2x 2x 2x 3x 3x 2x 2x 2x 2x 2x 1x 1x 1x 1x
const debug = require('debug')('tabtab');
const prompt = require('./prompt');
const installer = require('./installer');
const tabtabDebug = require('./utils/tabtabDebug');
 
// If TABTAB_DEBUG env is set, make it so that debug statements are also log to
// TABTAB_DEBUG file provided.
tabtabDebug();
 
const tabtab = () => 'tabtab';
 
/**
 * Utility to figure out the shell used on the system.
 *
 * Sadly, we can't use `echo $0` in node, maybe with more work. So we rely on process.env.SHELL.
 *
 * TODO: More work on this, namely to detect Git bash on Windows (bash.exe)
 */
tabtab.shell = (env = process.env) => {
  const shell = (env.SHELL || '').split('/').slice(-1)[0];
  return shell;
};
 
/**
 * Install and enable completion on user system. It'll ask for:
 *
 * - SHELL (bash, zsh or fish)
 * - Path to shell script (with sensible defaults)
 *
 * @param {Object} Options to use with namely `name` and `completer`
 *
 */
tabtab.install = (options = { name: '', completer: '' }) => {
  const { name, completer } = options;
  if (!name) throw new TypeError('options.name is required');
  if (!completer) throw new TypeError('options.completer is required');
 
  return prompt().then(({ location }) =>
    installer.install({
      name,
      completer,
      location
    })
  );
};
 
/**
 * Public: Main utility to extract information from command line arguments and
 * Environment variables, namely COMP args in "plumbing" mode.
 *
 * options -  The options hash as parsed by minimist, plus an env property
 *            representing user environment (default: { env: process.env })
 *    :_      - The arguments Array parsed by minimist (positional arguments)
 *    :env    - The environment Object that holds COMP args (default: process.env)
 *
 * Examples
 *
 *   var env = tabtab.parseEnv();
 *   // env:
 *   // complete    A Boolean indicating whether we act in "plumbing mode" or not
 *   // words       The Number of words in the completed line
 *   // point       A Number indicating cursor position
 *   // line        The String input line
 *   // partial     The String part of line preceding cursor position
 *   // last        The last String word of the line
 *   // lastPartial The last word String of partial
 *   // prev        The String word preceding last
 *
 * Returns the data env object.
 */
tabtab.parseEnv = (env) => {
  if (!env) {
    throw new Error('parseEnv: You must pass in an environment object.');
  }
 
  debug('Parsing env. CWORD: %s, COMP_POINT: %s, COMP_LINE: %s', env.COMP_CWORD, env.COMP_POINT, env.COMP_LINE);
 
  let cword = Number(env.COMP_CWORD);
  let point = Number(env.COMP_POINT);
  const line = env.COMP_LINE || '';
 
  if (Number.isNaN(cword)) cword = 0;
  if (Number.isNaN(point)) point = 0;
 
  const partial = line.slice(0, point);
 
  const parts = line.split(' ');
  const prev = parts.slice(0, -1).slice(-1)[0];
 
  const last = parts.slice(-1).join('');
  const lastPartial = partial
    .split(' ')
    .slice(-1)
    .join('');
 
  let complete = true;
  if (!env.COMP_CWORD || !env.COMP_POINT || !env.COMP_LINE) {
    complete = false;
  }
 
  return {
    complete,
    words: cword,
    point,
    line,
    partial,
    last,
    lastPartial,
    prev
  };
};
 
/**
 * Main logging utility to pass completion items.
 *
 * This is simply an helper to log to stdout with each item separated by a new
 * line.
 *
 * Bash needs in addition to filter out the args for the completion to work
 * (zsh, fish don't need this).
 *
 * @param {Array} Arguments to log
 * @param {Object} Optional environment object as parsed by tabtab
 */
tabtab.log = (args, env) => {
  if (!env) {
    env = tabtab.parseEnv(process.env);
  }
 
  const shell = tabtab.shell();
  if (shell === 'bash') {
    args = args.filter(arg => arg.indexOf(env.last) === 0);
  }
 
  for (const arg of args) {
    console.log(`\n${arg}`);
  }
 
  return {
    args,
    env
  };
};
 
module.exports = tabtab;