How can I expand a relative path at the command line, with tab completion?
Solution 1
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
Solution 2
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.
Solution 3
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.
Solution 4
If you are re-editing in Vim, check out :browse oldfiles
and :help oldfiles
.
cwd
Updated on September 18, 2022Comments
-
cwd over 1 year
In
bash
is there any way to expand a relative path into an absolute path, perhaps with tab completion?I ask because sometimes I will search for a file, find it, then
vim
it:cd /etc cd apache2 cd sites-available vim 000-default
Then I will do some other things and change directories:
cd /tmp ls cd ~ ls
Then I'll find that I need to edit the same file again, but it is not possible to use
history
, (or history search), because the file path is relative.Current Workaround
If I know I'm going to be reusing a file a lot, after I find it I will grab the full path using something like
realpath
:$ realpath 000-default /etc/apache2/sites-available/000-default (copy and paste path into next command:) $ vi /etc/apache2/sites-available/000-default
Caveats
This still requires copying and pasting. I believe there should be an easier way to get a file's full path into my history. What options do I have?
I believe that I have (accidentally) pressed some key combination before that expanded a relative path into a full path. I know in bash you can type:
cd /etc ls bash_*(control+x *)
and get:
ls bash.bashrc bash_completion bash_completion.d
So is there a way I can expand a relative path into an absolute path, so that I can save operations on a file in my history with that file's full path?
-
Angel Todorov about 12 yearsYou might want to start using
pushd
andpopd
so it's easier to go back to a previous directory: gnu.org/software/bash/manual/bashref.html#The-Directory-Stack -
cwd about 12 years@glennjackman - that looks really good. I found this blog and the comments really helpful, too. I'm also looking into
cdargs
now. Thanks! ps: if nobody else has a better answer just post that and I will accept it. -
phemmer about 12 yearsAnother possible solution is to leave vim running while youre working around with files, and then bring it back up. You can do this by either doing
:sh
in vim to start a subshell, and thenexit
or CTRL+D to get back into vim. Or by doing CTRL+Z in vim to background (STOP) it and thenfg
to get it back. -
Gilles 'SO- stop being evil' about 12 years
-
-
cwd about 12 yearsdamn. this is EXACTLY what I wanted to do. so simple! tab worked for me although ctrl+alt+e did not. I'm using a mac and iTerm2 to ssh to ubuntu. any way to set up something easier than
$PWD
? (the all caps is kind of cumbersome) -
cwd about 11 yearsupdate: on mac OS X I realized I can press escape, then control+e to expand the current line even if bash's tab expansion is not enabled.
-
Mikel about 11 yearsRight. Esc+Ctrl+e is equivalent to Ctrl+Alt+e. Esc sometimes works when Alt (or I guess Option on Mac?) doesn't.
-
jthill almost 4 yearsAlso the number marks,
'0
etc.