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 000TAB, 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.