that other guy 是对的:rlwrap 会起作用。不幸的是,它扔掉了
nodes 自己完成。如何避免这种情况是FAQ,所以这里遵循一种恢复完成的方法:not 通过将 TAB 提供给包装的命令,然后
以某种方式解析产生的混乱,但使用过滤器。
Filters 是小脚本,充当
rlwrap 插件。可以重写用户输入、命令输出、提示、历史和完成单词列表。
它们可以写成perl 或python 并组合成一个管道。
过滤器还可以做一件事:与用户背后的包装命令进行交互(cloak_and_dagger() 方法)
因此,如果我们教 node 一个新命令 rlwrap_complete(prefix) 打印 prefix 的完成列表,我们可以使用
cloak_and_dagger("rlwrap_complete($prefix)") 获取所有可能的完成,并将其用于 rlwraps 自己的完成。
这是为perl 编写的node 的过滤器,但不同命令的python 版本看起来非常相似:
#!/usr/bin/env perl
use lib ($ENV{RLWRAP_FILTERDIR} or ".");
use RlwrapFilter;
use strict;
my $filter = new RlwrapFilter;
$filter -> completion_handler( sub {
my($line, $prefix, @completions) = @_;
my $command = "rlwrap_complete('$prefix')";
my $completion_list = $filter -> cloak_and_dagger($command, "> ", 0.1); # read until we see a new prompt "> "
my @new_completions = grep /^$prefix/, split /\r\n/, $completion_list; # split on CRNL and weed out rubbish
return (@completions, @new_completions);
});
$filter -> run;
现在我们必须教node 命令rlwrap_complete()。作为nodedoesn't use an init file like .noderc,我们必须
创建一个 REPL 实例并扩展它:
#!/usr/bin/env node
// terminal:false disables readline (just like env NODE_NO_READLINE=1):
var myrepl = require("repl").start({terminal:false});
// add REPL command rlwrap_complete(prefix) that prints a simple list of completions of prefix
myrepl.context['rlwrap_complete'] = function(prefix) {
myrepl.complete(prefix, function(err,data) { for (x of data[0]) {console.log(x)}});
}
将过滤器代码移动到$RLWRAP_FILTERDIR/node_complete,将上述代码另存为myrepl.js并使其可执行。然后调用:
$ rlwrap -z node_complete ./myrepl.js
...享受具有可搜索历史的 REPL 和 TAB 完成!任何时候您按 TAB rlwrap 都会与 node 进行(不可见的)聊天以提出正确的完成。
如果需要,可以添加其他 rlwrap 好东西(彩色提示、vi 模式、其他过滤器)。
当然,在我们可以使用与node 相同的解决方案之前,任何 REPL 都需要能够进行一些元编程来访问其自己的命名空间作为数据。