How can I expand a relative path at the command line, with tab completion?
You could use programmable tab completion within bash for this:
function _vim_complete_file() {
IFS=$'\n' read -d '' -a FILES <<< "$( compgen -A file "${COMP_WORDS[$COMP_CWORD]}" )"
IFS=$'\n' read -d '' -a COMPREPLY <<< "$( realpath "${FILES[@]}" )"
}
complete -F _vim_complete_file vim
Now if you type vim 000
TAB, it will replace 000
with /path/to/000-default
.
Explanation
The way this works is that complete -F _vim_complete_file vim
tells bash to use the function _vim_complete_file
whenever you press TAB on an argument to vim
.
The function then runs compgen -A file
on the current word the cursor was on when you hit TAB. This returns a list of files matching it.
That list of files is then passed to realpath
which generates the fully qualified path. This list is stored as an array in COMPREPLY
which the shell looks in for the available completions.
I can't find a good way to do that.
What I do is type $PWD
before the file name, then press Tab to expand it. In bash
you may need to press Ctrl+Alt+e instead of Tab.
e.g.
vi $PWD/000-default
then
Ctrl+Alt+e
then
Enter
You might want to start using pushd and popd so it's easier to go back to a previous directory: http://gnu.org/software/bash/manual/bashref.html#The-Directory-Stack
I saw your comment about cdargs
(which I assume is this). For directories that I use frequently, I use an alias or function. For example
alias cgi='pushd /path/to/apache/cgi-bin'
or
docs() { pushd /path/to/apache/docroot/"$1"; }
The 2nd form is useful if there's a parent directory where the subdirs are frequent, then docs foo
takes me to /path/to/apache/docroot/foo
. The downside is you lose tab completion, but it hasn't been so arduous for me.