I found the answer myself: I have to use the -A action
option:
compgen -o filenames -A file ...
complete -o filenames -A file
Believe it might be better to use compgen
instead of find
in this case.
You probably already have a completion script with system. Try e.g.
locate bash_completion
On Debian variants this is probably:
/usr/share/bash-completion/bash_completion
where you find e.g. _filedir
. So the simplest way then would be something in the direction of:
*)
pushd "/some/path" >/dev/null
_filedir
popd >/dev/null
If that is not an option this could be a starter:
_comp_by_path()
{
local opt cur dir
local IFS=$'\n' x tmp
local -a tokens
opt="$1"
cur="$2"
dir="$3"
# Enter target directory
pushd "$dir" >/dev/null
# Get directories, filtered against current
[[ "$opt" != "-f" ]] && \
x=$( compgen -d -- "$cur" ) &&
while read -r tmp; do
tokens+=( "$tmp" )
done <<< "$x"
# Get files, filtered against current
[[ "$opt" != "-d" ]] && \
x=$( compgen -f -- "$cur" ) &&
while read -r tmp; do
tokens+=( "$tmp" )
done <<< "$x"
# If anything found
if [[ ${#tokens[@]} -ne 0 ]]; then
# Make sure escaping is OK
compopt -o filenames 2>/dev/null
COMPREPLY+=( "${tokens[@]}" )
fi
# Go back
popd >/dev/null
}
_GetOptMyCommand()
{
local cur
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "-h -l --help --list --" -- "$cur" ) );;
*)
_comp_by_path "any" "$cur" "/some/path"
esac
}
complete -F _GetOptMyCommand my_command
A variant using find
could be something in direction of this:
_zaso()
{
local dir="$1"
pushd "$dir" >/dev/null
find * -maxdepth 0 2>/dev/null
popd >/dev/null
}
_comp_with_find()
{
local cur dir
local IFS=$'\n'
cur="$1"
dir="$2"
compopt -o filenames 2>/dev/null
COMPREPLY=( $( compgen -W "$(_zaso "$dir")" -- "$cur" ) );
}
Also note that printf
in Bash has a %q
option. So to generate quoted strings this is an option to play with:
find * -maxdepth 0 2>/dev/null && \
while read -r tmp; do
printf "%q\n" "$tmp"
done <<< "$x"
Also not that file names can have newline characters in which a lot of this will break. Have not found a way to use \0
with compgen
.
Best Answer
I would modify the example from the link you mentioned into something like this:
For more info refer to the bash documentation or the bash hackers site.