Changing to a directory found somewhere in the tree hierarchy

Posted on

Problem :

I frequently find myself typing:

cd a/directory/I/use/a/lot

and inside that directory there are a lot of folders I cd to back and forth.

Is there a oh-my-zsh plugin that allows to type like:

cd somd<TAB>

And then autocompletes with a list of directories whose name contains the string somed, and that are reachable from the current directory? For instance given the directory structure

somedirX
foo/bar/somedirY
baz/somedirZ/bum

Typing cd somed<TAB> should return this completion list

somedirX
somedirY
somedirZ

I could not find anything yet.

Solution :

First, you need to define a function for the completion like that:

_children_dirs() {
    find . -type d -name "${words[CURRENT]}*" -printf "%Pn" 
        | while read -r line; do
      compadd -U -X "Subdirectories: " "$line"
    done
    compstate[insert]=menu # no expand
}

This function can now be used as a completer for cd with:

compdef _children_dirs cd

However, I do not think it is a good idea to use the last command. Indeed, try to do that from your home directory and you will freeze your shell for a while (Ctrl+c to stop). A better solution could be to assign a key sequence to this completion and use it only when it is needed and safe:

zstyle ':completion:children-dirs:*' completer _children_dirs
zle -C children-dirs menu-complete _generic
bindkey '^Y' children-dirs

With that, Ctrl+y will trigger children_dirs completion.

There is another solution that I think is better, if you are ready to use another command.

function ccd { cd $1 }
compdef _children_dirs ccd

This block defines a new command ccd that uses _children_dirs_ as completer (so triggered with TAB).

You can personalize the name filter in find to search for the pattern anywhere in the filename with: "*${words[CURRENT]}*".

Edit: I have created a plugin for zsh with that.

Leave a Reply

Your email address will not be published. Required fields are marked *