如何使用Term :: ReadLine :: Gnu获得不区分大小写的完成?

时间:2011-11-09 18:52:29

标签: perl readline case-insensitive

使用Term::ReadLine::Gnu时似乎无法完成不区分大小写的操作。以此示例脚本为例:

use strict;
use warnings;
use 5.010;
use Term::ReadLine;

my $term = Term::ReadLine->new('test');
say "Using " . $term->ReadLine;

if (my $attr = $term->Attribs) {
  $term->ornaments(0);
  $attr->{basic_word_break_characters}     = ". \t\n";
  $attr->{completer_word_break_characters} = " \t\n";
  $attr->{completion_function} = \&complete_word;
} # end if attributes

my @words = qw(apple approve Adam America UPPER UPPERCASE UNUSED);

sub complete_word
{
  my ($text, $line, $start) = @_;
  return grep(/^$text/i, @words);
} # end complete_word

while (1) {
  $_ = $term->readline(']');
  last unless /\S/;             # quit on empty input
} # end while 1

请注意,complete_word执行不区分大小写的匹配。如果我使用Term::ReadLine::Perl(通过执行PERL_RL=Perl perl script.pl)运行它,它可以正常工作。键入a<TAB><TAB>列出所有4个单词。键入u<TAB><TAB>会将u转换为U并列出3个字。

当我使用Term::ReadLine::Gnu代替(PERL_RL=Gnu perl script.plperl script.pl)时,它只会区分大小写完成。键入a<TAB>app。键入u<TAB><TAB>不会列出任何完成。

我的set completion-ignore-case on中甚至有/etc/inputrc,但它仍然不起作用。 (但它在bash中工作正常。)

有没有办法让Term::ReadLine::Gnu做不区分大小写的完成?

1 个答案:

答案 0 :(得分:3)

问题出现在Term::ReadLine::Gnu::XS::_trp_completion_function()(用户定义的完成函数的包装器)中。

您的complete_word()函数可以正确检索您的匹配项,但是包装器中的以下代码段会执行自己区分大小写的匹配:

for (; $_i <= $#_matches; $_i++) {
    return $_matches[$_i] if ($_matches[$_i] =~ /^\Q$text/);
}

其中@_matchescomplete_word()$text的结果,到目前为止已完成的文字。

所以看起来答案是 no ,没有支持的方式让Term::ReadLine::Gnu做不区分大小写的完成。您必须覆盖私有Term::ReadLine::Gnu::XS::_trp_completion_function(一个丑陋的黑客以确定) - 或直接修改XS.pm(可以说是一个更丑陋的黑客)。

编辑: Term::ReadLine::Gnu使用的版本:1.20