I have a shell script (which I source into .bashrc) that allows me to jump to my projects directory from anywhere.
cdp(){
proj="~/dev/projects/$@/"
builtin cd $proj
}
_my_cdp()
{
local cur opts
cur="${COMP_WORDS[COMP_CWORD]}"
opts=$(ls ~/dev/projects/)
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
}
complete -o nospace -F _my_cdp cdp
The problem is, the cd on line 3 says:
bash: cd: ~/dev/projects/jsonparse/: No such file or directory
Here is the full console output showing the error and proving the directory exists.
amflare:~$ cd dev/projects/ (go to dir)
amflare:~/dev/projects$ ls -al (look at contents)
total 68
drwxrwxr-x 17 www-data amflare 4096 Dec 29 13:11 .
drwxrwxr-x 4 amflare amflare 4096 Dec 6 17:32 ..
drwxrwxr-x 3 www-data amflare 4096 Dec 22 17:33 bot
drwxrwxr-x 3 www-data amflare 4096 Dec 20 15:17 jsonparse
drwxrwxr-x 3 www-data amflare 4096 Dec 28 19:58 magic
drwxrwxr-x 2 www-data amflare 4096 Nov 11 14:42 test
amflare:~/dev/projects$ cd (go to home)
amflare:~$ cdp (run autocomplete)
bot jsonparse magic test
amflare:~$ cdp jsonparse (pick target)
bash: cd: ~/dev/projects/jsonparse/: No such file or directory
amflare:~$ (still in home)
I've tried everything I can think of and a few things google gave back for other distros (I'm on Ubuntu Gnome 16.04). No matter what I do, the shell script will not acknowledge the existence of anything inside ~/dev/projects/. Additionally, it does not work when I have the functions in .bashrc itself, so I don't think it is a subshell problem. Please let me know if you need any more information. Thanks.
That's because the tilde isn't expanded. Use
proj=~/"dev/projects/$@/"with the tilde out of the quotes. Or use the variableHOME:proj="$HOME/dev/projects/$@". Note, though, that using$@is not really good. What do you want if there are several arguments?Also, don't use
opts=$(ls ~/dev/projects/). Usecompgendirectly like so:When completing, the completion function
_my_cdpwill have as parameter$2the word being completed; we give that tocompgen -d(with the prefix$proj), and loop through the results (the results are output one per lineāso yeah, it'll break if you have newlines in your directories). With each name found, we quote it usingprintf '%q', while using a parameter expansion to remove the prefix$proj. The quoting is used so as not to break if directory name contains spaces or funny characters (e.g., glob characters), and we populate the arrayCOMPREPLYone term at a time. That's a rather robust way to deal with completion (yet not 100% unbreakable, but it'll do the job for your non-crazy directory names!).