cpanpm icon indicating copy to clipboard operation
cpanpm copied to clipboard

[feature] Shell completion

Open Freed-Wu opened this issue 2 years ago • 4 comments
trafficstars

Is it possible that cpan has tab completion in shell (bash/zsh/fish/etc)? TIA!

Freed-Wu avatar Jan 11 '23 10:01 Freed-Wu

This is something I'm open to adding. The only thing I can think to complete is namespaces, and there are a lot of those. I don't know how I'd accomplish that; maybe an out of band process to make the complete file?

Note that tab completion is something almost entirely outside of the command itself, so cpan doesn't have to really do anything for you to be able to complete. The cpan command, however, can know how to create that file for you.

briandfoy avatar Nov 03 '23 17:11 briandfoy

I played around with namespace autocompletion in bash, and it's so slow as to be unusable. Also, the : is a special character in complete, which uses it as a word separator. Even when I limited it to the top namespace in a distribution it was pretty slow, and missed things that you would expect, such as Test::Foo being in the Foo distro.

I think this means that the command-line version of this has no where to go. If there were a web skin on cpan, you could hook in MetaCPAN's API and update as you type into a box.

briandfoy avatar Nov 06 '23 17:11 briandfoy

it's so slow as to be unusable.

What is your completion script? I want to try it in my machine to see its effect :smile:

Freed-Wu avatar Nov 07 '23 07:11 Freed-Wu

I used this to make a basic bash complete command line. This creates a smaller completion list than you actually need.

use File::Spec::Functions;

my $cpan_dir = catfile( $ENV{HOME}, qw(.cpan sources modules) );
my $packages = catfile( $cpan_dir, '02packages.details.txt.gz' );

open my $fh, '<:gzip', $packages or die "Could not open $packages: $!";

my $complete = qq(#/usr/bin/env bash\ncomplete -W ");

while( <$fh> ) {
	my( $namespace, $version, $path ) = split;
	next if $Seen{$path};
	$Seen{$path} = $namespace;
	$complete .= " $namespace";
	}

$complete .= qq(" cpan);

open my $complete_fh, '>:utf8', ".cpan_complete" or die "Could not open .cpan_complete: $!";
print {$complete_fh} $complete;
close $complete_fh;

briandfoy avatar Nov 07 '23 08:11 briandfoy