perl6 有没有办法进行可编辑的提示输入?
perl6 Is there a way to do editable prompt input?
在 bash shell 中,如果您点击向上或向下箭头,shell 将显示您输入的上一个或下一个命令,您可以编辑这些命令以是新的 shell 命令。
在 perl6 中,如果你这样做
my $name = prompt("Enter name: ");
它将打印"Enter name: "然后要求输入;有没有办法让 perl6 给你一个默认值,然后你只需将默认值编辑为新值。例如:
my $name = prompt("Your name:", "John Doe");
并打印
Your name: John Doe
其中 John Doe 部分是可编辑的,当您按下回车键时,编辑的字符串就是 $name 的值。
https://docs.raku.org/routine/prompt 没有说明如何去做。
如果您必须输入许多长字符串,而每个字符串与其他字符串只有几个字符不同,这将很有用。
谢谢。
要让编辑部分顺利进行,您可以使用 Linenoise 模块:
zef install Linenoise
(https://github.com/hoelzro/p6-linenoise)
然后,在您的代码中执行:
use Linenoise;
sub prompt($p) {
my $l = linenoise $p;
linenoiseHistoryAdd($l);
$l
}
然后你可以使用提示进行循环。请记住,基本上所有 Perl 6 内置函数都可以词法覆盖。现在,如何填写原始字符串,我还没有弄清楚。也许 libreadline 文档可以帮助您。
另一个解决方案:
使用io-prompt
有了它,您可以设置默认值甚至默认类型:
my $a = ask( "Life, the universe and everything?", 42, type => Num );
Life, the universe and everything? [42]
Int $a = 42
您可以安装它:
zef install IO::Prompt
但是,如果只是一个默认值是不够的。那么你最好使用Liz建议的方法。
默认情况下,程序完全不知道它们的终端。
您需要您的程序与终端通信以执行诸如预填充输入行之类的操作,期望 Perl 6 将此类操作作为核心语言的一部分来处理是不合理的。
就是说,只要您有一个兼容的终端,您的确切案例就由 Readline 库处理。
Perl 6 Readline 似乎没有预输入挂钩设置,因此很遗憾,您需要自己处理回调和读取循环。这是我粗略的尝试,完全符合您的要求:
use v6;
use Readline;
sub prompt-prefill($question, $suggestion) {
my $rl = Readline.new;
my $answer;
my sub line-handler( Str $line ) {
rl_callback_handler_remove();
$answer = $line;
}
rl_callback_handler_install( "$question ", &line-handler );
$rl.insert-text($suggestion);
$rl.redisplay;
while (!$answer) {
$rl.callback-read-char();
}
return $answer;
}
my $name = prompt-prefill("What's your name?", "Bob");
say "Hi $name. Go away.";
如果您仍打算使用 Linenoise, you might find the 'hints' feature good enough for your needs (it's used extensively by the redis-cli
application if you want a demo). See the hint
callback used with linenoiseSetHintsCallback
in the linenoise example.c file。如果这还不够好,您将不得不开始深入研究 linenoise。
在 bash shell 中,如果您点击向上或向下箭头,shell 将显示您输入的上一个或下一个命令,您可以编辑这些命令以是新的 shell 命令。
在 perl6 中,如果你这样做
my $name = prompt("Enter name: ");
它将打印"Enter name: "然后要求输入;有没有办法让 perl6 给你一个默认值,然后你只需将默认值编辑为新值。例如:
my $name = prompt("Your name:", "John Doe");
并打印
Your name: John Doe
其中 John Doe 部分是可编辑的,当您按下回车键时,编辑的字符串就是 $name 的值。
https://docs.raku.org/routine/prompt 没有说明如何去做。
如果您必须输入许多长字符串,而每个字符串与其他字符串只有几个字符不同,这将很有用。
谢谢。
要让编辑部分顺利进行,您可以使用 Linenoise 模块:
zef install Linenoise
(https://github.com/hoelzro/p6-linenoise)
然后,在您的代码中执行:
use Linenoise;
sub prompt($p) {
my $l = linenoise $p;
linenoiseHistoryAdd($l);
$l
}
然后你可以使用提示进行循环。请记住,基本上所有 Perl 6 内置函数都可以词法覆盖。现在,如何填写原始字符串,我还没有弄清楚。也许 libreadline 文档可以帮助您。
另一个解决方案:
使用io-prompt 有了它,您可以设置默认值甚至默认类型:
my $a = ask( "Life, the universe and everything?", 42, type => Num );
Life, the universe and everything? [42]
Int $a = 42
您可以安装它:
zef install IO::Prompt
但是,如果只是一个默认值是不够的。那么你最好使用Liz建议的方法。
默认情况下,程序完全不知道它们的终端。
您需要您的程序与终端通信以执行诸如预填充输入行之类的操作,期望 Perl 6 将此类操作作为核心语言的一部分来处理是不合理的。
就是说,只要您有一个兼容的终端,您的确切案例就由 Readline 库处理。
Perl 6 Readline 似乎没有预输入挂钩设置,因此很遗憾,您需要自己处理回调和读取循环。这是我粗略的尝试,完全符合您的要求:
use v6;
use Readline;
sub prompt-prefill($question, $suggestion) {
my $rl = Readline.new;
my $answer;
my sub line-handler( Str $line ) {
rl_callback_handler_remove();
$answer = $line;
}
rl_callback_handler_install( "$question ", &line-handler );
$rl.insert-text($suggestion);
$rl.redisplay;
while (!$answer) {
$rl.callback-read-char();
}
return $answer;
}
my $name = prompt-prefill("What's your name?", "Bob");
say "Hi $name. Go away.";
如果您仍打算使用 Linenoise, you might find the 'hints' feature good enough for your needs (it's used extensively by the redis-cli
application if you want a demo). See the hint
callback used with linenoiseSetHintsCallback
in the linenoise example.c file。如果这还不够好,您将不得不开始深入研究 linenoise。