Как я могу получить регистронезависимое завершение с помощью Term :: ReadLine :: Gnu? - PullRequest
4 голосов
/ 09 ноября 2011

Не получается завершить без учета регистра при использовании 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.pl или просто perl script.pl), выполняется только регистрозависимое завершение. Ввод a<TAB> дает app. Ввод u<TAB><TAB> не выводит никаких дополнений.

У меня даже есть set completion-ignore-case on в моем /etc/inputrc, но он все еще здесь не работает. (Тем не менее, он отлично работает в bash.)

Есть ли способ получить Term :: ReadLine :: Gnu для выполнения без учета регистра?

1 Ответ

3 голосов
/ 11 ноября 2011

Может показаться, что проблема в Term::ReadLine::Gnu::XS::_trp_completion_function() (обертке для определенной пользователем функции завершения).

Ваши совпадения правильно извлекаются из вашей функции complete_word(), но затем следующий фрагмент из оболочки выполняет свое собственное совпадение с учетом регистра:

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

, где @_matches - результат ваших complete_word(), а $text - завершенный текст.

Таким образом, похоже, что ответ нет , не поддерживается поддерживаемый способ получить Term::ReadLine::Gnu для завершения без учета регистра. Вы должны были бы переопределить приватный Term::ReadLine::Gnu::XS::_trp_completion_function (безобразный хак, чтобы быть уверенным) - или изменить XS.pm напрямую (возможно, еще более уродливый взлом).

РЕДАКТИРОВАТЬ: Term::ReadLine::Gnu используемая версия: 1,20

...