MultiplePsiFilesPerDocumentFileViewProvider for 3 languages
I have created lexers and parsers for 2 of my languages. It is necessary that each of the languages supports tags of the other and HTML. I implemented MultiplePsiFilesPerDocumentFileViewProvider class for one of my languages.
public class ModxFileViewProvider extends MultiplePsiFilesPerDocumentFileViewProvider implements TemplateLanguageFileViewProvider {
private static final Logger LOG = Logger.getInstance(ModxFileViewProvider.class);
private static Pattern xmlContentType = Pattern.compile("^\\{contentType [^}]*xml[^}]*}.*");
public static ModxOuterElement OUTER_MODX = new ModxOuterElement("Outer Modx");
public static FenomOuterElement OUTER_FENOM = new FenomOuterElement("Outer Fenom");
private static IElementType templateDataElement = new TemplateDataElementType(
"HTML/XML in Modx",
ModxLanguage.INSTANCE,
ModxTokenTypes.T_TEXT,
OUTER_MODX
);
private static IElementType fenomDataElement = new TemplateDataElementType(
"Fenom in Modx",
ModxLanguage.INSTANCE,
ModxTokenTypes.T_FENOM,
OUTER_FENOM
);
public ModxFileViewProvider(PsiManager manager, VirtualFile virtualFile, boolean eventSystemEnabled) {
super(manager, virtualFile, eventSystemEnabled);
}
@NotNull
@Override
public Language getBaseLanguage() {
return ModxLanguage.INSTANCE;
}
@NotNull
@Override
public Set<Language> getLanguages() {
Set<Language> languages = new HashSet<>();
languages.add(ModxLanguage.INSTANCE);
languages.add(FenomLanguage.INSTANCE);
languages.add(getTemplateDataLanguage());
return languages;
}
@Override
protected MultiplePsiFilesPerDocumentFileViewProvider cloneInner(VirtualFile fileCopy) {
return new ModxFileViewProvider(getManager(), fileCopy, false);
}
@NotNull
@Override
public Language getTemplateDataLanguage() {
return isXml() ? XMLLanguage.INSTANCE : HTMLLanguage.INSTANCE;
}
@Nullable
protected PsiFile createFile(@NotNull Language lang) {
ParserDefinition parser = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
if (parser == null) {
return null;
} else if (lang == XMLLanguage.INSTANCE || lang == HTMLLanguage.INSTANCE) {
PsiFileImpl file = (PsiFileImpl) parser.createFile(this);
file.setContentElementType(templateDataElement);
return file;
} else if (lang == FenomLanguage.INSTANCE) {
PsiFileImpl file = (PsiFileImpl) parser.createFile(this);
file.setContentElementType(fenomDataElement);
return file;
} else {
return lang == this.getBaseLanguage() ? parser.createFile(this) : null;
}
}
private boolean isXml() {
String text = getContents().toString();
int pos = text.indexOf("\n");
if (pos > 0) {
text = text.substring(0, pos);
}
return xmlContentType.matcher(text).matches();
}
}
But I encountered a problem that error information for Fenom tags is not displayed if TemplateDataElementType is specified for Fenom language.
private static IElementType fenomDataElement = new TemplateDataElementType(
"Fenom in Modx",
ModxLanguage.INSTANCE,
ModxTokenTypes.T_FENOM,
OUTER_FENOM
);
If you don't specify it, the error information is displayed, but then Commenter for Modx language doesn't work correctly because it is called from Fenom for some reason.
Each language works correctly individually
Please sign in to leave a comment.