带箭头键的 Perl Term::ReadKey
Perl Term::ReadKey with Arrow Keys
我在 ReadMode('cbreak') 中使用 Term::ReadKey 来读取单个字符并根据输入执行操作。这适用于除箭头键之外的所有其他键。按下箭头键时,该操作执行 3 次,我理解这是因为箭头键转换为“^[[A”等...
如何将箭头键转换为 ReadKey 可以解释的任意单个值?
我尝试了以下代码,但它不起作用:
use Term::ReadKey;
ReadMode('cbreak');
my $keystroke = '';
while ($keystroke ne 'h') {
print "Enter key: ";
#Read user keystroke
$keystroke = ReadKey(0);
chomp($keystroke);
if(ord($keystroke) == 27) {
$keystroke = ('0');
}
}
这是我根据建议编写的代码:
use Term::RawInput;
use strict;
use warnings;
my $keystroke = '';
my $special = '';
while(lc($keystroke) ne 'i' && lc($keystroke) ne 't'){
my $promptp = "Enter key: ";
($keystroke,$special) = rawInput($promptp, 1);
if ($keystroke ne '') {
print "You hit the normal '$keystroke' key\n";
} else {
print "You hit the special '$special' key\n";
}
chomp($keystroke);
$keystroke = lc($keystroke);
}
if($keystroke eq 'i') {
#Do something
}
if($keystroke eq 't') {
#Do something
}
现在,无论我按什么,我都无法退出这个循环
这是输出:
Enter key:
Enter key:
Enter key: You hit the normal 't' key
#Proceeds to function
Term::RawInput
并没有涵盖所有内容,但对于这项任务来说这是一个很好的开始:
use Term::RawInput;
my ($keystroke,$special) = rawInput("", 1);
if ($keystroke ne '') {
print "You hit the normal '$keystroke' key\n";
} else {
print "You hit the special '$special' key\n";
}
如果你想阅读 "keypresses" 的高级语义思想,而不是 "bytes from the terminal" 的低级语义思想,你需要一些可以解析和收集那些多-字节序列给你。
对于这类任务,我写了Term::TermKey:
use Term::TermKey;
my $tk = Term::TermKey->new( \*STDIN );
print "Press any key\n";
$tk->waitkey( my $key );
print "You pressed: " . $tk->format_key( $key, 0 );
这是我的工作解决方案...
use Term::ReadKey;
ReadMode('cbreak');
{
#Temporarily turn off warnings so no messages appear for uninitialized $keystroke
#that for some reason appears for the if statement
no warnings;
my $keystroke = '';
while ($keystroke ne 'h') {
print "\nEnter key: ";
#Read user keystroke
$keystroke = ReadKey(0);
#The first character for the arrow keys (ex. '^[[A') evaluates to 27 so I check for
#that
if(ord($keystroke) == 27) {
#Flush the rest of the characters from input buffer
#This produces an 'Use of uninitialized value...' error
#for the other two characters, hence 'no warnings' at the beginning.
#This will ignore the other 2 characters and only cause a single iteration
while( defined ReadKey(-1) ) {}
}
ReadMode 0;
}
}
基于 mob
答案,使用 Term::RawInput,我编写了这个脚本来模拟更复杂的输入交互。最重要的区别是使用 'rawInput': mob
suggested: rawInput("",1)
, 我发现实际上使用 rawInput("> ")
(没有第二个参数)使事情更容易使用, 提示符“>”更有用
此代码接受命令和特殊键。此外,它显示得很好,可以用作您系统的交互式 shell。
DELETE
键将删除所有字符和 BACKSPACE
单个字符。 ESC
将退出 shell。您可以添加更多键以包括箭头或其他任何东西来执行特殊功能。此代码将打印出 if..elsif
中未包含的任何特殊按键(因此您知道需要添加什么)。
use warnings;
use strict;
use Term::RawInput;
sub out {
my $out = shift;
print "[ $out ]\n";
}
do {
my ($keystroke,$special) = rawInput("> ");
if($special eq 'ESC') {
print "\n";
exit;
} elsif($special eq 'ENTER') {
out($keystroke);
} elsif($special ne 'DELETE') {
if ($keystroke ne '') {
out($keystroke);
} else {
print "'$special' key is not associated\n";
}
}
} while(1);
你可以在里面实现你的命令 "out";
我在 ReadMode('cbreak') 中使用 Term::ReadKey 来读取单个字符并根据输入执行操作。这适用于除箭头键之外的所有其他键。按下箭头键时,该操作执行 3 次,我理解这是因为箭头键转换为“^[[A”等...
如何将箭头键转换为 ReadKey 可以解释的任意单个值?
我尝试了以下代码,但它不起作用:
use Term::ReadKey;
ReadMode('cbreak');
my $keystroke = '';
while ($keystroke ne 'h') {
print "Enter key: ";
#Read user keystroke
$keystroke = ReadKey(0);
chomp($keystroke);
if(ord($keystroke) == 27) {
$keystroke = ('0');
}
}
这是我根据建议编写的代码:
use Term::RawInput;
use strict;
use warnings;
my $keystroke = '';
my $special = '';
while(lc($keystroke) ne 'i' && lc($keystroke) ne 't'){
my $promptp = "Enter key: ";
($keystroke,$special) = rawInput($promptp, 1);
if ($keystroke ne '') {
print "You hit the normal '$keystroke' key\n";
} else {
print "You hit the special '$special' key\n";
}
chomp($keystroke);
$keystroke = lc($keystroke);
}
if($keystroke eq 'i') {
#Do something
}
if($keystroke eq 't') {
#Do something
}
现在,无论我按什么,我都无法退出这个循环
这是输出:
Enter key:
Enter key:
Enter key: You hit the normal 't' key
#Proceeds to function
Term::RawInput
并没有涵盖所有内容,但对于这项任务来说这是一个很好的开始:
use Term::RawInput;
my ($keystroke,$special) = rawInput("", 1);
if ($keystroke ne '') {
print "You hit the normal '$keystroke' key\n";
} else {
print "You hit the special '$special' key\n";
}
如果你想阅读 "keypresses" 的高级语义思想,而不是 "bytes from the terminal" 的低级语义思想,你需要一些可以解析和收集那些多-字节序列给你。
对于这类任务,我写了Term::TermKey:
use Term::TermKey;
my $tk = Term::TermKey->new( \*STDIN );
print "Press any key\n";
$tk->waitkey( my $key );
print "You pressed: " . $tk->format_key( $key, 0 );
这是我的工作解决方案...
use Term::ReadKey;
ReadMode('cbreak');
{
#Temporarily turn off warnings so no messages appear for uninitialized $keystroke
#that for some reason appears for the if statement
no warnings;
my $keystroke = '';
while ($keystroke ne 'h') {
print "\nEnter key: ";
#Read user keystroke
$keystroke = ReadKey(0);
#The first character for the arrow keys (ex. '^[[A') evaluates to 27 so I check for
#that
if(ord($keystroke) == 27) {
#Flush the rest of the characters from input buffer
#This produces an 'Use of uninitialized value...' error
#for the other two characters, hence 'no warnings' at the beginning.
#This will ignore the other 2 characters and only cause a single iteration
while( defined ReadKey(-1) ) {}
}
ReadMode 0;
}
}
基于 mob
答案,使用 Term::RawInput,我编写了这个脚本来模拟更复杂的输入交互。最重要的区别是使用 'rawInput': mob
suggested: rawInput("",1)
, 我发现实际上使用 rawInput("> ")
(没有第二个参数)使事情更容易使用, 提示符“>”更有用
此代码接受命令和特殊键。此外,它显示得很好,可以用作您系统的交互式 shell。
DELETE
键将删除所有字符和 BACKSPACE
单个字符。 ESC
将退出 shell。您可以添加更多键以包括箭头或其他任何东西来执行特殊功能。此代码将打印出 if..elsif
中未包含的任何特殊按键(因此您知道需要添加什么)。
use warnings;
use strict;
use Term::RawInput;
sub out {
my $out = shift;
print "[ $out ]\n";
}
do {
my ($keystroke,$special) = rawInput("> ");
if($special eq 'ESC') {
print "\n";
exit;
} elsif($special eq 'ENTER') {
out($keystroke);
} elsif($special ne 'DELETE') {
if ($keystroke ne '') {
out($keystroke);
} else {
print "'$special' key is not associated\n";
}
}
} while(1);
你可以在里面实现你的命令 "out";