Making a custom XML language: trouble with getting Idea to recognize *.tml files as real TML files, instead of just XML

Hello,

The company I work for has a custom XML language called TML, and I am making a TML plugin in Idea.  I have made a TmlFileType that extends XmlLikeFileType so that I can get all the benefiets of XML. I also have a TmlLanguage class that extends XMLLanguage.  The associated Factory class for TmlFileType is registered in the plugin.xml in the <extensions> tag.

Everything mostly works: I get the correct validation from our schemas, the custom TML icon shows up when viewing the file in Idea, etc.  The problem comes when I am trying to create an action that detects if the file is a TML file.  I used the http://www.youtube.com/watch?feature=player_embedded&v=-ZmQD6Fr6KE as a guide.  When I obtain a reference to the PsiFile:

PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE):
if(!(psiFile.getFileType() instanceof TmlFileType))     {
     e.getPresentation().setEnabled(false);
     return;
}

the if condition is false even though it's clearly referring to the TML file.  Using the debugger, I found that the PsiFile getFileType() is returning an XmlFileType and not TmlFileType.  

Is there something else I need to do to get Idea to recognize that my file is a TML file and just an XML file?

Thanks,
Eric

5 comments

DomFileDescription is your friend (worked for me )


/**
* DOM file description for APDL ebimodule files
*/
public class ApdlFileDescription extends DomFileDescription<Module> {
    public ApdlFileDescription() {
        super(Module.class,"module");
    }

    @Override
    public Icon getFileIcon(@Iconable.IconFlags int flags) {
        return ApdlIcons.ApdlLogo;
    }

    @Override
    protected void initializeFileDescription() {
        registerNamespacePolicy(ApdlConstants.EBIMODULE_NAMESPACE_URI, ApdlConstants.EBIMODULE_NAMESPACE_URI);

    }
}



And you have to register it in your plugin.xml:

       <!--  allows IDE to recognize  apdl files only files with correct Namespace URI and root tag are recognized  -->
        <dom.fileDescription implementation="xxxxxxxx.ApdlFileDescription"/>


Now your automatically generated dom modell shall be recognized and used.


0

Thanks for your response.

I'm not sure, though, that my problem has to do with the DOM.  I really don't want my TML file to behave any differently than any other XML file except that Idea knows that it's TML instead of just XML.  I'm not totally sure what DomFileDescription buys me, and I am unsure about its usage.  

I need to be able to call on a PsiFile getFileType() and have it return my TmlFileType instead of XmlFileType.  Unless there's a different way entirely that I should be asking "is this thing I right clicked on a TML file?" that I am unaware of that maybe uses a DomFileDescription.  

Ultimately, what I need is a way of enabling or disabling a custom action in the UI dependent on what file type the thing I'm clicking on is.  So, when I right click my TML file in the project structure tree, I need my custom action to be turned on, and when I right click on any other generic XML file, the custom action is disabled.  I could do a hacky thing where I look at the literal file extension in the name of the PsiFile and check if it's "tml", but that seems like a bad idea.

-Eric

0

I think this is a good question!

The suggestion of using a DomFileDescription willnot alter what getFileType() will return. However - if you did introduce a TmlDomFileDescription class into your codebase you could make use of code similiar to the following

PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE):
boolean isTmlFile =
        psiFile instanceof XmlFile
                && DomManager.getDomManager(project).getDomFileDescription((XmlFile) psiFile) instanceof TmlFileDescription;

if (!(isTmlFile)) {
    e.getPresentation().setEnabled(false);
}



This would achieve what you are after.

If you do plan to do a lot of DOM manipulation within your plugin, I definitely recommend checking out the DomFileDescription class :)

Cheers

0

Thanks for the idea Alan.  At this time we aren't doing any DOM manipulation, but I'll look in to that if we ever do need to.  Your post gave me the idea to look at what else might be more readily available to use as a "what file is this" test.

I haven't been able to figure out how to get the getFileType() to return my custom file type, but I do find that

psiFile.getViewProvidor().getBaseLanguage()

does return an instance of TmlLanguage.  So, although it's still not what I wanted, it does what I need it to do, and will user this as a temporary solution.  This is still pretty gross (violating Law of Demeter and all), but hopefully we'll be able to change it in the future.

-Eric

0

I haven't completely fixed this problem, but the problem is no longer relavent to me.  I'd still be interested in why this was happening this way.  I was trying to make my own right click context menu that would let you create a new run configuration on the fly (the CreateAction).  Turns out all you have to do for that is just implement your own RuntimeConfigurationProducer and register it in the plugin.xml under the <extensions> tag.  Once that's done you get the "create <name>..." right click context menu item for free.  

0

Please sign in to leave a comment.