#!/usr/perl -w use strict; use File::Find; # to find the source use Getopt::Long; # to process options use Pod::Usage; # generate usage from pod # you can change those if needed my $pager= 'less'; my $DIRSEP='/'; my $batch= ''; # will get & if batch mode required my ( $list, $help); # other options my %found; # valid module files (a hash so we get only one of each) GetOptions( "pager:s" => \$pager, "batch" => sub { $batch= '&' }, "list" => \$list, "help" => \$help, ) or pod2usage(2); pod2usage(1) if $help; my $module= shift || pod2usage(2); # get the module name pod2usage(2) if( @ARGV); $module .= '.pm' unless $module=~ /\.pm$/; # add .pm if needed $module=~ s{(::|-)}{$DIRSEP}g; # replace :: or - by / find( { wanted => \&wanted, no_chdir => 1}, @INC); # go get the file from @INC my @found= keys %found; # get unique files unless( @found) # nothing found, exit { print "no source found for $module\n"; } elsif( @found == 1) # found one: { my $file= shift @found; if( $list) { print "$module in $file\n"; } # list files else # or { system" $pager $file $batch"; } # page file } else { my $i; if( $list) { print "found several candidates: \n", map { " [@{[++$i]}] $_\n"} @found; } else { unshift @found, "quit"; print "found several candidates: \n", map { " [@{[$i++]}] $_\n"} @found; # use Term::ReadLine to get the exact module index require Term::ReadLine; import Term::ReadLine; # get user input my $term = Term::ReadLine->new('vmod'); my $prompt= '> '; my $index= $term->readline($prompt); exit unless( $index=~ /^\d+$/); # make sure we have a number if( ($index > 0) && ($index<@found) ) # if it's a valid number { my $file= $found[$index]; # get the file system" $pager $file $batch"; # page it } } } exit; # called for each file in the @INC forest sub wanted { return unless( m/$module$/i); $found{$_}= 1; # store file name in %found } __END__ =head1 NAME vmod - a tool to display or page Perl modules if several modules are found then a choice is given =head1 SYNOPSIS viewmod [options] [file] file is the name of the module, with or without the .pm extension levels can be separated by '::', '/', '-' or the native directory separator Options: --help -h display this message --pager -p pager/editor to use (defaults to less) --batch -b run the pager in batch mode (with -p textedit for example) --list -l only display the directory in which the source is