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!

About these ads

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 Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Blog Stats

  • 177,948 hits

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: