(Note: The stuff below is highly experimental and I haven't tested it beyond with a few limited filenames, as I realized on completion this is too restrictive (I come across this post searching for solutions to the same problem...) - I'll explain see why later.)
Escape function - nothing special, just escapes the spaces and other special characters, I've probably missed some out...:
Code:
_escape () {
local argv=$1
local out
if (( $(echo $argv|grep -cE "[ ()!$|]|'\''|[|]")==1 )); then # Same as the sed expression below - sed needs to be escaped.
out=$(echo "$argv"|sed -e 's/\([ ()!$|]\|'\''\|\[\|\]\)/\\\1/g')
else
out=$argv
fi
echo $out # So caller can set it to a variable
return 0
}
File completion - get the entire directory listing then select the files only:
Code:
_fcomp () {
local argv=$2
local listing
local i j
local IFS=$'\n' # We want to ignore spaces and use \n only - or use $'\x0a'.
listing=( $(compgen -f $argv) )
for ((i=0, j=0; i<${#listing[*]}; i++)); do
if [ -f ${listing[i]} ]; then
COMPREPLY[j]=$(_escape "${listing[i]}") # Possible bottleneck in "_escape"?
((j++)) # Only incrase if it's a file
fi
done
}
Assign the above 2 functions using something like below, for the various editors:
complete -F _fcomp gedit less mousepad vi vim
The main problem with this implementation is that:
1 - You cannot access a file in another directory...
2 - Performance - Enumerating an entire directory and picking off the bits you want is rather slow. Best to just use quoted escape instead - something like: compgen -f -P '"' -S '"' "$searchString" - I only coded the escape function like this for self education...
Hope this give you some idea...