dthree / vorpal

Node's framework for interactive CLIs
http://vorpal.js.org
MIT License
5.64k stars 280 forks source link

expose rawParse to use minimist/commander #5

Closed Downchuck closed 9 years ago

Downchuck commented 9 years ago

Vorpal could expose rawParse(process.argv, { command: true|false}) to run a string through minimist or commander. This may be a special case.

I have an existing app, it's just using minimist for cli arguments in the usual form (app.js --arg items), and I'm working on the interactive CLI via vorpal. Trying to reduce redundancy when I can.

I am still working out how best to switch between command line (single commands) and interactive command line. But that's a different issue.

dthree commented 9 years ago

You mean in addition to vorpal.parse? I suppose I could literally map it to minimist if that helps.

Downchuck commented 9 years ago

That's the idea, you'd map to minimist by default, with an optional second argument that'd run commander.js parse -- which would use your vorpal command list to return an object. Both are meant to be maps over to minimist/commander just in case it's needed.

Related to using this: on vorpal.parse -- how do I detect whether or not a command was found? Is there a default callback, like parse(argv, notFoundFn)?

dthree commented 9 years ago

It is meant to do exactly what you app does if you run it first. So it would technically display the help command.

Check out the .catch command (it's new, maybe I didn't document it yet): here's an example I pulled out of wat, which im working on:


  vorpal
    .catch('[commands...]')
    .option('-d, --detail', 'View detailed markdown on item.')
    .option('-i, --install', 'View installation instructions.')
    .autocompletion(function (text, iteration, cb) {
      const self = this;
      const index = parent.clerk.indexer.index();
      let result = util.autocomplete(text, iteration, index, function (word, options) {
        const res = self.match(word, options);
        return res;
      });
      if (_.isArray(result)) {
        result.sort();
      }
      cb(undefined, result);
    })
    .action(function (args, cb) {
      const self = this;

      args = args || {};
      args.options = args.options || {};

      // Handle humans.
      if (String(args.commands[0]).toLowerCase() === 'wat') {
        args.commands.shift();
      }

       // ...

      cb();
    });

Catch basically is called if you don't match on any other command, so it overrides help as the default function if no command is met. By adding in a [variadicArg...], you can pretty much do anything you want.

dthree commented 9 years ago

On the parse, I think im gonna do this:

var args = vorpal.parse(process.argv, { use: 'minimist' });
var args = vorpal.parse(process.argv, { use: 'commander' });
Downchuck commented 9 years ago

I like it.

dthree commented 9 years ago

:)

Does the catch thing make sense?

Downchuck commented 9 years ago

Yes, it makes sense, does just what I want.

dthree commented 9 years ago

Perfect.

dthree commented 9 years ago

@Downchuck Added this. Coming out in a release today.