我正在研究一个简单的cli脚本,并希望为以下代码添加一些颜色:
rl.question('Enter destination path: ', function(answer) {
// ...
});
rl.write('/home/' + user + '/bin');
终端中显示的内容:
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: _
此时退格无效。
答案 0 :(得分:4)
如果您在没有第二个参数的情况下致电rl.setPrompt(prompt, length)
,the internal _promptLength
variable is set to the length of the prompt string; ANSI X3.64转义序列不解释。内部_getCursorPos
方法从_promptLength
]计算光标位置[3];因此,在长度中包含转义序列会导致光标定位得比它应该的位置更远。
要完全解决此问题,Node的readline库应在设置_promptLength
时解析ANSI转义序列。要解决此问题,您可以手动计算不带转义序列的提示字符串的长度,并将其作为第二个参数传递给rl.setPrompt(prompt, length)
。
答案 1 :(得分:2)
我也遇到过类似的问题。 Basil Crow对于问题原因的出色答案是正确的,因为确实是ANSI转义序列导致长度故障;但是,Interface.setPrompt()
不仅仅是问题 - 它是解决方案!
似乎这种对长度的误读(我在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()
将写出字符串和字符串的真实长度传递给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
(并全局应用修复)而不是对象实例本身。这里有很多选择。
希望这有助于某人!
答案 2 :(得分:0)
当然,您需要使用CSI序列rl.write
修改n D
字符串,其中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');
请注意最后一行中的11
和D
? D
代表要移回的字符数。 11
显然是字符数。
查看所有有趣的终端代码:http://en.wikipedia.org/wiki/ANSI_escape_code