1 var util = require('util')
2 var EventEmitter = require('events').EventEmitter
4 var StateMachine = function (rli, colors) {
9 var currentOptionsPointer
13 EventEmitter.call(this)
15 var showPrompt = function () {
16 rli.write(colors.ANSWER)
20 this.onKeypress = function (key) {
21 if (!currentOptions || !key) {
25 if (key.name === 'tab' || key.name === 'right' || key.name === 'down') {
26 this.suggestNextOption()
27 } else if (key.name === 'left' || key.name === 'up') {
28 currentOptionsPointer = currentOptionsPointer + currentOptions.length - 2
29 this.suggestNextOption()
32 if (!key.ctrl && !key.meta && key.name !== 'enter' && key.name !== 'return') {
37 this.suggestNextOption = function () {
38 if (!currentOptions) {
42 currentOptionsPointer = (currentOptionsPointer + 1) % currentOptions.length
44 rli._deleteLineRight()
45 rli.write(currentOptions[currentOptionsPointer])
48 this.kill = function () {
50 currentQuestionId = null
51 rli.write('\n' + colors.RESET + '\n')
55 this.onLine = function (line) {
56 if (currentQuestionId) {
57 rli.write(colors.RESET)
58 line = line.trim().replace(colors.ANSWER, '').replace(colors.RESET, '')
61 currentOptionsPointer = currentOptions.indexOf(line)
62 if (currentOptionsPointer === -1) {
71 if (currentQuestion.boolean) {
72 line = (line === 'yes' || line === 'true' || line === 'on')
75 if (line !== null && currentQuestion.validate) {
76 currentQuestion.validate(line)
79 if (currentQuestion.multiple) {
80 answers[currentQuestionId] = answers[currentQuestionId] || []
82 answers[currentQuestionId].push(line)
86 currentOptions.splice(currentOptionsPointer, 1)
87 currentOptionsPointer = -1
93 answers[currentQuestionId] = line
99 this.nextQuestion = function () {
100 currentQuestion = questions.shift()
102 while (currentQuestion && currentQuestion.condition && !currentQuestion.condition(answers)) {
103 currentQuestion = questions.shift()
106 this.emit('next_question', currentQuestion)
108 if (currentQuestion) {
109 currentQuestionId = null
111 rli.write('\n' + colors.question(currentQuestion.question) + '\n')
112 rli.write(currentQuestion.hint + '\n')
115 currentOptions = currentQuestion.options || null
116 currentOptionsPointer = -1
117 currentQuestionId = currentQuestion.id
119 this.suggestNextOption()
121 currentQuestionId = null
122 currentOptions = null
130 this.process = function (_questions, _done) {
131 questions = _questions
139 util.inherits(StateMachine, EventEmitter)
141 module.exports = StateMachine