基于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自己的完成者。
下面是在perl
为node
编写的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! 任何时候你按Tab键rlwrap
将有一个(不可见的)与node
聊天来提出正确的完成。
其他rlwrap
好东西(彩色提示, vi
模式,额外的filter)可以添加,如果你想要他们。
当然,任何REPL都需要能够进行一些元编程来访问自己的名称空间作为数据,然后才能使用与node
相同的解决scheme
rlwrap
会让你使用readline来执行任意程序。
如果程序没有(或者确信不要)使用自己的行编辑,那么效果最好。 特别是对于node
,您可以使用:
NODE_NO_READLINE=1 rlwrap node