在 Node 中使用 readline 提示/setPrompt 时无法清除行

Unable to clear line when using readline prompt / setPrompt in Node

我在使用 readline prompt 时无法清除 stdout 中的一行。

我的代码与此类似:

import readline from 'readline'

const rl = readline.createInterface(process.stdin, process.stdout)
let input = ''

readline.emitKeypressEvents(process.stdin)
process.stdin.on('keypress', registerInput)

function registerInput (str, key) {
  if (key.name === 'backspace') {
    input = input.slice(0, input.length - 1)
  } else {
    input += str
  }
  if (input === '42') {
    input = ''
    console.log(' ✓')
    nextPrompt()
  }
}

function nextPrompt () {
  readline.clearLine(process.stdout, 0)
  rl.setPrompt('What is the meaning of life? ')
  rl.prompt()
}

nextPrompt()

在真正的代码中,生成了算术题。

Here is a screen capture of the output.

会发生什么

光标重置(使用 .prompt(false) 将光标保持在原位),但输入仍然存在于新提示中。

预计

输入42不应出现在下一行的新提示中。

为什么我使用 .on('keypress' 而不是 rl.on('line'?我希望游戏中的响应迅速,避免按 enter.

我尝试过的:

环境

我正在使用 node v6.0.0 和 babel-cli v6.7.7(这里的 babel 只是用于导入语句,但在实际代码中,如果你没有安装 babel,我会使用 object-rest-spread and therefor need babel). Here is a gist of the generated code

问题

rl.promptreadline.clearLine 不兼容吗?如何解决?

我是这样解决的:

import readline from 'readline'

let input = ''
let question = 'What is the meaning of life? '

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
})
readline.emitKeypressEvents(process.stdin)
process.stdin.on('keypress', registerInput)

function registerInput (str, key) {
  if (key.name === 'backspace') {
    input = input.slice(0, input.length - 1)
  } else {
    const numbers = '1 2 3 4 5 6 7 8 9 0'.split(' ')
    if (numbers.indexOf(str) !== -1) {
      input += str
    }
  }
  if (input === '42') {
    console.log(' ✓')
    input = ''
  }
  render(question, input)
}

function render (question, input) {
  readline.clearLine(process.stdout, 0)
  readline.cursorTo(process.stdout, 0)
  process.stdout.write(question + input)
}

render(question, input)

但问题仍然存在,为什么 rl.promptreadline.clearLine 不兼容?

我猜 prompt 在幕后做了一些类似于我的方法。 resetPromptInput 就好了。