Javascript 向终端提示添加颜色会导致较大的空白
我正在编写一个简单的cli脚本,希望为以下代码添加一些颜色:Javascript 向终端提示添加颜色会导致较大的空白,javascript,node.js,command-line-interface,ansi,readline,Javascript,Node.js,Command Line Interface,Ansi,Readline,我正在编写一个简单的cli脚本,希望为以下代码添加一些颜色: rl.question('Enter destination path: ', function(answer) { // ... });
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_
它可以工作,但有大量的空白,我更希望没有。有人对如何处理这件事有什么想法吗
编辑:
我不能通过退格删除空白。。。当我尝试使用backspace键时,空白会像这样跳到另一端
Enter destination path: /home/jmcateer/bin_
Enter destination path: /home/jmcateer/bi _
Enter destination path: /home/jmcateer/b _
...
Enter destination path: _
此时退格无效。当然,您需要修改
rl。使用CSI序列nd
写入字符串,其中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显然是字符数
查看所有有趣的终端代码:当您调用rl.setPrompt(prompt,length)
而不使用第二个参数时;不解释ANSI X3.64转义序列。内部\u getCursorPos
方法从\u promplength
][3]计算光标位置;因此,在长度中包含转义序列会导致光标的位置超出其应有的距离
要完全解决此问题,在设置\u promplength
时,节点的readline库应该解析ANSI转义序列。为了解决这个问题,您可以在不使用转义序列的情况下手动计算提示字符串的长度,并将其作为第二个参数传递给rl。setPrompt(prompt,length)
我也遇到了类似的问题。巴兹尔·克罗(Basil Crow)对问题原因的出色回答是正确的,因为确实是ANSI转义序列导致了长度故障;然而,Interface.setPrompt()
不仅仅是问题,而是解决方案
似乎这种对长度的误读(我在bash中玩时巧妙地避免了这一点)会影响整个接口对象的写出过程,即当未指定长度参数时,任何以任何容量调用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 + '".');
});
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);
});
重新定义Interface.write()
以使用Interface.setPrompt()
将写出字符串和字符串的真实长度传递给setPrompt方法:
// 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 + '".');
});
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
(并将您的修复程序全局应用),而不是对象实例本身。这里有很多选择
希望这对别人有帮助
编辑另请参见:No joy它没有效果,它似乎不是正常字符请参见我的编辑它似乎根本不影响setPrompt
问题。我将进行重构,以使用更详细的方法,并看看这是否有效。