10
Jun
09

How to use the eclipse code formatter from your code



I was wondering if I could use the Eclipse Code Formatter from inside my code … so, the logical thing to do was to ask on stackoverflow, and see if anyone knew how to do that. Thanks to VonC‘s answer, I found out about the CodeFormatter class … and 10 jars and 2 hours later, I’ve got it working.

Here’s how I did it.

CodeFormatter is an abstract class, which means you can’t instantiate it directly. So, I started to search about classes derived from it, and so I found out about DefaultCodeFormatter, which I presumed was what I was looking for. I was right.

DefaultCodeFormatter implements the method :


public abstract TextEdit format(int kind,
                                String source,
                                int offset,
                                int length,
                                int indentationLevel,
                                String lineSeparator)

Method documentation can be read  here.

I wrote the following code to test it :


... main(String[] args) {
   String code = "public class geo{public static void main(String[] args){System.out.println(\"geo\");}}";
   CodeFormatter cf = new DefaultCodeFormatter();
   TextEdit te = cf.format(CodeFormatter.K_UNKNOWN, code, 0,code.length(),0,null);
   System.out.println(te);
}

I used the CodeFormatter.K_UNKNOWN constant for the formatting, because I was thinking that the CodeFormatter will “deduce” the type of code I’ve passed it. I’m not really sure what K_UNKNOWN does, but it seems to work well with the code I’ve tried.

So … the DefaultCodeFormatter returned a TextEdit object as the result of the code formatting.
I was kind of hoping that it’s toString method would give me the code. Instead, I found out it had several ReplaceEdit children nodes. I tried to iterate over each of the children and print their text using their getText, but they wouldn’t “show me the code” 🙂 . I thought “TextEdit’s apply method sounds interesting. Let’s see what it does”. Checking it’s method signature :

apply(IDocument document) 

revealed a IDocument parameter. I was hoping it would be easy to create a Document object, and that I wouldn’t need any other “eclipse objects”. Turns out it was easy. There is a Document implementation, that has a String constructor :

Document(String initialContent)

I applied the TextEdit to the document, and hoped for the best. The eclipse console printed out nicely formatted code. WIN !

Here’s the full code for the class I used to test the CodeFormatter :


import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;


public class FormatterTest {

	public static void main(String[] args)
	{
		String code = "public class geo{public static void main(String[] args){System.out.println(\"geo\");}}";
		CodeFormatter cf = new DefaultCodeFormatter();
		
		TextEdit te = cf.format(CodeFormatter.K_UNKNOWN, code, 0,code.length(),0,null);
		IDocument dc = new Document(code);
		try {
			te.apply(dc);
			System.out.println(dc.get());
		} catch (MalformedTreeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadLocationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}	
}

Here’s the list of jars I had to add to the classpath to get the code formatter to work :

  1. org.eclipse.jdt.core_3.4.4.v_894_R34x.jar
  2. org.eclipse.text_3.4.0.v20080605-1800.jar
  3. org.eclipse.core.runtime_3.4.0.v20080512.jar
  4. org.eclipse.osgi_3.4.3.R34x_v20081215-1030.jar
  5. org.eclipse.equinox.common_3.4.0.v20080421-2006.jar
  6. org.eclipse.core.resources_3.4.2.R34x_v20090126.jar
  7. org.eclipse.core.jobs_3.4.1.R34x_v20081128.jar
  8. org.eclipse.core.contenttype_3.3.0.v20080604-1400.jar
  9. org.eclipse.osgi.services_3.1.200.v20071203.jar
  10. org.eclipse.equinox.preferences_3.2.201.R34x_v20080709.jar

They may have different versions on your eclipse installation. They worked for my eclipse installation :


Version: 3.4.2
Build id: M20090211-1700

One of those jars isn’t needed, but I can’t remember which. Sorry for the extra classes.

Hope this helps anyone!


11 Responses to “How to use the eclipse code formatter from your code”


  1. June 11, 2009 at 08:02

    Hi

    Just my 2 cents:
    – DefaultCodeFormatter is internal, see org.eclipse.jdt.core.ToolFactory.createCodeFormatter
    – K_UNKNOWN does probe the type to format, see DefaultCodeFormatter.probeFormatting, of course this has a performance impact.

  2. October 15, 2009 at 00:01

    I like the eclipse source code formatter, but I do not like the idea of include a lot of libraries, so I suggest to try the open source project jastyle, a 100% pure java port of the astyle. It is very small (<70Kb) and it could be integrated easily. http://sourceforge.net/projects/jastyle/ . It does not use any additional library.

    It is not the most sophisticated library, but It works pretty well.

    Best regards,

    Barenca.

    • 4 geo
      October 15, 2009 at 09:34

      Cool! I know the Eclipse formatter uses a lot of libs, which can become pretty hard to manage. The simpler the better!
      I’m definitely going to try it out!

      Thanks!

  3. 5 jecki
    May 1, 2010 at 15:38

    Hi

    Your article has inspired me to create a maven plugin. Can I put a link to this page in my project page?

    Thanks,
    Jecki

  4. 9 Bill
    May 28, 2010 at 11:49

    thanks alot! for java 1.5 and greater, this worked for me.

    Map options=new TreeMap();
    options.put(org.eclipse.jdt.core.JavaCore.COMPILER_SOURCE, “1.5”);
    options.put(org.eclipse.jdt.core.JavaCore.COMPILER_COMPLIANCE, “1.5”);
    options.put(org.eclipse.jdt.core.JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, “1.5”);
    CodeFormatter formatter = org.eclipse.jdt.core.ToolFactory.createCodeFormatter(options);

    of course you could read your eclipse props in too.


Leave a comment


Blog Stats

  • 281,728 hits