有没有办法使用 "enquirer" npm 来处理标准输入?
Is there a way to handle standard input using "enquirer" npm?
计划概览
我一直在编写一个程序来帮助其用户记住圆周率的数字。
遇到的问题
该程序包含以下由 enquirer npm 提供的提示。
>>>>>>>>>> PI GAME <<<<<<<<<<
? Select your mode: …
❯ PRACTICE MODE
SHOW PI DIGITS
HIGH SCORES
我想在 selection 模式后接收标准输入,但程序没有等待就退出了。
预测原因
如果您跳过 enquirer 提供的模式 select 并直接启动该模式,程序将按预期接受标准输入。
因此,原因似乎是与标准输入相关的进程正在执行,而与它相关的某些状态已被询问者从初始状态更改。
我需要知道的
有什么方法可以将查询者所做的更改重置为初始状态并进入selected模式吗?
如果这很难,我想知道在 select 模式后是否有办法正确处理标准输入。
非常感谢你。
代码
#!/usr/bin/env node
'use strict'
{
const { Select } = require('enquirer')
const chalk = require('chalk')
const PI_START_TEXT = '3.'
const PI_BELOW_THE_DECIMAL_POINT = '1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679'
class PracticeMode {
start () {
const instruction = 'Keep typing in the number which fits the cursor position.'
// This program stops after executing the next line.
process.stdout.write(chalk.bold.green(instruction) + '\n\n' + PI_START_TEXT)
const readline = require('readline');
readline.emitKeypressEvents(process.stdin)
process.stdin.setRawMode(true);
let currentIndex = 0
process.stdin.on('keypress', (char, key) => {
if (key.ctrl && key.name === 'c') {
process.exit();
} else if (currentIndex === 100) {
this.putsCongratulations()
process.exit();
} else if (char === PI_BELOW_THE_DECIMAL_POINT[currentIndex]) {
process.stdout.write(char)
currentIndex++
} else {
const scoreMessage = `Your score: ${currentIndex}`
const remaining_digits_text = this.make_remaining_digits_text(currentIndex)
console.log(chalk.red(remaining_digits_text) + '\n' + scoreMessage)
process.exit();
}
})
}
putsCongratulations () {
const headSpaces = ' '.repeat(6)
const congratulationsSentences = [
'Congratulations!',
'You have memorized the first 100 digits of pi.'
]
let congratulations = ''
congratulationsSentences.forEach(sentence => {
congratulations += headSpaces + sentence + '\n'
})
console.log(chalk.bold.green(congratulations))
}
make_remaining_digits_text (currentIndex) {
let remaining_digits_text = ''
const digitsNum = 100
const sectionDigitsNum = 10
const lineDigitsNum = 50
for (let i = currentIndex; i < digitsNum; i++) {
if (i === lineDigitsNum) {
remaining_digits_text += '\n' + ' '.repeat(PI_START_TEXT.length)
} else if (i % sectionDigitsNum === 0) {
remaining_digits_text += ' '
}
remaining_digits_text += PI_BELOW_THE_DECIMAL_POINT[i]
}
return remaining_digits_text
}
}
class Game {
constructor () {
this.practiceMode = 'PRACTICE MODE'
this.showPiDigits = 'SHOW PI DIGITS'
this.highScores = 'HIGH SCORES'
}
start () {
const modes = [
{ name: this.practiceMode, explanation: 'Check how many digits of pi you can name from the point you designated.' },
{ name: this.showPiDigits, explanation: 'Check the first 100 digits of pi.' },
{ name: this.highScores, explanation: 'Check the high scores.' }
]
const prompt = new Select({
name: 'mode',
message: 'Select your mode:',
choices: modes.map(mode => mode.name),
footer () {
const explanations = modes.map(mode => ' '.repeat(2) + mode.explanation)
return chalk.green('\n' + explanations[this.index])
}
})
prompt.run()
.then(answer => {
switch (answer) {
case this.practiceMode:
// I have the problem here.
new PracticeMode().start()
break;
case this.showPiDigits:
break;
case this.highScores:
break;
}
})
}
}
function main () {
const welcomeMessage = '>'.repeat(10) + ' PI GAME ' + '<'.repeat(10)
console.log(chalk.bold.green(welcomeMessage))
// This doesn't work as intended.
new Game().start()
// If you run the next line instead, it works as intended.
// new PracticeMode().start()
}
main()
}
插入一行如下:
let currentIndex = 0
process.stdin.resume()
process.stdin.on('keypress', (char, key) => {
计划概览
我一直在编写一个程序来帮助其用户记住圆周率的数字。
遇到的问题
该程序包含以下由 enquirer npm 提供的提示。
>>>>>>>>>> PI GAME <<<<<<<<<<
? Select your mode: …
❯ PRACTICE MODE
SHOW PI DIGITS
HIGH SCORES
我想在 selection 模式后接收标准输入,但程序没有等待就退出了。
预测原因
如果您跳过 enquirer 提供的模式 select 并直接启动该模式,程序将按预期接受标准输入。 因此,原因似乎是与标准输入相关的进程正在执行,而与它相关的某些状态已被询问者从初始状态更改。
我需要知道的
有什么方法可以将查询者所做的更改重置为初始状态并进入selected模式吗? 如果这很难,我想知道在 select 模式后是否有办法正确处理标准输入。 非常感谢你。
代码
#!/usr/bin/env node
'use strict'
{
const { Select } = require('enquirer')
const chalk = require('chalk')
const PI_START_TEXT = '3.'
const PI_BELOW_THE_DECIMAL_POINT = '1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679'
class PracticeMode {
start () {
const instruction = 'Keep typing in the number which fits the cursor position.'
// This program stops after executing the next line.
process.stdout.write(chalk.bold.green(instruction) + '\n\n' + PI_START_TEXT)
const readline = require('readline');
readline.emitKeypressEvents(process.stdin)
process.stdin.setRawMode(true);
let currentIndex = 0
process.stdin.on('keypress', (char, key) => {
if (key.ctrl && key.name === 'c') {
process.exit();
} else if (currentIndex === 100) {
this.putsCongratulations()
process.exit();
} else if (char === PI_BELOW_THE_DECIMAL_POINT[currentIndex]) {
process.stdout.write(char)
currentIndex++
} else {
const scoreMessage = `Your score: ${currentIndex}`
const remaining_digits_text = this.make_remaining_digits_text(currentIndex)
console.log(chalk.red(remaining_digits_text) + '\n' + scoreMessage)
process.exit();
}
})
}
putsCongratulations () {
const headSpaces = ' '.repeat(6)
const congratulationsSentences = [
'Congratulations!',
'You have memorized the first 100 digits of pi.'
]
let congratulations = ''
congratulationsSentences.forEach(sentence => {
congratulations += headSpaces + sentence + '\n'
})
console.log(chalk.bold.green(congratulations))
}
make_remaining_digits_text (currentIndex) {
let remaining_digits_text = ''
const digitsNum = 100
const sectionDigitsNum = 10
const lineDigitsNum = 50
for (let i = currentIndex; i < digitsNum; i++) {
if (i === lineDigitsNum) {
remaining_digits_text += '\n' + ' '.repeat(PI_START_TEXT.length)
} else if (i % sectionDigitsNum === 0) {
remaining_digits_text += ' '
}
remaining_digits_text += PI_BELOW_THE_DECIMAL_POINT[i]
}
return remaining_digits_text
}
}
class Game {
constructor () {
this.practiceMode = 'PRACTICE MODE'
this.showPiDigits = 'SHOW PI DIGITS'
this.highScores = 'HIGH SCORES'
}
start () {
const modes = [
{ name: this.practiceMode, explanation: 'Check how many digits of pi you can name from the point you designated.' },
{ name: this.showPiDigits, explanation: 'Check the first 100 digits of pi.' },
{ name: this.highScores, explanation: 'Check the high scores.' }
]
const prompt = new Select({
name: 'mode',
message: 'Select your mode:',
choices: modes.map(mode => mode.name),
footer () {
const explanations = modes.map(mode => ' '.repeat(2) + mode.explanation)
return chalk.green('\n' + explanations[this.index])
}
})
prompt.run()
.then(answer => {
switch (answer) {
case this.practiceMode:
// I have the problem here.
new PracticeMode().start()
break;
case this.showPiDigits:
break;
case this.highScores:
break;
}
})
}
}
function main () {
const welcomeMessage = '>'.repeat(10) + ' PI GAME ' + '<'.repeat(10)
console.log(chalk.bold.green(welcomeMessage))
// This doesn't work as intended.
new Game().start()
// If you run the next line instead, it works as intended.
// new PracticeMode().start()
}
main()
}
插入一行如下:
let currentIndex = 0
process.stdin.resume()
process.stdin.on('keypress', (char, key) => {