5

我正在编写一个简单的 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:                 _

此时退格无效。

4

3 回答 3

4

当您在rl.setPrompt(prompt, length)没有第二个参数的情况下调用时,内部_promptLength变量将设置为提示字符串的长度解释ANSI X3.64 转义序列。内部方法从][3]_getCursorPos计算光标位置;_promptLength因此,在长度中包含转义序列会导致光标的位置比应有的位置更远。

为了完全解决这个问题,Node 的 readline 库应该在设置_promptLength. 要解决此问题,您可以手动计算不带转义序列的提示字符串的长度,并将其作为第二个参数传递给rl.setPrompt(prompt, length).

于 2012-08-30T08:21:31.417 回答
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直接修改(并全局应用您的修复)而不是对象实例本身。这里有很多选择。

希望这对某人有帮助!

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

于 2013-10-28T04:05:29.537 回答
0

当然,您需要rl.write使用 CSI 序列修改您的字符串,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');

注意最后一行中的11and the吗?代表要向后移动的字符数D。那么显然是字符数。D11

查看所有有趣的终端代码:http ://en.wikipedia.org/wiki/ANSI_escape_code

于 2012-08-22T15:25:51.943 回答