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.

Advertisement