dthree / vorpal

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

Conflicting contexts between `mode.init` and `mode.action` #99

Closed mvayngrib closed 8 years ago

mvayngrib commented 8 years ago

for discussion, not a demand :)

dthree commented 8 years ago

kk. Event is easy!

On state, we just need to nail a proposed API, or decide that this isn't necessary as an API feature.

For instance, you could always use this.parent.myRandomVariable, and that would last the duration of a Vorpal session. In an action, this is the commandInstance, which lasts for that command. this.parent is the user's session object. So something like this could work:


.action(function () {
  this.parent.state = this.parent.state || {};
  const state = this.parent.state;
  state.foo = 'bar';
});
mvayngrib commented 8 years ago

right, event i assume can just be emitted in _exitMode

i was actually trying to use this, but somehow in init and action, this was different even though both were a CommandInstance

dthree commented 8 years ago

I agree


Oh, well that's just a bug if those two aren't the same. Can you please check and see if init is running under the session context? i.e. this.foo === this.parent.foo

mvayngrib commented 8 years ago

i've been trying to write a test for it, but i'm not sure how to trigger an action within a mode:

  describe('mode context', function () {
    it('should have the same context in init and action', function () {
      var vorpal = Vorpal()
      var initCtx
      vorpal
        .mode('ooga')
        .init(function (args, cb) {
          initCtx = this
        })
        .action(function (args, cb) {
          this.should.equal(initCtx)
        })

      // enter mode
      vorpal
        .exec('ooga')

      // how to trigger action?
    })
  })
dthree commented 8 years ago

Check out the Vorpal UI library - these commands should do the trick:

https://github.com/dthree/vorpal/wiki/api-|-vorpal.ui#uisubmittext

mvayngrib commented 8 years ago

ended up using exec after all :) see #103

dthree commented 8 years ago

Okay dug into this.


Both contexts are using a commandInstance context, however a commandInstance nature expires after execution by nature, so it wouldn't be correct for them to have the same context (and wouldn't work in the current design).

For a common context that lasts the duration of the mode session, use this.parent in both contexts, which refers to your session.