dthree / vorpal

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

Multiple-Instances BUG #280

Open omidnavy opened 6 years ago

omidnavy commented 6 years ago

Hi Creating multiple instances using Vorpal() has issues in auto-generated help even when .show() is not called and .hide() has no effect on it. it will list all helps from those Vorpal's instances in multiple lines . eg: let main=new Vorpal(); let sys = new Vorpal(); sys.delimiter('sys'); sys.command('say [words...]').action((args,cb)=>{console.log(args.words)}); main.command('mode [modes]').action((args,cb)=>{ if(args.mode=='system'){ sys.show(); main.hide() //it doesn't really matter to be or not , or before sys.show() or after ! }; cb(); }); main.delimiter('main').show()

When pressing [tab tab] it will show something like this quit help mode

quit help say

What should I do to fix this ? the "mode" is not complete enough to serve as an instance, the instance has this problem . Is there any way ? any trick ? am I doing this right at all ?

Best Regards

ORESoftware commented 6 years ago

yeah, this is not good. Just curious why you want multiple vorpal instances? Of course, it should with multiple instances

b4dnewz commented 6 years ago

@omidnavi I'm pretty sure you are supposed to call Vorpal constructor just once and than add commands and/or extensions to the created instance, take a look at cash code which has many subcommands tied to the "root" vorpal instance.

SilverDragon135 commented 6 years ago

I found more issues, so I´m not sure, if it is solved in the code, but this is how I work with multiple instances:

const vorpal= require('vorpal')();

var child_app = null;

vorpal
    .version('0.0.1')
    .history('history')

vorpal
    .command('app1')
    .description('switches to app1')
    .action(function(targets, cb){
        var app1_controller = new ('./cmds/app1')(/*... other arguments to pass to child vorpal ...*/ cb);
        child_app = require('vorpal')().delimiter(`${this.delimiter()}app1 >`);
        child_app.use(child_app.vorpal).show();
    });

vorpal
    .command('app2')
    .description('switches to app2')
    .action(function(targets, cb){
        var app2_controller = new ('./cmds/app2')(/*... other arguments to pass to child vorpal ...*/ cb);
        child_app = require('vorpal')().delimiter(`${this.delimiter()}app2 >`);
        child_app.use(child_app.vorpal).show();
    });

vorpal.delimiter('root~$').show();

and sample app_controller:

function app1_controller(/*... other arguments to pass to child vorpal ...*/ parent_vorpal_callback) {
    this.vorpal = function(vorpal, options){       

        vorpal
            .command("app1_command [option1]")
            .description("app1 command.")
            .action(function(args,cb){
                cb();
            });

        /* overwrite child app exit function */
        vorpal
            .find("exit")
            .action(function(args,cb){
                //vorpal.exec("exit"); // this works, but not sure if it really exits child app istance
                if (parent_vorpal_callback) parent_vorpal_callback();
            });

    }
}

module.exports = app1_controller;

I think this is simpler than solution in issue #247 .