After the last long one, today is a short, but useful tip. There is a % while we are in command mode and that’s the relative path of the currently edited file. We can add some flags to it to make it more useful. Let’s see through some examples.

We can use the file path to call external problems like python3:

:!python3 %

We can use tab completion to edit/create a new test file easily with :e %<tab> and after that we only have to edit the path for example from path/to/module/network.go to path/to/module/network_test.go.

Doing that would be a pain all the time, there are filename modifiers. Here is short list where the edited file is path/to/module/network.go:

  • %:p: Absolute path to the file.
  • %:h: Head of the filename, like the parent directory (path/to/module).
  • %:t: Tail of the filename. The actual filename. (network.go)
  • %:r: Root of the filename, basically removed the last extension. This is useful when we want to save out file with a new extension. (path/to/module/network)
  • %:e: Opposite of %:r, it’s the last extension. (go)
  • %:s?pattern?substitution?: Replaces pattern with substitution. For example: %:s?path/to?new/path? -> new/path/module/network.go.
  • %:gs?pattern?substitution?: Same as %:s?..., but all occurrences.

We can chain them together (where it makes sense). For example if we have a temporary file and we want to save when we are done with it, we can simply manipulate the value to save to the right place.

For this series, I have a blind-draft/aov21/_dayXX.md for each day. That way if I don’t finish it in time, it will not be published accidentally. So when I’m done with a file, I can save it to the right place with with:

:w %:s?blind-draft/aov21?content/posts/advent-of-vim/2021?:s?_??

Because it’s a command, it can be in a map, and it’s in the command history and I have to change nothing because it preserves the day number.