rocky/Perl-Array-Columnize — Issue #2: Does not columnize on whole terminal width
Author: nkh
Created: 2011-11-10 13:51:11+00:00
State: open

I ran the test in your distribution "perl columnize.pm" and that works

Here is a script (you can ignore the fluff), it outputs the same @matches.

I believe that it is because you do not use the whole terminal width and in this very case the output cells are already pretty large.

$> pbs_perl_completion.pl 0 pbs --serv%

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#!/usr/bin/env perl

=pod

Add the following line in your I<~/.bashrc> or B them:

_pbs_perl_completion()
{
local old_ifs="${IFS}"
local IFS=$'\n';
COMPREPLY=( $(pbs_perl_completion.pl ${COMP_CWORD} ${COMP_WORDS[@]}) );
IFS="${old_ifs}"

return 1;
}

complete -o default -F _pbs_perl_completion pbs

Replace I with the name you saved the script under. The script has to
be executable and somewhere in the path.

I received from bash:

=over 2

=item * $index - index of the command line argument to complete (starting at '1')

=item * $command - a string containing the command name

=item * \@argument_list - list of the arguments typed on the command line

=back

You return possible completion you want separated by I<\n>. Return nothing if you
want the default bash completion to be run which is possible because of the <-o defaul>
passed to the B command.

Note! You may have to re-run the B command after you modify your perl script.

=cut

use strict;
use Tree::Trie;

my @completions =
qw(
-h
--h
-help
--help
-post_pbs
--post_pbs
-evaluate_shell_command_verbose
--evaluate_shell_command_verbose
-use_watch_server
--use_watch_server
-watch_server_double_check_with_md5
--watch_server_double_check_with_md5
-watch_server_verbose
--watch_server_verbose
-display_simplified_rule_transformation
--display_simplified_rule_transformation
-tnonh
--tnonh
-tnonr
--tnonr
) ;

my($trie) = new Tree::Trie;
$trie->add(@completions) ;

my ($argument_index, $command, @arguments) = @ARGV ;

$argument_index-- ;
my $word_to_complete = $arguments[$argument_index] ;

if(defined $word_to_complete)
{
if($word_to_complete =~ /%$/)
{
my ($search_type) = $word_to_complete =~ /(%+)$/ ;
my ($prefix) = $word_to_complete =~ /^(-+)/ ;

$word_to_complete =~ s/%+$// ;
$word_to_complete =~ s/^-+// ;

my ($longest, @matches) ;

for(@completions)
{
next unless /^$prefix/ ;
next unless /$word_to_complete/ ;

push @matches, $_ ;
$longest = length($_) unless $longest > length($_) ;
}

use Array::Columnize ;
print STDERR "$longest\n\n" ;
print STDERR "\n" . columnize(\@matches, {displaywidth => $longest}) ;

#print "$prefix$word_to_complete" ;

use Term::ReadKey;
my ($columns, $hchar, $wpixels, $hpixels) = GetTerminalSize();
$columns-- ;

use POSIX qw(ceil floor);
my $entries_per_row = floor($columns / ($longest + 1)) ;
my $rows = ceil (@matches / $entries_per_row) ;

#print STDERR join "\n", @matches ;
#print STDERR "\n$rows => $entries_per_row\n" ;
#print STDERR scalar(@matches) ."\n\n" ;

print STDERR "\n" ;

for my $row (0 .. $rows - 1)
{
for my $entry_index (0 .. $entries_per_row - 1 )
{
my $entry = $matches[($entry_index * $rows) + $row] ;

next unless defined $entry ;

use Term::ANSIColor qw (:constants) ;
my ($red, $green, $yellow, $reset) = (BOLD . RED , BOLD . GREEN, YELLOW, RESET) ;

$entry = sprintf "%-${longest}s ", $entry ;
$entry =~ s/$word_to_complete/$red$word_to_complete$reset/g ;
print STDERR $entry ;
}

print STDERR "\n" ;
}

#print STDERR "\n" ;
}
else
{
my @possible_completions = $trie->lookup($word_to_complete) ;
print join("\n", @possible_completions) ;
}

}
#~ else
#~ {
#~ # give all the possible completions, this would override other bash completion mechanisms (path, ...)
#~ print join("\n", $trie->lookup('')) ;
#~ }

print "option?\n" ;
print "?\n" ;