Set working directory for function arguments

216 Views Asked by At

My code is all located in the following directory on my computer /a/b/c/d/e/myCode. I got annoyed of typing make /a/b/c/d/e/myCode/project1 when I wanted to compile project1. To fix this I created a function in my bashrc that looks as follows:

function make_project { make /a/b/c/d/e/myCode/$1; }

Then I call it like this:

make_project project1

This works fine. The only problem with this is that I don't have autocompletion for project1. So if I have a project with a complicated name like my_complicatedly_named_project I will need to type the whole name in. Is there any way for bash to know that the arguments are directories in /a/b/c/d/e/myCode/ and it could autocomplete appropriately?

3

There are 3 best solutions below

1
On BEST ANSWER

The compgen command can be used to generate and test completions and looking over the existing completions can provide some help generating new ones. You are after directories in a particular subtree so the following should work in bash:

function _make_project {
    COMPREPLY=( $(cd /a/b/c/d/myCode; compgen -A directory -- "${COMP_WORDS[COMP_CWORD]}") );
}

This uses compgen to get directories that might complete the current argument, starting at the myCode subtree. To install this for your function you should use the complete command to associate this completion function with the bash function:

complete -F _make_project make_project

Update

To avoid having a space character appended to the completed work, when registering the completion function the nospace option can be provided. If this is combined with the -S option to compgen to append a suffix character then the completions can appear as directory names and it is possible to walk the subtree easily:

function _make_project {
    COMPREPLY=( $(cd /a/b/c/d/myCode; compgen -S / -A directory -- "${COMP_WORDS[COMP_CWORD]}") );
}
complete -o nospace -F _make_project make_project
0
On

Use a soft link for myCode directory.

ln -s /a/b/c/d/e/myCode/ ~/myCode

Modify your function to:

function make_project { make $1; }

I suppose typing an additional myCode will not hurt too much:

make_project ~/myCode/project_name

or just use make:

make ~/myCode/project_name 

You can use autocomplete as well after typing ~/myCode/

1
On

I don't know if bash can do this, but zsh can reasonably do this. To make this work in zsh, add this line to .zshrc:

fpath=(~/.zshcompletion $fpath)

Then create the file ~/.zshcompletion/_make_project:

#compdef make_project

# _arguments "1: :(World)"

_make_project() {
    # Note: Do the following two lines mean anything?:
    local curcontext="$curcontext" state line
    typeset -A opt_args

    for dir in /a/b/c/d/e/myCode/*(/); do
        compadd "$@" "${dir/*\//}"
    done
}

Note: I know this isn't the answer you asked for, but since zsh has basically the same user interface as bash (with scripts usually being compatible), I figured it might be useful if there's not an easy bash solution.