I often find myself opening Vim in the root of a Git repository, then opening a file and wanting to open another file in that same directory. I’ve created a shortcut to help with that action.

Let’s say I’m editing a blog post in Hugo. I like to keep the editor open in the root of the repository, and then open a post file:

$ vim content/posts/git-grepblame.md

Once I’m editing that file, I’d like to look at another post. To do that, I likely end up using tab completion to both get to the same path as the current file, and then later to pick which file I’d like to open, i.e.:

:e con<TAB>
:e content/p<TAB>
:e content/posts

I’m then finally able to go seek files in that directory, i.e:

:e content/posts/<TAB>
:e content/posts/git-<TAB>
:e content/posts/git-garbage-collect-all-repositories.md<CR>

I’d like to avoid the first part - so I’ve created a couple shortcuts which help with this, and a similar, situation:

" Make %% in command mode expand to the current file's path
cnoremap <expr> %% getcmdtype() == ':' ? expand('%:p:h').'/' : '%%'

Mnemonic: % stands for the current buffer’s file name, so %% is related (the current file’s directory).

With the above command mapping, all I have to do is now:

:e %%

Having done that, the path to the current buffer’s file is pre-populated, and I can either continue to tab-complete files in the same directory, or add/remove chunks from the path and go seek files in parent directories.


Other times, I’m instead looking for same-named files with different extensions. An example might be when editing a path/to/foo.dot file and wanting to open the corresponding path/to/foo.png output image, or a path/to/foo.t.tt template file and it corresponding path/to/foo.t.out output file.

For those cases, I’ve introduced another mapping:

" Make ^^ in command mode expand to the file, sans extension
cnoremap <expr> ^^ getcmdtype() == ':' ? expand('%:p:r') : '^^'

Mnemonic: ^ stands for the alternate file name, so ^^ stands for an alternate file’s property - its basename.

With the above, hitting ^^ in the command line expands to the current file name, sans extension.

:e ^^.png
:e ^^.out