completion.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Generated by CoffeeScript 1.6.3
  2. /**
  3. Most of the code adopted from the npm package shell completion code.
  4. See https://github.com/isaacs/npm/blob/master/lib/completion.js
  5. */
  6. var Q, complete, dumpScript, escape, getOpts, unescape;
  7. Q = require('q');
  8. escape = require('./shell').escape;
  9. unescape = require('./shell').unescape;
  10. module.exports = function() {
  11. return this.title('Shell completion').helpful().arg().name('raw').title('Completion words').arr().end().act(function(opts, args) {
  12. var argv, cmd, e, _ref;
  13. if (process.platform === 'win32') {
  14. e = new Error('shell completion not supported on windows');
  15. e.code = 'ENOTSUP';
  16. e.errno = require('constants').ENOTSUP;
  17. return this.reject(e);
  18. }
  19. if ((process.env.COMP_CWORD == null) || (process.env.COMP_LINE == null) || (process.env.COMP_POINT == null)) {
  20. return dumpScript(this._cmd._name);
  21. }
  22. console.error('COMP_LINE: %s', process.env.COMP_LINE);
  23. console.error('COMP_CWORD: %s', process.env.COMP_CWORD);
  24. console.error('COMP_POINT: %s', process.env.COMP_POINT);
  25. console.error('args: %j', args.raw);
  26. opts = getOpts(args.raw);
  27. _ref = this._cmd._parseCmd(opts.partialWords), cmd = _ref.cmd, argv = _ref.argv;
  28. return Q.when(complete(cmd, opts), function(compls) {
  29. console.error('filtered: %j', compls);
  30. return console.log(compls.map(escape).join('\n'));
  31. });
  32. });
  33. };
  34. dumpScript = function(name) {
  35. var defer, fs, path;
  36. fs = require('fs');
  37. path = require('path');
  38. defer = Q.defer();
  39. fs.readFile(path.resolve(__dirname, 'completion.sh'), 'utf8', function(err, d) {
  40. var onError;
  41. if (err) {
  42. return defer.reject(err);
  43. }
  44. d = d.replace(/{{cmd}}/g, path.basename(name)).replace(/^\#\!.*?\n/, '');
  45. onError = function(err) {
  46. if (err.errno === require('constants').EPIPE) {
  47. process.stdout.removeListener('error', onError);
  48. return defer.resolve();
  49. } else {
  50. return defer.reject(err);
  51. }
  52. };
  53. process.stdout.on('error', onError);
  54. return process.stdout.write(d, function() {
  55. return defer.resolve();
  56. });
  57. });
  58. return defer.promise;
  59. };
  60. getOpts = function(argv) {
  61. var i, line, partialLine, partialWord, partialWords, point, w, word, words;
  62. line = process.env.COMP_LINE;
  63. w = +process.env.COMP_CWORD;
  64. point = +process.env.COMP_POINT;
  65. words = argv.map(unescape);
  66. word = words[w];
  67. partialLine = line.substr(0, point);
  68. partialWords = words.slice(0, w);
  69. partialWord = argv[w] || '';
  70. i = partialWord.length;
  71. while (partialWord.substr(0, i) !== partialLine.substr(-1 * i) && i > 0) {
  72. i--;
  73. }
  74. partialWord = unescape(partialWord.substr(0, i));
  75. if (partialWord) {
  76. partialWords.push(partialWord);
  77. }
  78. return {
  79. line: line,
  80. w: w,
  81. point: point,
  82. words: words,
  83. word: word,
  84. partialLine: partialLine,
  85. partialWords: partialWords,
  86. partialWord: partialWord
  87. };
  88. };
  89. complete = function(cmd, opts) {
  90. var compls, m, o, opt, optPrefix, optWord;
  91. compls = [];
  92. if (opts.partialWord.indexOf('-')) {
  93. compls = Object.keys(cmd._cmdsByName);
  94. } else {
  95. if (m = opts.partialWord.match(/^(--\w[\w-_]*)=(.*)$/)) {
  96. optWord = m[1];
  97. optPrefix = optWord + '=';
  98. } else {
  99. compls = Object.keys(cmd._optsByKey);
  100. }
  101. }
  102. if (!(o = opts.partialWords[opts.w - 1]).indexOf('-')) {
  103. optWord = o;
  104. }
  105. if (optWord && (opt = cmd._optsByKey[optWord])) {
  106. if (!opt._flag && opt._comp) {
  107. compls = Q.join(compls, Q.when(opt._comp(opts), function(c, o) {
  108. return c.concat(o.map(function(v) {
  109. return (optPrefix || '') + v;
  110. }));
  111. }));
  112. }
  113. }
  114. if (cmd._comp) {
  115. compls = Q.join(compls, Q.when(cmd._comp(opts)), function(c, o) {
  116. return c.concat(o);
  117. });
  118. }
  119. return Q.when(compls, function(compls) {
  120. console.error('partialWord: %s', opts.partialWord);
  121. console.error('compls: %j', compls);
  122. return compls.filter(function(c) {
  123. return c.indexOf(opts.partialWord) === 0;
  124. });
  125. });
  126. };