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
...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
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.
:put =command(args) to insert command output. (This is similar mechanism to that used in previous item.)
- Use redirection to store command output in a register or variable. (