1var fs = require('fs'),
2  path = require('path')
3
4// add bash completions to your
5//  yargs-powered applications.
6module.exports = function (yargs, usage) {
7  var self = {
8    completionKey: 'get-yargs-completions'
9  }
10
11  // get a list of completion commands.
12  self.getCompletion = function (done) {
13    var completions = [],
14    current = process.argv[process.argv.length - 1],
15    previous = process.argv.slice(process.argv.indexOf('--' + self.completionKey) + 1),
16    argv = yargs.parse(previous)
17
18    // a custom completion function can be provided
19    // to completion().
20    if (completionFunction) {
21      if (completionFunction.length < 3) {
22        // synchronous completion function.
23        return done(completionFunction(current, argv))
24      } else {
25        // asynchronous completion function
26        return completionFunction(current, argv, function (completions) {
27          done(completions)
28        })
29      }
30    }
31
32    if (!current.match(/^-/)) {
33      usage.getCommands().forEach(function (command) {
34        completions.push(command[0])
35      })
36    }
37
38    if (current.match(/^-/)) {
39      Object.keys(yargs.getOptions().key).forEach(function (key) {
40        completions.push('--' + key)
41      })
42    }
43
44    done(completions)
45  }
46
47  // generate the completion script to add to your .bashrc.
48  self.generateCompletionScript = function ($0) {
49    var script = fs.readFileSync(
50      path.resolve(__dirname, '../completion.sh.hbs'),
51      'utf-8'
52    ),
53    name = path.basename($0)
54
55    // add ./to applications not yet installed as bin.
56    if ($0.match(/\.js$/)) $0 = './' + $0
57
58    script = script.replace(/{{app_name}}/g, name)
59    return script.replace(/{{app_path}}/g, $0)
60  }
61
62  // register a function to perform your own custom
63  // completions., this function can be either
64  // synchrnous or asynchronous.
65  var completionFunction = null
66  self.registerFunction = function (fn) {
67    completionFunction = fn
68  }
69
70  return self
71}
72