The documentation says:

<afile>    When executing autocommands, is replaced with the file name
           for a file read or write.
<abuf>     When executing autocommands, is replaced with the currently
           effective buffer number (for ":r file" and ":so file" it is
           the current buffer, the file being read/sourced is not in a
<amatch>   When executing autocommands, is replaced with the match for
           which this autocommand was executed.  It differs from
           <afile> only when the file name isn't used to match with
           (for FileType, Syntax and SpellFileMissing events).

Yet, if I had this autocmd:

autocmd BufNewFile * echo expand('<amatch>') expand('<afile>')

And opened, say .zshrc in /tmp (cd /tmp; vim .zshrc), I get:

/tmp/.zshrc .zshrc

They are not the same. What's going on?

% is faithful to what I actually typed. vim ./.zshrc with expand('%') added to the above autocmd gives me:

/tmp/.zshrc .zshrc ./.zshrc
  • Do you think the difference can be that <afile> is only the filename whereas <amatch> is the complete path for the file ?
    – nobe4
    Aug 26 '15 at 6:39
  • @Nobe4 yes, that's always how it turns out. %, however, is faithful to whatever I actually mentioned. But I'm not sure I can trust % here. :/
    – muru
    Aug 26 '15 at 6:40
  • If you type vim /tmp/.zshrc they're the same strings. If your cwd is /tmp you will get an absolute path, and a relative path, and while they are not the same strings, they are the same paths. Aug 26 '15 at 6:40
  • @Carpetsmoker I typed just plain vim .zshrc
    – muru
    Aug 26 '15 at 6:41
  • In expand you can have : expand('<amatch>') == expand('%:p') and expand('<afile>') == expand('%') . What do you think ? Edit: Just saw your edition, the expand('<afile>') == expand('%') doesn't apply anymore
    – nobe4
    Aug 26 '15 at 6:43

<amatch> is exactly what is matched against the autocmd pattern. For autocmds that match filenames, symlinks are resolved, the result is canonicalized, and the full path is returned.

<afile> is the canonical full path as above, but the result is also shortened, which is essentially the same as fnamemodify(file, ':.') (the exact details are more involved, but the preceding description is accurate for all "normal" cases).

Thus, in general expand('<afile>') == expand('<amatch>:.') (edit: provided, of course, that they do refer to the same thing).

  • That seems to be the behaviour, yes. But do you have anything to support this answer?
    – muru
    Aug 26 '15 at 13:06
  • 3
    @muru: You mean, other than my good looks and my perfect smile? ;) Yeah, I think I do: <afile> and <amatch> sources. Aug 26 '15 at 13:13
  • In general, afile is not the same as amatch, as it can quite be different depending on the autocommand event. Aug 26 '15 at 16:26
  • 2
    @ChristianBrabandt Yes. The point of the question is, they can still be different for autocmds where <afile> and <amatch> do refer to the same thing (namely, to a file), contrary to what the manual implies. My answer explains how and why they differ in that particular case. Better now? :) Aug 26 '15 at 17:42

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.