7

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
           buffer).
<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
muru
  • 24,838
  • 8
  • 82
  • 143
  • 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 06: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 06: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. – Martin Tournoij Aug 26 '15 at 06:40
  • @Carpetsmoker I typed just plain vim .zshrc – muru Aug 26 '15 at 06: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 06:43
  • I'm not absolutely sure but isn't <amatch> the pattern match of the autocmd? If you use BufNewFile it will be the filename; apparently absolute from your examples. For FileType it should then be the matched file type: zsh for your example if you replace BufNewFile with FileType. – tokoyami Aug 26 '15 at 10:14
  • @tokoyami (mostly) yes. The question is, why does <amatch> differ from <afile> in cases other than those specified in the docs? So, FileType is pretty much irrelevant. – muru Aug 26 '15 at 10:17
  • @muru Ah, got it. – tokoyami Aug 26 '15 at 10:40

1 Answers1

8

<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).

Sato Katsura
  • 4,009
  • 17
  • 24
  • 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: and sources. – Sato Katsura 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. – Christian Brabandt 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? :) – Sato Katsura Aug 26 '15 at 17:42