The current Eclipse plugin I am working on is, of course, much more complex than this, but I thought it would be nice to share how to make a simple Eclipse plugin that processes the selected text or text in the current file in the editor. Do the following steps first before we proceed to the coding portion:
- Create a new plugin project in Eclipse
- Open the MANIFEST.MF and click on Overview tab. Update the plugin information on version and put in your name in Provider. Tick the “This plug-in is a singleton” checkbox.
- Click on Dependencies tab and add in the following Required Plug-ins (if it isn’t there yet). The jar files of these plug-ins will be made available in your project automatically, so if you encounter unresolved imports for Eclipse API, you might have missed an entry here.
- org.eclipse.ui
- org.eclipse.core.runtime
- org.eclipse.jface.text
- org.eclipse.ui.editors
- Click on Extensions tab and under All Extensions, click on the Add button. Add “org.eclipse.ui.popupMenus” and save the MANIFEST.MF file. You should see the plugin.xml file being added to the project.
- Open the plugin.xml file and add the following entries. These entries will add in the context menu for the editor and link the menu item to a class in your plugin. You can refer to the Eclipse API documentation for more details.
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<!-- add to pop menu -->
<extension point="org.eclipse.ui.popupMenus">
<!-- add to editor context menu -->
<objectContribution
id="Plugin.EditorContribution"
objectClass="org.eclipse.ui.IEditorInput"
nameFilter="*.*">
<!-- add a menu item call "Plugin" -->
<menu
label="Plugin"
path="additions"
id="Plugin.EditorMenu">
<separator
name="group">
</separator>
</menu>
<!-- add a sub menu item called "Do Stuff" -->
<!-- that calls the class plugin.actions.DoStuff -->
<action
label="Do Stuff"
class="plugin.actions.DoStuff"
menubarPath="Plugin.EditorMenu/group"
enablesFor="1"
id="Plugin.DoStuffAction">
</action>
</objectContribution>
</extension>
</plugin>
Now, create a new package under src named “plugin.actions”, by default, there should be an existing package called “plugin” containing the Activator.java file. Create a new file under “plugin.actions” called “DoStuff.java” implementing the interface “IObjectActionDelegate”. Next, add in the following code.
package plugin.actions;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import plugin.Activator;
/**
* Sample code template for editor context menu
* and editor text selection or file text processing.
* @author augustli
*/
public class DoStuff implements IObjectActionDelegate {
private static final String TITLE = "Do Stuff";
private static final int TEXT_REPLACE_ALL = 0;
private static final int TEXT_REPLACE_SELECTED = 1;
private static final int TEXT_INSERT = 2;
private int textOutputMode = 0;
private String textOutput = null;
private Shell shell;
/**
* Constructor
*/
public DoStuff() {
super();
}
/**
* Get the shell object for use in prompting error message.
* @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
*/
@Override
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
shell = targetPart.getSite().getShell();
}
/**
* Get the selection text or text for whole file
* and pass it to process for modification.
* @see IActionDelegate#run(IAction)
*/
@Override
public void run(IAction action) {
try {
//get active editor
IEditorPart editorPart = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow()
.getActivePage().getActiveEditor();
if (editorPart instanceof AbstractTextEditor) {
//check if there is text selection
int offset = 0;
int length = 0;
String selectedText = null;
IEditorSite iEditorSite = editorPart.getEditorSite();
if (iEditorSite != null) {
ISelectionProvider selectionProvider = iEditorSite.getSelectionProvider();
if (selectionProvider != null) {
ISelection iSelection = selectionProvider.getSelection();
offset = ((ITextSelection) iSelection).getOffset();
if (!iSelection.isEmpty()) {
selectedText = ((ITextSelection) iSelection).getText();
length = ((ITextSelection) iSelection).getLength();
}
}
}
ITextEditor editor = (ITextEditor) editorPart;
IDocumentProvider dp = editor.getDocumentProvider();
IDocument doc = dp.getDocument(editor.getEditorInput());
//do processing here
process(selectedText, doc.get());
//if null is returned, do not replace text in editor
if (textOutput != null) {
if (textOutputMode == TEXT_REPLACE_ALL) {
doc.replace(0, doc.getLength(), textOutput);
} else if (textOutputMode == TEXT_REPLACE_SELECTED && selectedText != null) {
doc.replace(offset, length, textOutput);
} else {
doc.replace(offset, 0, textOutput);
}
}
}
} catch (Exception e) {
MessageDialog.openError(shell, TITLE, e.getMessage());
}
}
/**
* Selected text or text for the whole file
* will be pass as parameter for processing.
* @param selectedText Selected text, if any, otherwise null.
* @param editorText All text in editor.
*/
private void process(String selectedText, String editorText) {
//add your own code here to modify text here before returning it
//you must set two class variables as output,
//choose one from the following:
//To replace selected text, if there is no selection,
//text will be inserted instead
textOutputMode = TEXT_REPLACE_SELECTED;
textOutput = "Replacement text here";
//To replace all text in editor
textOutputMode = TEXT_REPLACE_ALL;
textOutput = "This will replace all text in editor.";
//To insert text at current cursor position
textOutputMode = TEXT_INSERT;
textOutput = "Text to insert";
//To do nothing, return null for textOutput
textOutput = null;
}
/**
* Skip implementation
* @see IActionDelegate#selectionChanged(IAction, ISelection)
*/
@Override
public void selectionChanged(IAction action, ISelection selection) {
}
}
In the code, we get an instance of the editor and check if there is any selected text. If found, then the selected text is passed to the process method along with the text for the whole file. The textOutputMode and textOutput must be set the process method in order to either inserttext in the current position, replace the selected text, all the text in the editor or do nothing.
[August Li] 12-16-2010 Updated code to be able to insert text.
Thanks for sharing this, I’m starting with Eclipse plugin development and had been struggling to find out how to handle text in the current file in the Editor. You just saved a Brazilian’s internship in France
No problem, glad to know I was able to help someone through my blog
This is awesome, thanks the example!
Thanks a lot …it was very useful to start plugin development. Please do Post other Plugin related stuffs.
HI,
Thanks for your example.I am trying to add context menu to Java editor.But i am not able to get exact object class for java editor.But your example helped me to add context menu.Thanks for your example.
You have any example to hoe to get cursor location,i need to add some test based on cursor location
I updated the code to be able to insert text.
Thank you very much to shred light into this. I an new to Eclipse plug-in development and it would have been taking long time to figure this out myself.
Thanks for your example, it’s gonna help me a lot
Really cool example!!!
I tryed your code and its prima!.
I have a prob and maybe you know why, i have two actions in the contexmenu but for some reason they just apear in one editor, I want it to apear in all the open editors.
Your example does that and I dont know where to define it, I mean, the only thing I have diferent is that I have no group my 2 actions are directly in the additions.
are the editors of the same type or class? maybe the class isn’t org.eclipse.ui.IEditorInput? other than that, i can’t think of other reasons without actually debugging your code, which i can’t do at this time
I got what I did wrong:
in org.eclipse.ui.popupMenus instead of adding a ObjectContribution I added a ViewContribution.
Thanks very much for sharing your work =) it helped me a lot.
Keep going with the good work