0

I use autocompletion a lot, especially for long path names:

e.g.

$ /home/au/Doc<tab> <tab>uments/A<tab> <tab>\ file\ with\ a\ very\ long\ name

This can be performed within vim:

:!ls <full path - with tabbed autocompletion>

What is the best way to get a long and difficult to accurately type path into the current buffer?

I was thinking along the lines of using the :!ls one above, then going back to the start of the line and changing the :!ls bit to yank the text (I have no idea how to achieve this)

1 Answer 1

3

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)
5
  • Also Ctrl-x ctrl-f?
    – D. Ben Knoble
    Commented May 31, 2020 at 14:22
  • @D.BenKnoble Just noticed this. OP's primary use case is leveraging command-line for auto-completion of, I believe, absolute paths (especially long ones). I thought ctrl-x ctrl-f just presents you with files in the cwd. What did you have in mind?
    – B Layer
    Commented Jun 2, 2020 at 20:15
  • You can start with / :P just thought it might be worth a mention.
    – D. Ben Knoble
    Commented Jun 2, 2020 at 20:43
  • @D.BenKnoble LOL. Oh. Didn't think of that. Thanks. I'll play around with it when I get a minute.
    – B Layer
    Commented Jun 2, 2020 at 21:08
  • 1
    @D.BenKnoble Finally gave you your due. :D
    – B Layer
    Commented Jun 12, 2020 at 5:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.