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.