Instead of keeping on commenting …
complete -f -X '!*.@(zip|udp)' unzip
should add completion for
-f -X '!*.@(zip|udp)'
| | | |||________|
| | | || |
| | | || +- filterpat: zip or udp
| | | |+------------- @ : Matches one of the given patterns
| | | +-------------- *. : Anything+<dot>
| | +---------------- ! : Negate
| +------------------- -X : Filter out matches in "filterpat"
+---------------------- -f : files
In other words: Complete files and remove all not ending in .zip
or .udp
.
Extras
If you add -o default
completion will complete/match all files and directories if there is no files ending in .zip
or .udp
.
If you add -o plusdirs
completion will add any directories in addition to any matches of files ending in .zip
or .udp
.
Current
When you use complete -p unzip
you get current pattern.
From your comments it sounds mostly like you are missing either +
or @
in pattern, as in:
# Err:
complete -f -X '!*.(zip|udp)' unzip
|
+---- Missing + or @
which would mean match any file literally ending in .(zip|udp)
. E.g.
touch 'file_test.(zip|udp)'
Also have a look at this section of the manual:
it is possible e.g. extglob
is not enabled. Enable by:
shopt -s extglob
Check current status of all shopt
settings by entering:
shopt
Function
If that is -F something
it means it uses a function named something to generate the list of completions.
The _filedir_xspec
is typically a Debian function. You might have something like this:
$ cat /etc/bash_completion
. /usr/share/bash-completion/bash_completion
Which means /usr/share/bash-completion/bash_completion
get sourced. Here you'll find the function in question. A few lines further down you see that this function / completion is added by a function named _install_xspec
by e.g.:
_install_xspec '!*.@(zip|[ejsw]ar|exe|pk3|wsz|zargo|xpi|s[tx][cdiw]|sx[gm]|o[dt][tspgfc]|od[bm]|oxt|epub|apk|do[ct][xm]|p[op]t[mx]|xl[st][xm])' unzip zipinfo
Manual entries:
Update to comments 1:
– No match due to invalid archives or file permissions.
This should not affect the result. complete
only matches files given by the rules and do no processing of the files. If you can list them with ls
, they should match.
As a side note one could add such a functionality by using a complete function:
function _unzip_validated() {
# 1. Generate list of files ending in e.g. .zip and .udp
# 2. Validate each file and remove invalid ones from file list.
}
complete -F _unzip_validated unzip
– Colors. Why does ls
distinguish test.zip
from test.upd
?
This does not affect complete
. Colors by ls
are provided by $LS_COLORS
. Try:
echo "$LS_COLORS" | tr : '\n' | sort
You should see something like *.zip=01;31
which means:
*.zip=01;31
|____| | |
| | +--- Red
| +------ Bold
+---------- Files with .zip extension
*.udp
on the other hand has no entry associated with it, so no coloring.
Next step (should have been first)
- Open terminal and go to a directory with test files. Both .zip and .udp
- Enter
bash --norc
- Enter
complete -f -X '!*.@(zip|udp)' unzip
- Enter
shopt -s extglob
- Enter
unzip <tab><tab>
Result?
Also, click edit below your question and add output of:
bind -V
shopt
env
might be helpful.