Imediava's Blog

Just another WordPress.com site

Using Eclipse completion features in your own plug-in

One of the coolest things I found when I first moved to Eclipse was code completion. It was useful and pretty, it allowed me to save typing and it provided useful information in a visually appealing way.

When you’re developing your own plugin for Eclipse you want it to be as cool as possible, so using Eclipse code completion system may come to your mind.

However I could not find many examples online about how to benefit from the system from a plugin developer’s perspective. This post is my try to facilitate the task of familiarizing with the tool. It’s an extension from some of the few links I’ve found with useful and simple information about the subject (http://www.eclipsezone.com/eclipse/forums/t83426.html) .

As the link says, it’s really easy to add content assistance to a text field. Just the following two lines do the trick:

Text t = new Text(parent, SWT.BORDER) // your SWT text field
ContentProposalAdapter adapter = new ContentProposalAdapter( t,
	new TextContentAdapter(),
	new SimpleContentProposalProvider(new String [] {"A", "B", "C"}),
	null,  null)

However there’s a few things that we can modify in the example to give the proposals a better, more Eclipse-like behaviour. The code for the examples is going to be coded with groovyMonkey but translating it to Java it’s fairly simple.

First thing I want to change is the filtering behaviour. With the code from the first example the suggestion is not affected by a change in the text field content. However when developing a plugin what we usually want is that only the proposals that match the typed text are shown. This can be modified enabling the filtering for the proposals provider:

proposalsProvider = new SimpleContentProposalProvider(proposals)
proposalsProvider.setFiltering(true)

The next behaviour we can replace is the way the proposals accepted are handled. The default behaviour is appending the proposal text to the text field content, but that’s not the way we usually want our assistant to behave. What we usually want is to set the selected proposal as the current text for the field. To get that, all we have to do is modify the “acceptance style” to PROPOSAL_REPLACE:

adapter = new ContentProposalAdapter( nameText,  new TextContentAdapter(), proposalsProvider, null,  null)
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE)

A bigger example

Finally I’m gonna show how the whole code works in a bigger example. Thanks to groovyMonkey features, playing with Eclipse API is quite easy. I’m gonna use this features to take the names of all the user-defined types in the workspace. This can be done using groovyMonkey with the following snippet:

List types = []
workspace.root.projects.each { project ->

   //selects only the java projects
   if (project.isOpen() && project.isNatureEnabled("org.eclipse.jdt.core.javanature")){
 	   javaProject = JavaCore.create(project)
	   roots = javaProject.getPackageFragments()

	   // Filters the source code packages
	   .findAll{ fragment -> fragment.getKind() == IPackageFragmentRoot.K_SOURCE}

	   .each { fragment ->
	 	    fragment.compilationUnits.each { compilationUnit ->

	 	        for(type in compilationUnit.getAllTypes()){
	 	        	types.add(type.getElementName())
	 	        }
	 	    }

	   }

   }
}

Now I can create a really simple wizard with a text field that uses all the code completion features I have talked about in the post. When the content of the field is modified it suggests user-defined types from the workspace.

/*
 * Menu: CodeCompletion
 * Script-Path: /GroovyMonkeyScripts/propios/CodeCompletion.gm
 * Kudos: imediava
 * License: EPL 1.0
 * Job: UIJob
 */

def wizardDialog1

import org.eclipse.swt.widgets.Text;

import org.eclipse.jface.fieldassist.ContentProposalAdapter
import org.eclipse.jface.fieldassist.SimpleContentProposalProvider
import org.eclipse.jface.fieldassist.TextContentAdapter

import org.eclipse.core.resources.*
import org.eclipse.jdt.core.IPackageFragmentRoot
import org.eclipse.core.runtime.Path
import org.eclipse.jdt.core.JavaCore

List types = []
workspace.root.projects.each { project ->

   //selects only the java projects
   if (project.isOpen() && project.isNatureEnabled("org.eclipse.jdt.core.javanature")){
 	   javaProject = JavaCore.create(project)
	   roots = javaProject.getPackageFragments()

	   // Filters the source code packages
	   .findAll{ fragment -> fragment.getKind() == IPackageFragmentRoot.K_SOURCE}

	   .each { fragment ->
	 	    fragment.compilationUnits.each { compilationUnit ->

	 	        for(type in compilationUnit.getAllTypes()){
	 	        	types.add(type.getElementName())
	 	        }
	 	    }

	   }

   }
}

mainapp = jface.shell( window.getShell()) {

	wizardDialog1 = wizardDialog() {

				wizardPage1 = wizardPage( title:"Step 1", description:"Step 1", closure: { parent ->

					jface.composite( parent ) {
						gridLayout( numColumns : 2, verticalSpacing: 20)

						label( text: "Name" )
						nameText = text(style: "border")

						proposals = types.toArray(new String[0])
						proposalsProvider = new SimpleContentProposalProvider(proposals)
						proposalsProvider.setFiltering(true)
						adapter = new ContentProposalAdapter( nameText,  new TextContentAdapter(), proposalsProvider, null,  null)
						adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE)
					}
				})
	}

  	wizardDialog1.open()

	wizardPage1.setPageComplete(false)
}

I’ll leave for following posts other changes that can improve the assistant’s look and behaviour like adding icons next to every proposal.

Advertisements

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

%d bloggers like this: