Wednesday, December 17, 2008
Automatically Create Working Sets Eclipse plug-in
Tuesday, December 16, 2008
Smart Semicolon Eclipse plug-in
Sunday, December 07, 2008
Hooking into Eclipse command execution
// Add listener to monitor Cut and Copy commands
ICommandService commandService = (ICommandService) PlatformUI
.getWorkbench().getAdapter(ICommandService.class);
if (commandService != null) {
commandService.addExecutionListener(new IExecutionListener() {
public void notHandled(String commandId,
NotHandledException exception) {
}
public void postExecuteFailure(String commandId,
ExecutionException exception) {
}
public void postExecuteSuccess(String commandId,
Object returnValue) {
// Is it a Cut or Copy command
if ("org.eclipse.ui.edit.copy".equals(commandId)
|| "org.eclipse.ui.edit.cut".equals(commandId)) {
Clipboard clipboard = new Clipboard(PlatformUI
.getWorkbench().getActiveWorkbenchWindow()
.getShell().getDisplay());
Object contents = clipboard
.getContents(TextTransfer.getInstance());
if (contents instanceof String) {
// Now do something with text selection
}
}
}
public void preExecute(String commandId, ExecutionEvent event) {
}
});
}
Cool huh?
Thursday, November 27, 2008
Graphical cd
gcd() {
local CDTO=`zenity --title="cd" --file-selection --directory`
if [ -n "${CDTO}" ] ; then
cd "${CDTO}"
fi
}
Thursday, November 13, 2008
Zero length Java array cache
The output is:
import java.util.Map;
import java.util.WeakHashMap;
/**
* A simple cache using WeakHashMap of zero length arrays of a given class.
*
* @author schitale
*
*/
public class ZeroLength {
private static Mapmap = new WeakHashMap ();
@SuppressWarnings("unchecked")
public staticT[] array(Class c) {
T[] array = (T[]) map.get(c);
if (array == null) {
array = (T[]) java.lang.reflect.Array.newInstance(c, 0);
map.put(c, array);
}
return array;
}
public static void main(String[] args) {
System.out.println(array(String.class).getClass().getCanonicalName()
+ " of length " + array(String.class).length);
System.out.println(array(String[].class).getClass().getCanonicalName()
+ " of length " + array(String.class).length);
}
}
java.lang.String[] of length 0If you want to rely on the identity of the zero length array instance (e.g. == based comparison) then replace the WeakHashMap with HashMap. However, in that case you have to watch out for memory leaks through static fields of array component classes. You may want to add a method to remove the reference to the array from the HashMap.
java.lang.String[][] of length 0
Is there a better way to do this?
IMHO the java.lang.Class class should provide such factory method. This is along the lines of factory method:
public static final T List T java.util.Collections.emptyList();
The implementation in java.lang.Class may look like:
private static T[] zeroLengthArray;
public static synchronized T[] emptyArray() {
if (zeroLengthArray == null) {
zeroLengthArray = (T[]) java.lang.reflect.Array.newInstance(this, 0);
}
return zeroLengthArray;
}
Thursday, October 23, 2008
Bundles, Extension Points, Extensions View for Eclipse 3.4
- Bundles
- Extensions Points
- Extensions
You can start with any one of these at the top level by using the toolbar settings. You can continue to expand the relationships between these objects to any level.
Several actions are supported in the context menu:
- Open plugin.xml
- Copy extension and extension element trees
- Open Java Type specified by attributes which specify implementing Java classes.
For example, the Copy Extension action copied the following xml to the Clipboard:
Export a file containing the names and locations of the shared projects in the workspace.
I plan to make more enhancements to this view.
You can download it here.
DISCLAIMER: This plug-in is experimental. So no guarantees. Use the plug-in at your own risk.
Tuesday, October 14, 2008
Reclaim Ctrl+C and Ctrl+V for familiar Copy and Paste in gnome-terminal
In this entry I describe how to make Ctrl+C and Ctrl+V do Copy and Paste in gnome-terminals. Here is how to do it:
Open a gnome-terminal window and type the following commands:
Add the following to .bashrc
> stty intr ^K # free Ctrl+C for copy
> stty lnext ^- # free Ctrl+V for paste
> stty -g
> stty -g > ~/.stty # store the settings in home directory
case $- inNow using the gconf-editor, edit the gnome-terminal's key bindings (@ /apps/gnome-terminal/keybindings key).
*i*)
stty `cat ~/.stty` # reload the stored stty settings
bind -u quoted-insert # unbind the quoted-insert function of bash - free Ctrl+V for paste
esac
Close and reopen the terminal window. And now Ctrl+C will copy and Ctrl+V will paste.
Sunday, October 12, 2008
Launching the Open Type dialog
OpenTypeSelectionDialog dialog = new OpenTypeSelectionDialog(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
true,
PlatformUI.getWorkbench().getProgressService(),
null,
IJavaSearchConstants.TYPE);
dialog.setTitle(JavaUIMessages.OpenTypeAction_dialogTitle);
dialog.setMessage(JavaUIMessages.OpenTypeAction_dialogMessage);
dialog.setInitialPattern("java.lang.String");
int result= dialog.open();
if (result != IDialogConstants.OK_ID)
{
return;
}
Object[] types= dialog.getResult();
if (types != null && types.length > 0) {
IType type= null;
for (int i= 0; i < types.length; i++) {
type= (IType) types[i];
try {
JavaUI.openInEditor(type, true, true);
} catch (CoreException x) {
// Handle exception
}
}
}
Enhanced Plug-in Registry View
The Plug-in Registry View has a mode (Show Extension Content only) to show:
- extension-points
- extensions
- extension elements
- extension attributes
This plug-in adds some additional actions on the Plug-in Registry View's tool bar. The following screen shot shows the example of the additional actions.
For attributes with values that look like Java Type name - the Open
This works well if you have added all the plug-in classes to your Java search using the tip - Extending the Java search scope.
The other supported action is:
- Open plugin.xml
You can download the plug-in here.
BTW this plug-in makes use of the technique described in the entry - Add pulldown actions to Eclipse View's Toolbars.
DISCLAIMER: This plug-in is experimental. So no guarantees. Use the plug-in at your own risk.
Sunday, September 28, 2008
Template Tools Eclipse plug-in
Template Tools Eclipse plug-in enhances the functionality of code templates:
- ${clipboard} template variable - replaced by the contents of the clipboard.
- ${prompt(input|file|directory|enumeration, value [, value]*|color|font)}
- input - the user is prompted to enter a value
- file - the user is prompted to select a file
- directory - the user is prompted to select a directory
- enumeration - the user is prompted to select a value from the list of values
- color - the user is prompted to select a color using a color dialog. The color value can be formatted using java.util.Formatter strings. The parameters passed to the format are red, green or blue color component values. If no format is specified the value is formatted as the org.eclipse.swt.graphics.RGB.toString() value of the color.
- font - the user is prompted to select a font using a FontDialog. The returned value is the org.eclipse.swt.graphics.FontData.toString() value returned by the font dialog.
This plug-in also supports extension-point promptProviders.
<extension
point="TemplateTools.promptProviders">
<promptProvider
class="templatetools.InputPrompt"
type="input">
</promptProvider>
:
:
</extension>
Here is the implementation:
package templatetools;
import java.util.Formatter;
import java.util.List;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.ui.PlatformUI;
public class ColorPrompt implements IPrompt {
@SuppressWarnings("unchecked")
public String getValue(String name, List params) {
ColorDialog colorDilaog = new ColorDialog(PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getShell());
RGB color = colorDilaog.open();
if (color != null) {
if (params.size() > 0) {
Object format = params.get(0);
if (format instanceof String) {
StringBuffer formatBuffer = new StringBuffer();
new Formatter(formatBuffer).format((String) format,
color.red, color.green, color.blue);
return formatBuffer.toString();
}
} else {
return color.toString();
}
}
return null;
}
}
You can download the plug-in here.
DISCLAIMER: This plug-in is experimental. So no guarantees. Use the plug-in at your own risk.Monday, September 15, 2008
Reorder Eclipse Plug-in : How does it work?
Basically, the Reorder plug-in uses the AST APIs to get parsed structure of the Java source code surrounding the caret in the Java editor.
- It gets the ASTNode at caret position using NodeFinder API and starts traversing the parent ASTNodes until it find a Class Instance Creation, Method Invocation, Method Declaration or an Array initializer node.
- Once found it gets the ASTNode's list of arguments, parameters or array initialization elements and stores the text of each node in a ordered list of items. While doing so, it also records the intervening white spaces as items.
- It also records which item's extent surrounds the caret position. It records it as a current item.
- Then, it swaps the current item with the following or preceding non-whitespace item in the list based on the action that was invoked - forward or backward swap.
- Lastly it builds the string from the list of items and replaces the original text with the new string.
Sunday, September 14, 2008
Reorder Eclipse Plug-in for Java Editor
This plug-in adds two toolbar buttons to the Java editor:
- Swap backward
- Swap forward
Usage
With the caret at | in:
void method(int iii, String |sss, boolean bbb){}pressing the Swap forward button yields:
void method(int iii, boolean bbb, String |sss){}or pressing Swap backward button with the original source yields:
void method(String |sss, int iii, boolean bbb){}
You can download the plug-in from here. TODO
- Key bindings for the actions
- Generalization of the concept to other language editors
DISCLAIMER: This plug-in is experimental. So no guarantees. Use the plug-in at your own risk.
Saturday, September 13, 2008
Add pulldown actions to Eclipse View's Toolbars
org.eclipse.ui.actionSets
extension point (which allows contribution to the Wokbench Window's toolbars) allow the pulldown
style. However the actions added to the org.eclipse.ui.viewActions
extension point do not allow the pulldown
style. IMHO this is a annoying limitation. It may be that the original reason for this limitation was to avoid confusion with the drop down menu in the View toolbars. However the visual of a pulldown
action down action is different enough that it is not confusing. Besides the pull down actions are used in View toolbars of many Eclipse provided Views e.g. Open Console action on the as Console view's toolbar. So how are such actions created? Well such actions are programatically created during the View's createPartControl()
invocation. However that is not always the case. You may want to contribute a pulldown
action to a View created elsewhere. In this entry I show you how to do exactly that programatically.The basic idea behind this is to watch for opening of the view that you are interested in and programatically add the
pulldown
style action when the view is opened. Just put the following code in your plug-in's Activator. One thing to keep in mind is that your plug-in may get activated some time after the View that you are contributing a pull down action to - was already created. To handle that we process all the exiting windows that are already present when our code activates. We monitor the opening of the views in the Workbench windows by adding the IPartListener to the Window's PartService. What happens if the user creates more Workbench windows and then openes the View of interest in that Workbench window. Well, we monitor creation of new Workbench windows by adding the IWindowListener to the Workbench. We keep track of the fact that the action was added to the View's toolbar in a WeakHashMap (keyed by the IViewPart) so that we add the action only once. This is because the addActions() is called from multiple places in the following code. One more thing...the action you add must use SWT.AS_DROP_DOWN_MENU style and also implement the IMenuCreator intreface. That's it. Here is the code: private static WeakHashMap actionsAddedToView = new WeakHashMap();
private static void addActions(IViewPart viewPart)
{
Boolean added = actionsAddedToView.get(viewPart);
if (added == null) {
// The actions were not added yet
final IToolBarManager toolBarManager = viewPart.getViewSite().getActionBars().getToolBarManager();
// SomePulldownAction extends Action implements IMenuCreator
// public SomePulldownAction() {
// super("Some Action...", IAction.AS_DROP_DOWN_MENU);
// }
// Also implement the getMenu() action.
// public Menu getMenu(Control parent) {
// create menu
// add menu items
// return the menu
// }
SomePulldownAction someDownloadAction = new SomePulldownAction();
someDownloadAction.init(viewPart);
toolBarManager.insertAfter("id-of-an-exiting-action-on-views-toolbar", someDownloadAction); //$NON-NLS-1$
// Add more actions
// ...
// ...
// ...
toolBarManager.update(true);
actionsAddedToView.put(viewPart, Boolean.TRUE);
}
}
// Listner for monitoring the view opening
private static final IPartListener partListener = new PartListenerAdapter()
{
@Override
public void partOpened(IWorkbenchPart part)
{
if (part instanceof IViewPart)
{
IViewPart viewPart = (IViewPart) part;
if ("-id-of-the-view-to-which-you-want-to-add-the-pulldown-action".equals(viewPart.getSite().getId()))
{
addActions(viewPart);
}
}
}
@Override
public void partClosed(IWorkbenchPart part)
{
if (part instanceof IViewPart)
{
IViewPart viewPart = (IViewPart) part;
if ("-id-of-the-view-to-which-you-want-to-add-the-pulldown-action".equals(viewPart.getSite().getId()))
{
// forget the view's actions added state
actionsAddedToView.remove(viewPart);
}
}
}
};
private static void processWindow(IWorkbenchWindow window)
{
IWorkbenchPage[] pages = window.getPages();
for (IWorkbenchPage workbenchPage : pages)
{
IViewPart viewPart = workbenchPage.findView("-id-of-the-view-to-which-you-want-to-add-the-pulldown-action");
if viewPart != null && viewPart.getSite() != null)
{
addActions(viewPart);
break;
}
}
// Monitor furture view creation in case the view
// is closed and reopened
window.getPartService().addPartListener(partListener);
}
static {
// Add pulldown action to the view that may be already present in
// exiting Workbench windows.
IWorkbenchWindow[] workbenchWindows = PlatformUI.getWorkbench().getWorkbenchWindows();
for (IWorkbenchWindow workbenchWindow : workbenchWindows)
{
processWindow(workbenchWindow);
}
// Monitor future Workbench windows
PlatformUI.getWorkbench().addWindowListener(new IWindowListener()
{
public void windowActivated(IWorkbenchWindow window) {}
public void windowClosed(IWorkbenchWindow window) {}
public void windowDeactivated(IWorkbenchWindow window) {}
public void windowOpened(IWorkbenchWindow window)
{
processWindow(window);
}
});
}
Tuesday, September 09, 2008
An enhanced ListEditor implementation
/**
* The subclasses must override this to return the modified entry.
*
* @param original the new entry
* @return the modified entry. Return null to prevent modification.
*/
protected abstract String getModifiedEntry(String original);
One possible implementation could look something like this:
@Override
protected String getModifiedEntry(String original) {
InputDialog entryDialog = new InputDialog(
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
"Edit entry", "Edit entry:", original, null);
if (entryDialog.open() == InputDialog.OK) {
return entryDialog.getValue();
}
return null;
}
In fact, I make use of this in my Path Tools Eclipse Plug-in to edit the custom commands for folders and files. Here is the screenshot:
Here is the full code:
package somepackage;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.ListEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;
/**
* This class extends {@link ListEditor} to enable editing of entries.
*
* @author Sandip V. Chitale
*
*/
public abstract class EntryModifiableListEditor extends ListEditor {
public EntryModifiableListEditor(String name, String labelText, Composite parent) {
super(name, labelText, parent);
}
/**
* The subclasses must override this to return the modified entry.
*
* @param original the new entry
* @return the modified entry. Return null to prevent modification.
*/
protected abstract String getModifiedEntry(String original);
private Button editButton;
private List commandListControl;
@Override
public Composite getButtonBoxControl(Composite parent) {
Composite buttonBoxControl = super.getButtonBoxControl(parent);
if (editButton == null) {
editButton = createPushButton(buttonBoxControl, "Edit..."); // TODO I18N
editButton.setEnabled(false);
editButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (commandListControl.getSelectionCount() == 1) {
String modified = getModifiedEntry(commandListControl.getSelection()[0]);
if (modified != null) {
int selectedIndex = commandListControl.getSelectionIndex();
commandListControl.remove(selectedIndex);
commandListControl.add(modified, selectedIndex);
}
}
}
});
buttonBoxControl.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent event) {
editButton = null;
}
});
}
return buttonBoxControl;
}
/**
* Helper method to create a push button.
*
* @param parent the parent control
* @param key the resource name used to supply the button's label text
* @return Button
*/
private Button createPushButton(Composite parent, String key) {
Button button = new Button(parent, SWT.PUSH);
button.setText(key);
button.setFont(parent.getFont());
GridData data = new GridData(GridData.FILL_HORIZONTAL);
int widthHint = convertHorizontalDLUsToPixels(button,
IDialogConstants.BUTTON_WIDTH);
data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT,
SWT.DEFAULT, true).x);
button.setLayoutData(data);
return button;
}
@Override
public List getListControl(Composite parent) {
List listControl = super.getListControl(parent);
if (commandListControl == null) {
commandListControl = listControl;
commandListControl.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
editButton.setEnabled(commandListControl.getSelectionCount() == 1);
}
});
}
return listControl;
}
}
Sunday, September 07, 2008
Perspectives and Views Toolbar Plugin for Eclipse
Get the Eclipse 3.4 compatible Perspectives and Views Toolbar Plug-in here.
DISCLAIMER: This plug-in is experimental. So no guarantees. Use the plug-in at your own risk.
Sunday, August 31, 2008
Eclipse template variables ${selection} and ${clipboard}
245788 Add a template variable ${selection} and allow Surround With action to deal consider it.
245790 Add a template variable ${clipboard}
The jist of the enhancement is that two new template variables should be added:
${selection} - this is replaced by what ever was the selection in the editor at the time of template insertion was invoked. Note that this requires a template invocation machanism that does not destroy the selection in text editor.
${clipboard} - this is replaced by the text content of the the clipboard.
Here is a use case:
template name: hyperlink
template pattern:
<a href="${clipboard}">${selection}</a>${cursor}
and with text http://www.google.com/ in the clipboard and the text
Google|
selected in the Eclipse editor.
Invoking the hyperlink template using the Surround with... action yields:
<a herf="http://www.google.com">Google</a>
Granted this would have been easy to type but imagine a complex URL copied into the clipboard from the browser address bar in place of "http://www.google.com/".
Please vote on the enhancement if you like this idea.
Friday, August 29, 2008
Self maintaining package level logger access class
package somepackage;Thoughts?
import java.util.logging.Logger;
/**
* Self maintaining package level logger access
*
*/
final class Log {
private static Logger logger;
// not thread safe
static Logger getLogger() {
if (logger == null) {
logger =
Logger.getLogger(Log.class.getPackage().getName());
}
return logger;
}
private Log(){}
}
Monday, August 25, 2008
INFO: Eclipse View and Perspective IDs
Views | |
Ant | org.eclipse.ant.ui.views.AntView |
Bookmarks | org.eclipse.ui.views.BookmarkView |
Breakpoints | org.eclipse.debug.ui.BreakpointView |
CVS Annotate | org.eclipse.team.ccvs.ui.AnnotateView |
CVS Editors | org.eclipse.team.ccvs.ui.EditorsView |
CVS Repositories | org.eclipse.team.ccvs.ui.RepositoriesView |
Call Hierarchy | org.eclipse.jdt.callhierarchy.view |
Cheat Sheets | org.eclipse.ui.cheatsheets.views.CheatSheetView |
Classic Search | org.eclipse.search.SearchResultView |
Console | org.eclipse.ui.console.ConsoleView |
Debug | org.eclipse.debug.ui.DebugView |
Declaration | org.eclipse.jdt.ui.SourceView |
Display | org.eclipse.jdt.debug.ui.DisplayView |
Error Log | org.eclipse.pde.runtime.LogView |
Expressions | org.eclipse.debug.ui.ExpressionView |
Help | org.eclipse.help.ui.HelpView |
Hierarchy | org.eclipse.jdt.ui.TypeHierarchy |
History | org.eclipse.team.ui.GenericHistoryView |
Internal Web Browser | org.eclipse.ui.browser.view |
JUnit | org.eclipse.jdt.junit.ResultView |
Javadoc | org.eclipse.jdt.ui.JavadocView |
Members | org.eclipse.jdt.ui.MembersView |
Memory | org.eclipse.debug.ui.MemoryView |
Navigator | org.eclipse.ui.views.ResourceNavigator |
Outline | org.eclipse.ui.views.ContentOutline |
Package Explorer | org.eclipse.jdt.ui.PackageExplorer |
Packages | org.eclipse.jdt.ui.PackagesView |
Plug-in Dependencies | org.eclipse.pde.ui.DependenciesView |
Plug-in Registry | org.eclipse.pde.runtime.RegistryBrowser |
Plug-ins | org.eclipse.pde.ui.PluginsView |
Problems | org.eclipse.ui.views.ProblemView |
Progress | org.eclipse.ui.views.ProgressView |
Project Explorer | org.eclipse.ui.navigator.ProjectExplorer |
Projects | org.eclipse.jdt.ui.ProjectsView |
Properties | org.eclipse.ui.views.PropertySheet |
Registers | org.eclipse.debug.ui.RegisterView |
SVN Annotate | org.tigris.subversion.subclipse.ui.annotations.AnnotateView |
SVN Properties | org.tigris.subversion.subclipse.ui.svnproperties.SvnPropertiesView |
SVN Repositories | org.tigris.subversion.subclipse.ui.repository.RepositoriesView |
Search | org.eclipse.search.ui.views.SearchView |
Synchronize | org.eclipse.team.sync.views.SynchronizeView |
Tasks | org.eclipse.ui.views.TaskList |
Types | org.eclipse.jdt.ui.TypesView |
Variables | org.eclipse.debug.ui.VariableView |
Welcome | org.eclipse.ui.internal.introview |
Perspectives | |
CVS Repository Exploring | org.eclipse.team.cvs.ui.cvsPerspective |
Debug | org.eclipse.debug.ui.DebugPerspective |
Java | org.eclipse.jdt.ui.JavaPerspective |
Java Browsing | org.eclipse.jdt.ui.JavaBrowsingPerspective |
Java Type Hierarchy | org.eclipse.jdt.ui.JavaHierarchyPerspective |
Plug-in Development | org.eclipse.pde.ui.PDEPerspective |
Resource | org.eclipse.ui.resourcePerspective |
SVN Repository Exploring | org.tigris.subversion.subclipse.ui.svnPerspective |
Team Synchronizing | org.eclipse.team.ui.TeamSynchronizingPerspective |
Monday, August 18, 2008
Where is Sandip?
Sunday, August 17, 2008
Article on Eclipse Zone
PathTools : Simple Yet Useful Eclipse Plug-in
Toolbar
Preferences Page