5

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] 
  1. I would understand if autocomplete fails (because it would canonize the path and look into base/ and not dir/).

  2. 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 ?

blahdiblah
  • 33,069
  • 21
  • 98
  • 152
mbonnin
  • 6,893
  • 3
  • 39
  • 55
  • 1
    Googling for "bash autocomplete symlink to directory" finds: http://unix.stackexchange.com/questions/14337/why-is-bash-completion-of-a-symlink-different-than-a-directory http://superuser.com/questions/155167/tab-completion-with-directories-links http://superuser.com/questions/271626/bash-autocomplete-on-symlink-to-directory-complete-to-whole-directory-including – huon Apr 12 '12 at 08:56
  • First link is about find, not bash autocompletion. Second link is about autocompletion to a symlink. This is not my case as subdir is a regular directory. Also I guess I have mark-symlinked-directories set to on already as typing `cd li[tab]` autocompletes to `cd link/` None of these links tell me how to complete to `cd ../subdir/` – mbonnin Apr 12 '12 at 09:42

3 Answers3

1

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

Peter.O
  • 6,696
  • 4
  • 30
  • 37
  • Where do you get the table from ? Is it documented in bash manual or did you get it from experience ? About the lcd() command, I do not really need this. What I want is autocomplete to put the ending '/'. – mbonnin Apr 12 '12 at 12:13
  • Also a strange thing I just noticed is that both `cd ../dir` and `cd ../subdir` work ! Looks strange... – mbonnin Apr 12 '12 at 12:14
  • I seems that what you need it `complete` ... I haven't used it before, but it certainly allows for customization.... I've added a link .. – Peter.O Apr 12 '12 at 15:30
  • Problem is I want to customize the default `cd` command. So using complete would force me to completely override the default completion just for my particular case. This could work but I do not like it so much. And it still does not explain why the default completion is behaving this way... – mbonnin Apr 13 '12 at 08:19
  • My impression, from reading that linked page, is that it is most likely a simple case of it being the deault behaviour for `cd` (the page refers to a definition file (couldn't find it on my system though)... eg. I like it (and probably others do too). I like it because it offers a way to know that it **is** a symbolic link... – Peter.O Apr 13 '12 at 08:57
  • I guess you're right by saying it 'works as designed' But `subdir` **is not** a symlink so I still find the behaviour a bit strange. – mbonnin Apr 13 '12 at 12:15
0

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...

mbonnin
  • 6,893
  • 3
  • 39
  • 55
0

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

SchmitzIT
  • 9,227
  • 9
  • 65
  • 92
  • I doubt this is the same problem as I do not have the bash-completion installed. Also the problem I describe is very specific to symlink and the internal readline completion – mbonnin May 16 '12 at 07:43