completion.js 2.5 KB

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