n.r.
n.r.

Reputation: 1900

How to inhibit Term::ReadLine's default filename completion?

How can I disable Term::ReadLine's default completion, or rather, make it stop suggesting filename completions at some point?

For example, what do I need to replace return() with in order to inhibit the default completion from the second word onwards?

Neither of these works:

    $attribs->{'filename_completion_function'}=undef;
    $attribs->{'rl_inhibit_completion'}=1;
use Term::ReadLine;

my $term    = new Term::ReadLine 'sample';
my $attribs = $term->Attribs;
$attribs->{attempted_completion_function} = \&sample_completion;

sub sample_completion {
    my ( $text, $line, $start, $end ) = @_;

    # If first word then username completion, else filename completion
    if ( substr( $line, 0, $start ) =~ /^\s*$/ ) {

        return $term->completion_matches( $text,
            $attribs->{'username_completion_function'} );
    }
    else {
        return ();
    }
}

while ( my $input = $term->readline( "> " ) ) {
    ...
}

Upvotes: 4

Views: 258

Answers (3)

Michael Krebs
Michael Krebs

Reputation: 8196

With the Gnu implementation I discovered that I can set attempted_completion_over to avoid filename completions when my attempted_completion_function returns no results:

$attribs->{attempted_completion_over} = 1;

Gnu.pm indicates this variable is as of "GRL 4.2".

Note that you should set this variable every time your attempted_completion_function runs, or at least every time it returns no matches. I don't see that documented anywhere, but libreadline apparently resets the variable to zero after every call.

Upvotes: 1

Bublifuk Vykuk
Bublifuk Vykuk

Reputation: 1

I had to do this in my completion handler:

if <no more matches> then
    $attribs->{completion_entry_function} = \&dummy;

i.e.:

sub complete {
    my $text = shift // '';
    my $line = shift // '';
    my $start = shift // 0;
    my $end = shift // 0;
    # msg("$text, $line, $start, $end");
    my @matches = $g->complete($text, $line, $start, $end);
    # msg(vDump(\@matches));
    $attribs->{completion_entry_function} = \&dummy;
    return @matches;
}
$attribs->{attempted_completion_function} = \&complete;

Upvotes: 0

n.r.
n.r.

Reputation: 1900

Define completion_function instead of attempted_completion_function:

$attribs->{completion_function} = \&completion;

And then return undef if completion should stop, and return $term->completion_matches($text, $attribs->{filename_completion_function}) if filename completion is to take over.

In the following example, nothing is suggested for the first parameter, but filenames are for the second parameter.

use Term::ReadLine;

my $term = new Term::ReadLine 'sample';
my $attribs = $term->Attribs;
$attribs->{completion_function} = \&completion;

sub completion {

  my ( $text, $line, $start ) = @_;

  if ( substr( $line, 0, $start ) =~ /^\s*$/) {

    return 

  } else {

    return $term->completion_matches($text, $attribs->{filename_completion_function})

  }
}

while ( my $input = $term->readline ("> ") ) {
  exit 0 if $input eq "q";
}

Upvotes: 2

Related Questions