The last command executed is available in a register. Specifically, the :
register. So autocomplete the path, submit the command and then in the buffer in Normal mode simply
":p
...to paste in the command and path. Edit away the non-path parts as needed.
For a bit more of an automated approach you can extract the filename before dumping it into the buffer.
Let's say my command was :!ls /foo/bar/baz.txt
. Following that with...
:let @x = split(@:, " ")[-1]
(Assuming no spaces in your path!) This splits the output on spaces and takes the last element ([-1]
) of the resulting list (ie. the path) and stores it into register 'x' ... and we know that pasting the register's contents into the buffer is just a matter of "xp
. (Basic registers are a familiar and easy way to get vim command output into a buffer. I mention one of various alternatives at the end of this post.)
Taking things way beyond minimums, you could even have Vim parse the path using the fnamemodify()
function which takes a path and one or more modifiers that can do things like extract the head, file only, extension, all but extension, etc.
For example, after the !ls
command do:
:let @x = fnamemodify(split(@:, " ")[-1], ":p:h")
Where the modifiers indicate "head" of "(full) path" That will save /foo/bar
into register x and then, as before, insert it with "xp
.
Vim can do all kinds of path/string processing. This is just a couple examples to introduce the idea. (Or you may just want to paste register :
as is and be done with it.)
Alternatives to register :
Another quick way to get part of a previously executed command is to hit q:
which will put you in Ex mode. There you can look at any command in history and cut/paste any bits you want to transfer to the buffer. Navigate in the window that is opened in this mode just like you navigate a normal buffer.
An interesting approach that never even crossed my mind is mentioned in a comment below by @D.Ben Knoble : from Insert mode enter a /
(as in filesystem root) and trigger filename completion with <c-x><c-f>
. A popup will show all top level dirs and files and you can select one with <c-y>
then hit <c-x><c-f>
again and choose another and so on. A little awkward for me personally versus a bunch of <Tab>
s but clever enough to deserve a mention here. :)
Path in command output
What if the command output rather than the command itself contains the path (or anything else you want to extract). Here are a few things you can do.
- From Insert mode use the expression register to run a command. Output will be fed directly to the buffer.
:h @=
- Use
:put =command(args)
to insert command output. (This is similar mechanism to that used in previous item.) :h :put
- Use redirection to store command output in a register or variable. (
:h :redi
)