基于gnu readline的节点shell

在内部使用gnu readline的节点是否有shell?

正如你所知道的节点壳吸盘有两种方式(除其他外):它没有search历史。 这可以通过使用像https://github.com/danielgtaylor/nesh这样的事情来解决。 使用gnu readline的shell(比如psql,ipython,python,bash等)具有很多开箱即用的function,并且全部共享您在〜/ .inputrc中设置的configuration。 例如我在上面列出的所有shell中都有很好的vim模式,因为它们都在内部使用gnu readline。 如果有一个js的shell在内部也使用gnu readline,那么它会和我的其他shell一起使用。

那个人是对的: rlwrap会工作。 不幸的是,它抛弃了node自己的完成。 如何避免这是一个常见问题 ,所以下面的方法来恢复完成: 不是通过提供一个选项卡封装的命令,然后以某种方式parsing结果混乱,但使用filter。

filter是充当rlwrap插件的小脚本。 可以重新编写用户input,命令输出,提示,历史和完成单词列表。 它们可以用perl或者python编写,并且可以在stream水线中进行组合。

filter可以做更多的技巧:与用户背后的包装命令交互( cloak_and_dagger()方法)

因此,如果我们教node一个新的命令rlwrap_complete(prefix) ,打印完成的prefix列表,我们可以使用cloak_and_dagger("rlwrap_complete($prefix)")来获得所有可能的完成,并使用rlwrap自己的完成者。

下面是在perlnode编写的filter,但不同命令的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() 。 由于node 不使用像.noderc这样的初始化文件,我们必须创build一个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)}}); } 

将filter代码移到$RLWRAP_FILTERDIR/node_complete ,将上面的代码保存为myrepl.js并使其可执行。 然后打电话:

 $ rlwrap -z node_complete ./myrepl.js 

…享受可search历史 TAB完成的REPL! 任何时候你按Tabrlwrap将有一个(不可见的)与node聊天来提出正确的完成。

其他rlwrap好东西(彩色提示, vi模式,额外的filter)可以添加,如果你想要他们。

当然,任何REPL都需要能够进行一些元编程来访问自己的名称空间作为数据,然后才能使用与node相同的解决scheme

rlwrap会让你使用readline来执行任意程序。

如果程序没有(或者确信不要)使用自己的行编辑,那么效果最好。 特别是对于node ,您可以使用:

 NODE_NO_READLINE=1 rlwrap node