给terminal提示添加颜色会导致大的空白区域

我正在处理一个简单的cli脚本,并想添加一些颜色到下面的代码:

rl.question('Enter destination path: ', function(answer) { // ... }); rl.write('/home/' + user + '/bin'); 

在terminal显示:

 Enter destination path: /home/jmcateer/bin_ 

但我想添加一些颜色的提示我做了以下几点:

 rl.question('\u001b[1;36mEnter destination path:\u001b[0m ', function(answer) { }); rl.write('/home/' + user + '/bin'); 

命令行提示结束显示:

 Enter destination path: /home/jmcateer/bin_ 

它的工作原理,但是我不希望有大量的空白空间。 有没有人有任何想法如何处理这个?

编辑:

我不能通过退格来删除白色空间…当我尝试使用退格键时,白色空间像这样跳到另一端

 Enter destination path: /home/jmcateer/bin_ Enter destination path: /home/jmcateer/bi _ Enter destination path: /home/jmcateer/b _ ... Enter destination path: _ 

此时退格不起作用。

Solutions Collecting From Web of "给terminal提示添加颜色会导致大的空白区域"

当你调用没有第二个参数的rl.setPrompt(prompt, length) , 内部_promptLengthvariables被设置为提示string的长度 ; ANSI X3.64转义序列不被解释。 内部_getCursorPos方法从_promptLength [3]计算光标位置; 因此,在长度中包含转义序列导致光标被定位得比它应该更远。

要完全解决这个问题,当设置_promptLength时,Node的readline库应该parsingANSI转义序列。 要解决此问题,可以手动计算不带转义序列的提示string的长度,并将其作为第二个parameter passing给rl.setPrompt(prompt, length)

我也碰到类似的问题。 罗勒乌鸦是正确的,在他的问题的原因的确切答案是,它确实是造成长度故障的ANSI转义序列; 然而, Interface.setPrompt()不只是问题 – 这是解决scheme

看来这个长度的误读(我在bash中玩的时候巧妙地避免了这个) 会影响整个Interface对象的写出过程 ,也就是说,当没有指定长度参数时,任何以任何容量调用Interface.setPrompt()东西都会受到影响。

为了克服这个问题,你可以做两件事情之一:

重新定义Interface.setPrompt()总是为提示输出指定一个长度,以便类似于Interface.question()方法再次正常工作:

 // I'm using the 'color' npm library for the sake of convenience. It is not required // and you can use normal regex to strip color codes and what not. var colors = require('colors'), readline = require('readline'); var rl = readline.createInterface(process.stdin, process.stdout); /* Overcome some bugs in the Nodejs readline implementation */ rl._setPrompt = rl.setPrompt; rl.setPrompt = function(prompt, length) { rl._setPrompt(prompt, length ? length : prompt.split(/[\r\n]/).pop().stripColors.length); }; var str = '[' + '?'.green + '] Blackbeard walks under the black flag with a ____? '; rl.question(str, function(answer) { var answ = 'scallywag swagger'; console.log( 'You answered "' + ((answer == answ) ? answer.green : answer.red) + '". The correct answer is', '"' + answ.green + '".'); }); 

重新定义Interface.write()以使用Interface.setPrompt()将writeoutstring和string的真实长度传递给setPrompt方法:

 var colors = require('colors'), readline = require('readline'); var rl = readline.createInterface(process.stdin, process.stdout); /* Overcome some bugs in the Nodejs readline implementation */ rl._write = rl.write; rl.write = function(d, key) { // "key" functionality is lost, but if you care enough you can add it back rl.setPrompt(d, d.split(/[\r\n]/).pop().stripColors.length); rl.prompt(true); }; var str = '[' + '?'.green + '] Blackbeard walks under the black flag with a ____? '; rl.write(str); rl.on('line', function(answer) { var answ = 'scallywag swagger'; console.log( 'You answered "' + ((answer == answ) ? answer.green : answer.red) + '". The correct answer is', '"' + answ.green + '".'); rl.prompt(true); }); 

两者的结果是一样的: 输出上面的脚本

或者你可以做到这一点。 或者,您可以直接修改readline.Interface.prototype (并将修补程序全局应用),而不是对象实例本身。 这里有很多select。

希望这可以帮助别人!

编辑 – 另见: https : //github.com/joyent/node/issues/3860

当然,你需要用CSI序列n D来修改你的rl.writestring,其中n是将光标移回的字符数。

这里是一个片段,试验:

 var rl = require('readline').createInterface({input: process.stdin, output: process.stdout}); rl.question('\u001b[1;36mEnter destination path: \u001b[0m', function(answer) { }); rl.write('\u001b[11 D/home/jp/bin'); 

注意最后一行中的11DD代表返回的字符数。 11显然是字符的数量。

看到这个有趣的terminal代码: http : //en.wikipedia.org/wiki/ANSI_escape_code