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