10

Related to Bash-like partial tab-complete for filenames in Vim

One of the truly fantastic features of zsh is that you can type, for example, ls /u/s/m/m/who.1, press Tab and have it complete to ls /usr/share/man/man1/who.1.gz. Once you get used to it, it's really annoying to to go back to /u<tab>/s<tab>/m<tab>/m<tab>..., especially when the entire partial path can only resolve to one actual path, but each individual component may have multiple completions. Can this be achieved in Vim, for example, when using :e or :cd?

There are other useful path-related features in zsh, such as using cd foo bar to move to an equivalent path with foo replaced with bar (i.e., /blah/foo/baz/yada becomes /blah/bar/baz/yada). If there's a solution that brings in these as well (essentially handing over shell-related tasks to a shell that does those very well), it would be great.

  • 1
    I'm not aware of anything that achieves precisely what you're asking, but there's various fuzzy-file finders that allow you to open files in a similar way. I favour CtrlP, but there's also Command-T and I'm sure there's others I'm forgetting the name of. – Rich Feb 10 '15 at 9:56
  • 1
    @Rich As long as I don't have to mash Tab a dozen times, I'd be happy. – muru Feb 10 '15 at 9:57
  • There is already a similar question on SO. – romainl Feb 11 '15 at 9:12
6

I used to use CtrlP and other related plugins heavily earlier until I truly discovered the native powers of vim. Let me explain a few ways of doing this without requiring an external plugin :

  1. :e, the nice thing about :e is you can do something like :e /u*/s*/m*/m*/<Tab> and vim will expand that automatically for you to :e /usr/share/man/man. That is much shorter and simple than what you posted, but an even better way is to do :e /usr/**/man<Tab>, that way it will look recursively under /usr and list out all matching paths, this can take time though depending on how large the set is, but in a project this works wonders because you can do something like :e ap**/jav**/user<Tab> and it will complete all incomplete paths and give you a list of matching paths and works super great.
  2. :b, To open existing buffers. This is really powerful because it accepts partials by default so you can just do something like :b usr*man<Tab> and it will complete the file name if it's already been loaded in the buffer list. This is especially good because it's near instant and really fast. Also I use vim sessions heavily, with the help of tpope/vim-obsession and dhruvasagar/vim-prosession, that keeps all the files I open in the buffer list and they are available even if I exist vim and come back to it from the project directory.
  • 1
    /u*/s*/m*/m*/<Tab> is how I used to work around bash. It's not a substitute for zsh by a mile. /usr/**/man<Tab> is horrendously slow when you have the whole filesystem open, but might be useful for small projects. Unless I misunderstand :b, it's not for opening new files. – muru Feb 10 '15 at 17:47
  • @muru you're right, it's not a substitute to zsh but it's still better than having to type the whole thing yourself, it's about making it easier, ** is horrendously slow indeed, but works good for regular projects. :b is for existing open buffer, that's why using sessions helps. – Dhruva Sagar Feb 10 '15 at 17:56
5

vim-zsh-path-completion purports to do exactly what you're asking for (the first part, at least), but I have never tried it. (I hadn't even heard of it until romainl linked to an SO answer by its author, although its documentation does also mention several limitations.

In addition to this, there are various fuzzy-file finders that achieve something similar for opening files.

My favoured plugin for this is CtrlP. When used for opening files, it searches for any files whose full paths contain the characters that you type in in the correct order—you don't have to type in parts of every component of the path (and all the path separators) as you have in your example, but it works perfectly well if you do. It also uses the same interface for opening recently used files and currently open buffers, and more besides.

By default, it maps <c-p> in normal mode to open the CtrlP prompt. The prompt displays a list of files, which is narrowed down as you type in characters. You can press Enter at any point to open the currently selected file, or use <c-k> and <c-j> to move the selection up and down through the list of currently-matched files.

Another popular alternative is Command-T, but I favour CtrlP because it's implemented in VimScript; Command-T has a Ruby component.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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