Why type a full identifier if your editor can do it for you?
Good variable and function names are a great boon to productivity and maintainability, but brevity and clarity are often at odds. Instead of wearing out your keys, fingertips, and memory, consider making your text editor do the typing for you.
If you use Vim, you have access to a handy autocompletion mechanism. In insert mode, type one or more letters of an identifier, then hit CTRL-N. The editor will complete your identifier using the first identifier in the same file that starts with the same letter(s). Hitting CTRL-N again gives you the second matching identifier, and so on.
This can be a real timesaver if you use long variable or subroutine names. As long as you've already typed an identifier once in a file, you can autocomplete it ever after, just by typing the first few letters and then CTRL-Ning to the right name:
sub find_the_factorial_of { my ($the_number_whose_factorial_I_want) = @_; return 1 if $the_n<CTRL-N> <= 1; return $the_n<CTRL-N> * find<CTRL-N>($the_n<CTRL-N> - 1); }
Unfortunately, Vim's idea of an identifier (in Vim-speak, a "keyword") isn't as broad as Perl's. Specifically, the editor doesn't recognize the colon character as a valid part of an identifier, which is annoying if you happen to like multipart class names, or qualified package variables.
However, it's easy to teach Vim that those intervening double-colons are valid parts of the identifiers. Add them to the editor's list of keyword characters by adding the line to your .vimrc file:
set iskeyword+=:
Then the following works too:
use Sub::Normal; my $sub = Sub<CTRL-N>->new( ); # Expands to: Sub::Normal->new( )
Of course, you still have to type the full name of Sub::Normal
once, as part of the initial use
statement. That really isn't as Lazy as it could be. It would be much better if Vim just magically knew about all the Perl modules you have installed and could cleverly autocomplete their names from the very first time you used them.
As it happens, that's easy to arrange as well. You just need a file that lists every module you have installed. Then tell Vim (in .vimrc again) to use all the identifiers in that file as a second source of keyword completions:
set complete+=k~/.vim_extras/file_that_lists_every_installed_Perl_module
The complete+=k
tells Vim you're adding to the existing sources of completions for keywords. The path name that follows specifies the file containing the additional completions.
All you need is a simple Perl script to generate that file for you:
use File::Find 'find'; # Where to create this list... my $LIST_DIR = "$ENV{HOME}/.vim_extras/" my $LIST_FILE = "file_that_lists_every_installed_Perl_module"; # Make sure the directory is available... unless (-e $LIST_DIR ) { mkdir $LIST_DIR or die "Couldn't create directory $LIST_DIR ($!)\\n"; } # (Re)create the file... open my $fh, '>', "$LIST_DIR$LIST_FILE" or die "Couldn't create file '$LIST_FILE' ($!)\\n"; # Only report each module once (the first time it's seen)... my %already_seen; # Walk through the module include directories, finding .pm files... for my $incl_dir (@INC) { find { wanted => sub { my $file = $_; # They have to end in .pm... return unless $file =~ /\\.pm\\z/; # Convert the path name to a module name... $file =~ s{^\\Q$incl_dir/\\E}{ }; $file =~ s{/}{::}g; $file =~ s{\\.pm\\z}{ }; # Handle standard subdirectories (like site_perl/ or 5.8.6/)... $file =~ s{^.*\\b[a-z_0-9]+::}{ }; $file =~ s{^\\d+\\.\\d+\\.\\d+::(?:[a-z_][a-z_0-9]*::)?}{ }; return if $file =~ m{^::}; # Print the module's name (once)... print {$fh} $file, "\\n" unless $already_seen{$file}++; }, no_chdir => 1, }, $incl_dir; }
Of course, you don't have to call the file .
vim_extras/file_that_lists_every_installed_Perl_module. Just change the $LIST_DIR
and $LIST_FILE
variables to something saner.
It's a natural next step to automate the generation of this file via cron
. Beyond that, though, consider using Vim auto-commands to update the module list when you load and save files. To get information on auto-commands, type :help autocmd-intro
within Vim. You could also check in and check out these module lists from a central repository to ensure that your editor knows about the class your coworker just added.
For a final coup-de-grace, consider extracting variable and subroutine names from the files as well. This will let you complete method names and exported variables. You could do this with regular expressions as heuristics, or through modules such as Parse::Perl
.
Tip
Emacs users take heart. You can usually find equivalents by searching the web for taskname
cperl-mode. Here's an autocompletion minor mode to add to your ~/.emacs file:
(defadvice cperl-indent-command (around cperl-indent-or-complete) "Changes \\\\[cperl-indent-command] so it autocompletes when at the end of a word." (if (looking-at "\\>") (dabbrev-expand nil) ad-do-it)) (eval-after-load "cperl-mode" '(progn (require 'dabbrev) (ad-activate 'cperl-indent-command)))
Get Perl Hacks now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.