如何在不打印换行符的情况下使用 Term::ReadLine 读取用户输入?
How can I read user input using Term::ReadLine without having the newline character printed out?
如何在用户按下 Enter 时使用 Term::ReadLine
读取用户输入而不打印换行符?
我想这样做的原因是因为我想从屏幕底部的提示中读取用户输入(如 less
或 vim
)。目前,按 Enter 会导致屏幕向下滚动,这可能是个问题。另外,我想避免此时不得不诉诸 ncurses
。
设置
$term->Attribs->{echo_control_characters}
到 0
、undef
或 off
似乎不起作用。
#!perl
use Term::ReadLine;
use Term::ReadKey;
my $term = new Term::ReadLine ('me');
$term->ornaments(0);
$term->Attribs->{echo_control_characters} = 0;
print STDERR "\e[2J\e[s\e[" . ( ( GetTerminalSize() ) [1] ) . ";1H"; # clear screen, save cursor position, and go to the bottom;
my $input = $term->readline('> ');
print STDOUT "\e[uinput = $input\n"; # restore cursor position, and print
我可以使用 Term::ReadKey
和 cbreak
作为读取模式来做到这一点:
#!perl
use Term::ReadKey;
ReadMode 'cbreak';
my ( $k, $input );
print STDERR "> ";
while ( defined ( $k = ReadKey 0 ) and $k !~ /\n/ )
{
$input .= $k;
print STDERR $k;
}
print STDOUT "input = $input\n";
ReadMode 'restore';
但那样我就无法使用 Term::ReadLine
功能,例如历史记录、完成和行编辑。
您可以设置 rl_getc_function
在打印之前拦截回车 return,如 问题所示。以下对我有用:
use strict;
use warnings;
BEGIN {
$ENV{PERL_RL} = "Gnu";
}
use Term::ReadLine;
use Term::ReadKey;
my $term = Term::ReadLine->new('me');
my $attr = $term->Attribs;
$term->ornaments(0);
$attr->{getc_function} = sub {
my $ord = $term->getc($attr->{instream});
if ( $ord == 13 ) { # carriage return pressed
$attr->{done} = 1;
return 0;
}
return $ord;
};
print STDERR "\e[2J\e[s\e[" . ( ( GetTerminalSize() ) [1] ) . ";1H";
my $input = $term->readline('> ');
print STDOUT "\e[uinput = $input\n"; # restore cursor position, and print
如何在用户按下 Enter 时使用 Term::ReadLine
读取用户输入而不打印换行符?
我想这样做的原因是因为我想从屏幕底部的提示中读取用户输入(如 less
或 vim
)。目前,按 Enter 会导致屏幕向下滚动,这可能是个问题。另外,我想避免此时不得不诉诸 ncurses
。
设置
$term->Attribs->{echo_control_characters}
到 0
、undef
或 off
似乎不起作用。
#!perl
use Term::ReadLine;
use Term::ReadKey;
my $term = new Term::ReadLine ('me');
$term->ornaments(0);
$term->Attribs->{echo_control_characters} = 0;
print STDERR "\e[2J\e[s\e[" . ( ( GetTerminalSize() ) [1] ) . ";1H"; # clear screen, save cursor position, and go to the bottom;
my $input = $term->readline('> ');
print STDOUT "\e[uinput = $input\n"; # restore cursor position, and print
我可以使用 Term::ReadKey
和 cbreak
作为读取模式来做到这一点:
#!perl
use Term::ReadKey;
ReadMode 'cbreak';
my ( $k, $input );
print STDERR "> ";
while ( defined ( $k = ReadKey 0 ) and $k !~ /\n/ )
{
$input .= $k;
print STDERR $k;
}
print STDOUT "input = $input\n";
ReadMode 'restore';
但那样我就无法使用 Term::ReadLine
功能,例如历史记录、完成和行编辑。
您可以设置 rl_getc_function
在打印之前拦截回车 return,如
use strict;
use warnings;
BEGIN {
$ENV{PERL_RL} = "Gnu";
}
use Term::ReadLine;
use Term::ReadKey;
my $term = Term::ReadLine->new('me');
my $attr = $term->Attribs;
$term->ornaments(0);
$attr->{getc_function} = sub {
my $ord = $term->getc($attr->{instream});
if ( $ord == 13 ) { # carriage return pressed
$attr->{done} = 1;
return 0;
}
return $ord;
};
print STDERR "\e[2J\e[s\e[" . ( ( GetTerminalSize() ) [1] ) . ";1H";
my $input = $term->readline('> ');
print STDOUT "\e[uinput = $input\n"; # restore cursor position, and print