Complete::Util - General completion routine
This document describes version 0.59 of Complete::Util (from Perl distribution Complete-Util), released on 2017-07-03.
This package provides some generic completion routines that follow the Complete convention. (If you are looking for bash/shell tab completion routines, take a look at the See Also section.) The main routine is complete_array_elem which tries to complete a word using choices from elements of supplied array. For example:
complete_array_elem
complete_array_elem(word => "a", array => ["apple", "apricot", "banana"]);
The routine will first try a simple substring prefix matching. If that fails, will try some other methods like word-mode, character-mode, or fuzzy matching. These methods can be disabled using settings.
There are other utility routines e.g. for converting completion answer structure from hash to array/array to hash, combine or modify answer, etc. These routines are usually used by the other more specific or higher-level completion modules.
Usage:
arrayify_answer($arg) -> array
Make sure we return completion answer in array form.
This is the reverse of hashify_answer. It accepts a hash or an array. If it receives a hash, will return its words key.
hashify_answer
words
This function is not exported by default, but exportable.
Arguments ('*' denotes required arguments):
$arg* => array|hash
Return value: (array)
combine_answers($answers, ...) -> hash
Given two or more answers, combine them into one.
This function is useful if you want to provide a completion answer that is gathered from multiple sources. For example, say you are providing completion for the Perl tool cpanm, which accepts a filename (a tarball like *.tar.gz), a directory, or a module name. You can do something like this:
*.tar.gz
combine_answers( complete_file(word=>$word), complete_module(word=>$word), );
But if a completion answer has a metadata final set to true, then that answer is used as the final answer without any combining with the other answers.
final
$answers* => array[hash|array]
Return value: (hash)
Return a combined completion answer. Words from each input answer will be combined, order preserved and duplicates removed. The other keys from each answer will be merged.
complete_array_elem(%args) -> array
Complete from array.
Try to find completion from an array of strings. Will attempt several methods, from the cheapest and most discriminating to the most expensive and least discriminating: normal string prefix matching, word-mode matching (see Complete::Common::OPT_WORD_MODE for more details), char-mode matching (see Complete::Common::OPT_CHAR_MODE for more details), and fuzzy matching (see Complete::Common::OPT_FUZZY for more details).
Complete::Common::OPT_WORD_MODE
Complete::Common::OPT_CHAR_MODE
Complete::Common::OPT_FUZZY
Will sort the resulting completion list, so you don't have to presort the array.
array* => array[str]
exclude => array
replace_map => hash
You can supply correction entries in this option. An example is when array if ['mount','unmount'] and umount is a popular "typo" for unmount. When someone already types um it cannot be completed into anything (even the current fuzzy mode will return both so it cannot complete immediately).
['mount','unmount']
umount
unmount
um
One solution is to add replace_map {'unmount'=>['umount']}. This way, umount will be regarded the same as unmount and when user types um it can be completed unambiguously into unmount.
{'unmount'=>['umount']}
word* => str (default: "")
Word to complete.
complete_comma_sep(%args) -> array
Complete a comma-separated list string.
elems* => array[str]
remaining => code
What elements should remain for completion.
This is a more general mechanism if the uniq option does not suffice. Suppose you are offering completion for sorting fields. The elements are field names as well as field names prefixed with dash (-) to mean sorting with a reverse order. So for example elems is ["name","-name","age","-age"]. When current word is name, it doesn't make sense to offer name nor -name again as the next sorting field. So we can set remaining to this code:
uniq
-
elems
["name","-name","age","-age"]
name
-name
remaining
sub { my ($seen_elems, $elems) = @_; my %seen; for (@$seen_elems) { (my $nodash = $_) =~ s/^-//; $seen{$nodash}++; } my @remaining; for (@$elems) { (my $nodash = $_) =~ s/^-//; push @remaining, $_ unless $seen{$nodash}; } \@remaining; }
As you can see above, the code is given $seen_elems and $elems as arguments and is expected to return remaining elements to offer.
$seen_elems
$elems
sep => str (default: ",")
uniq => bool
Whether list should contain unique elements.
When this option is set to true, if the formed list in the current word already contains an element, the element will not be offered again as completion answer. For example, if elems is [1,2,3,4] and word is 2,3, then without uniq set to true the completion answer is:
[1,2,3,4]
word
2,3,
2,3,1 2,3,2 2,3,3 2,3,4
but with uniq set to true, the completion answer becomes:
2,3,1 2,3,4
See also the remaining option for a more general mechanism of offering fewer elements.
complete_hash_key(%args) -> array
Complete from hash keys.
hash* => hash
hashify_answer($arg, $meta) -> hash
Make sure we return completion answer in hash form.
This function accepts a hash or an array. If it receives an array, will convert the array into `{words=>$ary}' first to make sure the completion answer is in hash form.
Then will add keys from meta to the hash.
meta
$meta => hash
Metadata (extra keys) for the hash.
modify_answer(%args) -> undef
Modify answer (add prefix/suffix, etc).
answer* => hash|array
prefix => str
suffix => str
Return value: (undef)
ununiquify_answer(%args) -> undef
If answer contains only one item, make it two.
For example, if answer is ["a"], then will make answer become ["a","a "]. This will prevent shell from automatically adding space.
["a"]
["a","a "]
Example:
use Benchmark qw(timethis); use Complete::Util qw(complete_array_elem); # turn off the other non-exact matching methods $Complete::Common::OPT_CI = 0; $Complete::Common::OPT_WORD_MODE = 0; $Complete::Common::OPT_CHAR_MODE = 0; my @ary = ("aaa".."zzy"); # 17575 elems timethis(20, sub { complete_array_elem(array=>\@ary, word=>"zzz") });
results in:
timethis 20: 7 wallclock secs ( 6.82 usr + 0.00 sys = 6.82 CPU) @ 2.93/s (n=20)
Answer: fuzzy matching is slower than exact matching due to having to calculate Levenshtein distance. But if you find fuzzy matching too slow using the default pure-perl implementation, you might want to install Text::Levenshtein::Flexible (an optional prereq) to speed up fuzzy matching. After Text::Levenshtein::Flexible is installed:
timethis 20: 1 wallclock secs ( 1.04 usr + 0.00 sys = 1.04 CPU) @ 19.23/s (n=20)
If set to true, will display more log statements for debugging.
Can be used to force which Levenshtein distance implementation to use. pp means the included PP implementation, which is the slowest (1-2 orders of magnitude slower than XS implementations), xs which means Text::Levenshtein::XS, or flexible which means Text::Levenshtein::Flexible (performs best).
pp
xs
flexible
If this is not set, the default is to use Text::Levenshtein::Flexible when it's available, then fallback to the included PP implementation.
Please visit the project's homepage at https://metacpan.org/release/Complete-Util.
Source repository is at https://github.com/perlancar/perl-Complete-Util.
Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=Complete-Util
When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.
Complete
If you want to do bash tab completion with Perl, take a look at Complete::Bash or Getopt::Long::Complete or Perinci::CmdLine.
Other Complete::* modules.
Complete::*
Bencher::Scenarios::CompleteUtil
perlancar <perlancar@cpan.org>
This software is copyright (c) 2017, 2016, 2015, 2014, 2013 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Complete::Util, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Complete::Util
CPAN shell
perl -MCPAN -e shell install Complete::Util
For more information on module installation, please visit the detailed CPAN module installation guide.