I have the following directory structure:
base/
dir/
subdir/
link -> ../dir
Now if I cd to dir/link and type:
cd ../subd[tab]
I get:
cd ../subdir[space]
I would understand if autocomplete fails (because it would canonize the path and look into base/ and not dir/).
I would also understand if it autocompletes to cd ../subdir/
with the ending / (because it would interpret ..
as go up one level
and search into dir/).
But I do not understand the actual behaviour that is somewhere between the two. Ideally I would like bash to behave like 2. (autocomplete to cd ../subdir/). I am using fedora 14, bash version 4.1.7(1). Any idea how to accomplish this ?
UPDATE: The program with which you can customize auto-completion is called complete
.
You can find some good basic examples here: More on Using the Bash Complete Command
Using function and script names as per the above link, here is a script which appends the /
to a symbolic link to a directory... It is just a rough sample, but it shows it can be done (I haven't tried it with the cd
builtin...
Associate the function _mycomplete_
with executable myfoo
complete -F _mycomplete_ myfoo
The function to go in ~/.bashrc
function _mycomplete_()
{
local cmd="${1##*/}"
local word=${COMP_WORDS[COMP_CWORD]}
local line=${COMP_LINE}
local xpat='!*.foo'
COMPREPLY=($(compgen -f -X "$xpat" -- "${word}"))
if ((${#COMPREPLY[@]}==1)) ;then
[[ -h $COMPREPLY ]] && COMPREPLY="$COMPREPLY/"
fi
}
Original answer:
At the command-line, the main indicator of a auto-expansion to a symbolic link is shown on the last line of the following table, ie. a name expands but without the final /
.
on pressing TAB on pressing TAB (again)
what happens? meaning what happens?
=================== ======================= ====================================
Nothing is appended 1=> Multiple sub-dirs exist => A list of possibilities is presented
2=> No sub-directory exists => Nothing is appended (again)
Expands to end in / => A uniquely matching dir => ...as per first column (repeat)
Expands text only => Current name is a link => Expands to end in /
In your example, if you have already primed the command-line to the full name, ie. cd link
then the indicator is not obvious. Also you won't know it is a symbolic link via the list of possibilities.
To be able to cd
to the link's target, you can use cd -P link
, or set -P; cd link
After digging the source code a bit, it looks like this is a bit complicated. The actual problem is a mix between bash allowing symlinks inside the working directory (see pwd -L and pwd -P) and readline not able to determine the type of a match if it is not in a physical directory
In readline/complete.c:1694
s = (nontrivial_match && rl_completion_mark_symlink_dirs == 0)
? LSTAT (filename, &finfo)
: stat (filename, &finfo);
stat() fails since ../ is understood as relative to the physical path and not the logical path. readline fails to determine this is a directory and therefore does not append the final '/'.
A very similar problem is described here
So I guess I can live with the existing behaviour for now...
I was having the exact same problem in Ubuntu. Autocompletion was working like in your example #2, but started working as you describe at some point. I purged and reinstalled the package bash-completion, and now everything seems back to normal. Do not uninstall bash! Only bash-autocompletion.
Edit
look at this:
https://bbs.archlinux.org/viewtopic.php?id=113158