LanguageSubstitutor can't override user file types

By default, in Project Settings > File Types, there exists an association of .hs files with Haskell files, which provides some simplistic, default syntax highlighting and completion.

There are two different IntelliJ plugins that may want to register an .hs file: IntelliJ-Eta and HaskForce. As such, I don't want both to try, I want them to be able to figure this out based on some project metadata, possibly due to the existence of a Eta or Haskell facet in the project.

LanguageSubstitutors seem to be a way to handle this; however, if the File Types has an association of .hs files with (built-in) Haskell files, then the LanguageSubstitutors don't seem to apply to it. Only when I remove the .hs file type association will the substitutor catch it and apply language substitution.

Is there any way around this? I am considering having the plugin auto-remove the association, but that seems like a big hack.

0

Indeed, by default, built-in FileType for Haskell files (*.hs) is com.intellij.openapi.fileTypes.impl.AbstractFileType and com.intellij.lang.LanguageUtil#getFileLanguage returns null for files with such types. Since com.intellij.psi.LanguageSubstitutor#getLanguage accepts not-null Language instances, it is not invoked for these files.

You can register your own FileType (implementing LanguageFileType) for *.hs files (via com.intellij.openapi.fileTypes.FileTypeFactory) to override built-in AbstractFileType. As a result, LanguageSubstitutor will be invoked for *.hs files as expected.

1
Avatar
Permanently deleted user

Will it cause conflicts if two different plugins define a LanguageFileType for *.hs files? The goal here is just to find a way to allow the two plugins to coexist peacefully.

0

Seems there shouldn't be conflicts. However, since it's unpredictable what LanguageFileType instance will be used as FileType for *.hs files, an icon shown for *.hs files will also be unpredictable. Also, any plugin code depending on a FileType instance provided by the plugin won't work correctly if a FileType from other plugin will be used for *.hs files. Looks like other things should work. Here LanguageSubstitutor should be registered with language ID provided by other plugin:

<lang.substitutor language="<haskell lang ID of other plugin>" implementationClass="package.MySubstitutor"/>
0

请先登录再写评论。