Complete::Bash - Completion module for bash shell
This document describes version 0.19 of Complete::Bash (from Perl distribution Complete-Bash), released on 2015-04-02.
Bash allows completion to come from various sources. The simplest is from a list of words (-W):
-W
% complete -W "one two three four" somecmd % somecmd t<Tab> two three
Another source is from a bash function (-F). The function will receive input in two variables: COMP_WORDS (array, command-line chopped into words) and COMP_CWORD (integer, index to the array of words indicating the cursor position). It must set an array variable COMPREPLY that contains the list of possible completion:
-F
COMP_WORDS
COMP_CWORD
COMPREPLY
% _foo() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=($( compgen -W '--help --verbose --version' -- $cur ) ) } % complete -F _foo foo % foo <Tab> --help --verbose --version
And yet another source is an external command (including, a Perl script). The command receives two environment variables: COMP_LINE (string, raw command-line) and COMP_POINT (integer, cursor location). Program must split COMP_LINE into words, find the word to be completed, complete that, and return the list of words one per-line to STDOUT. An example:
COMP_LINE
COMP_POINT
% cat foo-complete #!/usr/bin/perl use Complete::Bash qw(parse_cmdline format_completion); use Complete::Util qw(complete_array_elem); my ($words, $cword) = @{ parse_cmdline() }; my $res = complete_array_elem(array=>[qw/--help --verbose --version/], word=>$words->[$cword]); print format_completion($res); % complete -C foo-complete foo % foo --v<Tab> --verbose --version
This module provides routines for you to be doing the above.
Format completion for output (for shell).
Bash accepts completion reply in the form of one entry per line to STDOUT. Some characters will need to be escaped. This function helps you do the formatting, with some options.
This function accepts completion answer structure as described in the Complete POD. Aside from words, this function also recognizes these keys:
Complete
words
as (str): Either string (the default) or array (to return array of lines instead of the lines joined together). Returning array is useful if you are doing completion inside Term::ReadLine, for example, where the library expects an array.
as
string
array
Term::ReadLine
esc_mode (str): Escaping mode for entries. Either default (most nonalphanumeric characters will be escaped), shellvar (like default, but dollar sign $ will not be escaped, convenient when completing environment variables for example), filename (currently equals to default), option (currently equals to default), or none (no escaping will be done).
esc_mode
default
shellvar
$
filename
option
none
path_sep (str): If set, will enable "path mode", useful for completing/drilling-down path. Below is the description of "path mode".
path_sep
In shell, when completing filename (e.g. foo) and there is only a single possible completion (e.g. foo or foo.txt), the shell will display the completion in the buffer and automatically add a space so the user can move to the next argument. This is also true when completing other values like variables or program names.
foo
foo.txt
However, when completing directory (e.g. /et or Downloads) and there is solely a single completion possible and it is a directory (e.g. /etc or Downloads), the shell automatically adds the path separator character instead (/etc/ or Downloads/). The user can press Tab again to complete for files/directories inside that directory, and so on. This is obviously more convenient compared to when shell adds a space instead.
/et
Downloads
/etc
/etc/
Downloads/
The path_sep option, when set, will employ a trick to mimic this behaviour. The trick is, if you have a completion array of ['foo/'], it will be changed to ['foo/', 'foo/ '] (the second element is the first element with added space at the end) to prevent bash from adding a space automatically.
['foo/']
['foo/', 'foo/ ']
Path mode is not restricted to completing filesystem paths. Anything path-like can use it. For example when you are completing Java or Perl module name (e.g. com.company.product.whatever or File::Spec::Unix) you can use this mode (with path_sep appropriately set to, e.g. . or ::).
com.company.product.whatever
File::Spec::Unix
.
::
Arguments ('*' denotes required arguments):
completion* => hash|array
Completion answer structure.
Either an array or hash. See function description for more details.
opts => hash
Return value: Formatted string (or array, if `as` is set to `array`) (str|array)
Parse shell command-line for processing by completion routines.
This function basically converts COMP_LINE (str) and COMP_POINT (int) into something like (but not exactly the same as) COMP_WORDS (array) and COMP_CWORD (int) that bash supplies to shell functions.
The differences with bash are (these differences are mostly for parsing convenience for programs that use this routine):
1) quotes and backslashes are stripped (bash's COMP_WORDS contains all the quotes and backslashes);
2) variables are substituted with their values from environment variables except for the current word (COMP_WORDS[COMP_CWORD]) (bash does not perform variable substitution for COMP_WORDS). However, note that special shell variables that are not environment variables like $0, $_, $IFS will not be replaced correctly because bash does not export those variables for us.
$0
$_
$IFS
3) tildes (~) are expanded with user's home directory except for the current word (bash does not perform tilde expansion for COMP_WORDS);
4) no word-breaking characters aside from whitespaces and = are currently used (bash uses COMP_WORDBREAKS which by default also include :, ;, and so on). This is done for convenience of parsing of Getopt::Long-based applications. More word-breaking characters might be used in the future, e.g. when we want to handle complex bash statements like pipes, redirection, etc.
=
:
;
Caveats:
Due to the way bash parses the command line, the two below are equivalent:
% cmd --foo=bar % cmd --foo = bar
Because they both expand to ['--foo', '=', 'bar']. But obviously Getopt::Long does not regard the two as equivalent.
['--foo', '=', 'bar']
Getopt::Long
cmdline => str
Command-line, defaults to COMP_LINE environment.
point => int
Point/position to complete in command-line, defaults to COMP_POINT.
Return value: (array)
Return a 2-element array: [$words, $cword]. $words is array of str, equivalent to COMP_WORDS provided by bash to shell functions. $cword is an integer, equivalent to COMP_CWORD provided by bash to shell functions. The word to be completed is at $words->[$cword].
[$words, $cword]
$words
$cword
$words->[$cword]
Note that COMP_LINE includes the command name. If you want the command-line arguments only (like in @ARGV), you need to strip the first element from $words and reduce $cword by 1.
@ARGV
Parse command-line for options and arguments, more or less like Getopt::Long.
Parse command-line into words using parse_cmdline() then separate options and arguments. Since this routine does not accept Getopt::Long (this routine is meant to be a generic option parsing of command-lines), it uses a few simple rules to server the common cases:
parse_cmdline()
After --, the rest of the words are arguments (just like Getopt::Long).
--
If we get something like -abc (a single dash followed by several letters) it is assumed to be a bundle of short options.
-abc
If we get something like -MData::Dump (a single dash, followed by a letter, followed by some letters and non-letters/numbers) it is assumed to be an option (-M) followed by a value.
-MData::Dump
-M
If we get something like --foo it is a long option. If the next word is an option (starts with a -) then it is assumed that this option does not have argument. Otherwise, the next word is assumed to be this option's value.
--foo
-
Otherwise, it is an argument (that is, permute is assumed).
cword => array[str]
Alternative to passing `cmdline` and `point`.
If you already did a parse_cmdline(), you can pass the cword result (the second element) here to avoid calling parse_cmdline() twice.
words => array[str]
If you already did a parse_cmdline(), you can pass the words result (the first element) here to avoid calling parse_cmdline() twice.
Returns an enveloped result (an array).
First element (status) is an integer containing HTTP status code (200 means OK, 4xx caller error, 5xx function error). Second element (msg) is a string containing error message, or 'OK' if status is 200. Third element (result) is optional, the actual result. Fourth element (meta) is called result metadata and is optional, a hash that contains extra information.
Return value: (hash)
Other modules related to bash shell tab completion: Bash::Completion, Getopt::Complete. Term::Bash::Completion::Generator
Programmable Completion section in Bash manual: https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html
Please visit the project's homepage at https://metacpan.org/release/Complete-Bash.
Source repository is at https://github.com/perlancar/perl-Complete-Bash.
Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=Complete-Bash
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.
perlancar <perlancar@cpan.org>
This software is copyright (c) 2015 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::Bash, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Complete::Bash
CPAN shell
perl -MCPAN -e shell install Complete::Bash
For more information on module installation, please visit the detailed CPAN module installation guide.