Search code examples
javaeclipseeclipse-plugineclipse-cdt

Use own CodeFormatter in eclipse plugin with CDT


I'm trying to make use of the extension point org.eclipse.cdt.core.CodeFormatter but it seems to have no effect. Unfortunately I cannot find any example. The extension point description isn't very comprehensive.

My plugin.xml looks like this:

<extension
     point="org.eclipse.cdt.core.CodeFormatter">
  <codeFormatter
        class="de.verified.rtt.ide.editors.rts.RTTLCodeFormatter"
        id="de.verified.rtt.ide.editors.rts.codeformatter"
        name="RTTL Code Formatter">
  </codeFormatter>

This extension is on top level. Maybe it has to inside a language, file association, perspective or something else?

Detailed problem description:

In my plugin I'm using a language that extends C++ with some keywords and concepts. To parse this file I'm writing my own Source Parser that extends GNUCPPParser. At the moment my parser creates standard IASTDeclarations for tokens that unknown to CDT. E.g for "@rttConcept{...}" my parser uses a "ICPPASTNamespaceDefinition" because @rttConcept is in a way similar to a namespace definition. Now using "@rttConcept" doesn't create syntax error highlightings in the editor anymore. When trying to format this code using the CodeFormatter an exception is thrown

org.eclipse.cdt.internal.formatter.AbortFormatting: [1/1] Unexpected token type, expecting:91, actual:Token type=1006 image =@ offset=0 at org.eclipse.cdt.internal.formatter.Scribe.printNextToken(Scribe.java:1653)

There is a check whether the NamespaceDefinition really corresponds to the token "namespace" in the code which it doesn't. I only want to use my own CodeFormatter to catch the AbortFormatting exception:

@SuppressWarnings("restriction")
public class MyCodeFormatter extends CCodeFormatter {

    public static final String ID = "de.blub.rtt.ide.editors.rts.codeformatter";

    @Override
    public TextEdit[] format(int kind, String source, IRegion[] regions, String lineSeparator) {
        try {
            return super.format(kind, source, regions, lineSeparator);            
        } catch(AbortFormatting ex) {
            return null;
        }
    }
}

Solution

  • Declaring your formatter in plugin.xml just makes it available as a formatter.

    If you want to use it as the current formatter, you have to select it in the preferences UI (Preferences -> C/C++ -> Code Style -> Formatter, there should be a drop-down with your formatter's name as one of the options).

    (The above selection affects the entire workspace. You can also choose a formatter on a per-project basis in Project Properties -> C/C++ General -> Formatter.)

    That said, note the caveat in greywolf82's comment.


    UPDATE: To answer your comment, yes, I believe the current formatter can be changed programmatically via CDT's public API. I would expect something like the following to work:

    HashMap<String, String> options = CCorePlugin.getOptions();
    options.put(CCorePreferenceConstants.CODE_FORMATTER,
                "de.verified.rtt.ide.editors.rts.codeformatter");
    CCorePlugin.setOptions(options);