Augmenting filetype detection for supplemental types

12 views
Skip to first unread message

Rob Foehl

unread,
Feb 25, 2023, 9:13:48 PM2/25/23
to vim...@googlegroups.com
Attempting to set multiple filetypes based on something like

autocmd FileType foo if ... | set filetype=foo.bar | endif

seems to have an ordering problem with the FileType autocmd that sets
'syntax' -- the "foo.bar" filetype is set, requisite files for "bar" are
loaded, and then the autocmd waiting on the original expansion of <afile>
to "foo" runs and effectively resets the syntax.

Is there a way to tack on a supplemental filetype without running into
this problem? The obvious approach of setting the whole string at once
works, but that requires duplicating everything that could otherwise
determine the initial filetype...

-Rob

Bram Moolenaar

unread,
Feb 26, 2023, 9:48:05 AM2/26/23
to vim...@googlegroups.com, Rob Foehl
It's hard to think of an elegant way to deal with this. Once the
FileType event is triggered, it would normally find all matching
autocommands and execute them. Changing the value halfway makes it
unpredictable, easily leading to weird errors.

One way would be to not change 'filetype' directly but set a timer with
a very short timeout to do it later. This can already be done now, you
can try it out. Obvious disadvantage is that all the
indent/syntax/ftplugin files will be sourced twice.

A specific way to handle this would be to add a FileTypePre event, which
would be triggered first and allow for changing 'filetype'. Hmm,
perhaps we would also need this for the Syntax event?
This would be a very specific solution, do we really need it?

--
hundred-and-one symptoms of being an internet addict:
182. You may not know what is happening in the world, but you know
every bit of net-gossip there is.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Rob Foehl

unread,
Feb 27, 2023, 12:50:42 AM2/27/23
to vim...@googlegroups.com
On Sun, 26 Feb 2023, Bram Moolenaar wrote:

> One way would be to not change 'filetype' directly but set a timer with
> a very short timeout to do it later. This can already be done now, you
> can try it out. Obvious disadvantage is that all the
> indent/syntax/ftplugin files will be sourced twice.

Yeah, this works:

autocmd FileType foo if ... | call timer_start(0, {_ -> execute('set filetype=foo.bar', '')}) | endif

...assuming one can live with the double inclusion, which had tripped me
up the first time I'd tried this. Also attempted were various hacks
in {,after/}ftplugin/foo/, with mixed results.

(Aside: a time of 0 isn't explicitly documented, but seems to work as
expected, i.e. meaning something like "next tick"...)

> A specific way to handle this would be to add a FileTypePre event, which
> would be triggered first and allow for changing 'filetype'. Hmm,
> perhaps we would also need this for the Syntax event?
> This would be a very specific solution, do we really need it?

That'd be cleaner... Whether it's really needed, I'm not sure. I'm
pretty far down the rabbit hole of trying to mix syntaxes in particular --
see other thread on extend causing trouble -- but not far enough to have a
solid grasp on whether there's a better way, or what that would be.

I've found a lot of existing workarounds -- the @htmlPreproc cluster, the
near-copy of HTML in PHP, the dynamic inclusions in Markdown/RST/others --
and having hacked up another, none seem all that satisfying.

-Rob
Reply all
Reply to author
Forward
0 new messages