5

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?

Benjy Kessler
  • 7,356
  • 6
  • 41
  • 69
  • Please see ["Should questions include “tags” in their titles?"](http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles), where the consensus is "no, they should not"! –  Dec 22 '14 at 12:10

3 Answers3

2

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
patthoyts
  • 32,320
  • 3
  • 62
  • 93
  • A small question, when I press tab now in autocompletes correctly but it adds a space afterwards. So if I want a subdirectory I have to click backspace and then /. Is there a way for the autocomplete not to add the space? – Benjy Kessler Dec 22 '14 at 11:16
0

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.

piojo
  • 6,351
  • 1
  • 26
  • 36
  • You're welcome. This is quite similar to my case where I wanted to set some environment stuff based on which project I was working on, but the folder name was really the only important piece of data. So I figured out how to do this, and I hope I never have to figure it out again. :) – piojo Dec 22 '14 at 15:29
0

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/

pratZ
  • 3,078
  • 2
  • 20
  • 29