Tuesday, February 24, 2015

Let's put Orion into Context !

OK, try 2 (for those that noticed my earlier, empty, post...;-).

A small aside to start:

I've recently joined the Eclipse Orion team; after >10 years on the eclipse platform it was time for a change. Working on the eclipse UI was easily the highlight of my career so far. The opportunity to work with many truly exceptional people in such an energetic ecosystem made the work even more rewarding. While I missed out on EclipseCon this year I *will* find my way to at least one more so that I can properly thank (in person...with Beer !) at least some of the crew that has been instrumental in moving eclipse forward over the years; far too many to name individually...you know who you are..and thanks !!

Now on to the future and Orion...

It took me literally no time at all to realize that Orion needed some tooling work. Immediately upon my first attempt to work on some JS code I realized that the tooling that made me look effective in JDT just didn't exist. I was reduced to regex searches and the like to wend my way through the maze of JS / CSS / HTML files comprising Orion. This made going up the learning curve for the codebase seem more like climbing a mountain of molasses. Something had to be done...

...and has ! Take a look at the Orion 8 N&N to see the new tooling in Orion 8 and for those lucky enough to be at EclipseCon don't miss Simon Kaegi's talk: "JavaScript Language Tools. In Orion.". These are just the first fruit of the efforts to make the Orion editor more that just a fancy notepad, more are on the way.

Since the new functionality has already been announced  this post will look more closely at where we're going with the tooling. It's worth noting that all the Orion 8 feedback needed was a change in how the existing hover tooltip got its information and 'quick fix' commands (pretty good bang for the buck IMO).

It's all about the context

Most of the help from JDT comes from its crawling large statically analyzed parse trees(AST's). Since this is largely impossible in JavaScript what can we do ?

There are (loosely speaking) three different types of tooling feedback:

Information: Regular tooltip style giving JSDocs or showing a color when hovering over parts of a

Manipulation: The is for feedback that allows the user to modify their files in some way (think quick fixes and, eventually, refactoring and color/font definition).

Navigation: This is the ability for the editor to recognize and locate files referenced from the one they're editing.

Of these three the one that is most important is 'Navigation'. One of the first problems we encountered was that the code is (of course) always written reflecting the directory structure of where it is *deployed* (i.e. where it lives on the server). In cases where anything but the 'null' deploy is used (the code is in the same structure for development as it is when deployed) we needed some sort of 'File Map' to allow us to properly locate the development file given a reference in a deployed file. This is currently available through the file navigation hovers in Orion 8 but this is just the beginning. It's more than just 'require' and 'import' but should also be capable of deeper introspection such as locating a specific CSS class used in a JS snippet that is assigning a class to a classlist (by searching the available CSS classes for that specific class name).

With the ability to navigate from 'required' references in one file to the actual JS (or 'imported' CSS files) we also gain the ability to walk dependencies looking for useful info to show the user (i.e. JSDoc content assist for methods declared in a required JS file...). As we become more proficient in parsing relevant info we will start to gain the ability to answer some of the trickier questions like "Where is this JS / CSS class used ?" and "Where is this method used ?" (needed for eventual refactoring).

Orion 9 and beyond

Here are some of the things we'll be focused on for future releases...

Type Inferencing

Due to its inherently mushy nature JavaScript is effectively tooling resistent. Our goal is to not
restrict what the developer wants to do but instead warn them if they're doing something that will
make the tooling ineffective. For example Orion uses RequireJS to access instances of various JS
services. The 'required' service instances are assigned to variables in the object doing the requiring. The tooling will work only if the code never assigns a different, unknown, value to this var. To help here the tooling will produce a warning should such an assignment be used (preventing us from doing content assist...on that var).

Note that can (and should) be generalized to account for new techniques to 'typify' JS. If we parse a 'type' (whether from JSDoc or some other type description) the underlying mechanisms will be common enough to show the warning any time a 'typed' var is assigned to regardless of how that type was originally specified (unless of course the value being assigned is of a matching type).

Deeper Context Introspection

It's the union of all the references within a web project that truly define its 'context'. Being able to infer as much as possible about the resources being used in a particular scenario is proportional to the tooling support we can provide. One of the possibilities we're looking at is the ability to specify the HTML doc we're doing our development in the context of. This would provide access to the specific CSS files used by that page (which may be different from those used on a different page), allowing us to provide more accurate feedback; in the end everything has some page at its root.

Since the tooling relies heavily on the file map we'll be making it simpler to create and maintain the map for your particular setup as well as providing this functionality 'in the UI' (i.e. allowing the user to define explicitly the file being referenced and having the UI remember this choice, some sort of support people writing the deploy scripts...). The goal here is to make this as simple (for you) as possible so that the advantages of having access to great tooling far outweigh the effort needed to provide the file map for your project.

As a complete noob to the Web development world one of the first differences I noticed is that web pages are the result of the *merge* between the HTML, JS and CSS files. I found that working on these files in separate tabs was a pain. We'll be working on various ways of allowing the coder to focus more closely on working and less on navigation issues. I don't think it'll take 10 years to show multiple editors on one tab within Orion...;-).

What I'd like to see is something like this:

This uses everything we've seen so far. Type inferencing tells us that '_thumb' is a DIV, meaning that we can infer that 'splitLayout' is a CSS class name. We can then search in the appropriate CSS files to locate the actual CSS class and extract it to show in the tooltip. Ideally in this scenario the tooltip would allow you to edit the contents of the class to allow you to 'tweak' it without ever having to open it.

I wish that this was available when I started...;-)

Friday, December 13, 2013

Split Editors: Anatomy of a new Feature

Finally, we're able to start moving the Eclipse IDE beyond what 3.x could do, showing some real pay-off for all the pain (for you and us). First up is the infamous Bug 8009, 11 years old and highly desired but never able to be implemented in the 3.x code base.

Lars has (again) beat me to the punch as far as the announcement goes so I'll take a different track; how did we go from the idea to the finished feature ?

Step 1: Design and Mockups

We started by making a variety of informal stabs at hacking the functionality, arriving in the end at the conclusion that in order to proceed we needed to allow a mechanism for  an MPart to contain a sub-structure (sashes and other parts...). This part is all about testing the scope of the feature and learning what we really need.

This eventually lead to the extension of the model with a new element MCompositePart, giving us a formal definition of a part that can contain other parts.

Step 2: Functional Prototype

Once the MCompositePart made it into the model it was time to hack up a prototype of the feature, making sure that it performs all the operations necessary to expose the new functionality. My favorite technique for this type of work (especially when it's eventually aimed at the IDE rather than pure e4) is to just make a new project based off the 'Hello World, Command' template. Then I work on the command's handler code until I have a 'command' that can do what I want. In this case I ended up with the following (Kodos to the Orion team; my code snippets use an Embedded Orion Editor):

public Object execute(ExecutionEvent event) throws ExecutionException {
 window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
 MApplication theApp = (MApplication) window.getService(MApplication.class);
 MTrimmedWindow win1 = (MTrimmedWindow) theApp.getChildren().get(0);

 // Get services
 ms =  win1.getContext().get(EModelService.class);
 ps = win1.getContext().get(EPartService.class);
 pe = win1.getContext().get(IPresentationEngine.class);
 MPart part = ps.getActivePart();
 if (part == null)
  return null;
 MPartStack stack = getStackFor(part);
 if (stack == null)
  return null;
 MStackElement stackSelElement = stack.getSelectedElement();
 if (stackSelElement instanceof MCompositePart) {
  unsplitPart((MCompositePart) stackSelElement);
 } else {
  horizontal = !horizontal ;
 return null;

This gives me a command that will act as a toggle and change orientation each time you split (to ensure that we can do both) and accomplishes two objectives:
  1. Allows me to fully implement the desired functionality, creating methods to be used in the implementation of the handler.
  2. Test / refine the rendering capabilities to allow for the new requirements. In this case very few were needed as you can see by looking at the commits on Bug 378298. A lot of this code is only necessary because we have to support the new MCompositePart itself and it not directly related to the split editor feature.
BTW, not to worry about the implementations of the 'split' and 'unsplit' methods used in the code above; we'll be getting back to that code later :-).

Now we have a working implementation of the feature but it's not correctly packaged since all the code is in the handler class (and that handler uses the IDE's mechanisms but we will want this functionality in e4 as well)...what to do ? what to do ?

Step 3: Packaging the code for re-use

OK, the first thing to consider is what this feature would look like in pure e4. The pattern used by the MinMaxAddon is also applicable to this scenario so let's go with it:
  1. Define a new SplitPartAddon that reacts to two new IPresentationEngine constants "SPLIT_HORIZONTAL" and "SPLIT_VERTICAL".
  2. Move the methods required to do this out of the original handler into the new addon, calling them appropriately based on the new tags being added / removed from an existing MPart.
Here's SplitterAddon (note that the complete functional implementation is only 150 lines of code):

 * Listens for the IPresentationEngine's SPLIT_HORIZONTAL and SPLIT_VERTICAL tags being applied to
 * an MPart and takes the appropriate steps to split / unsplit the part
 * @since 1.1
public class SplitterAddon {
 EModelService ms;

 EPartService ps;

  * Handles changes in tags
  * @param event
 private void subscribeTopicTagsChanged(
   @UIEventTopic(UIEvents.ApplicationElement.TOPIC_TAGS) Event event) {
  Object changedObj = event.getProperty(EventTags.ELEMENT);

  if (!(changedObj instanceof MPart))

  MPart part = (MPart) changedObj;

  if (UIEvents.isADD(event)) {
   if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE,
     IPresentationEngine.SPLIT_HORIZONTAL)) {
    splitPart(part, true);
   } else if (UIEvents.contains(event, UIEvents.EventTags.NEW_VALUE,
     IPresentationEngine.SPLIT_VERTICAL)) {
    splitPart(part, false);
  } else if (UIEvents.isREMOVE(event)) {
   MCompositePart compPart = SplitterAddon.findContainingCompositePart(part);
   if (UIEvents.contains(event, UIEvents.EventTags.OLD_VALUE,
     IPresentationEngine.SPLIT_HORIZONTAL)) {
   } else if (UIEvents.contains(event, UIEvents.EventTags.OLD_VALUE,
     IPresentationEngine.SPLIT_VERTICAL)) {

  * Finds the CompositePart containing the given part (if any)
  * @param part
  * @return The MCompositePart or 'null' if none is found
 public static MCompositePart findContainingCompositePart(MPart part) {
  if (part == null)
   return null;

  MUIElement curParent = part.getParent();
  while (curParent != null && !(curParent instanceof MCompositePart))
   curParent = curParent.getParent();

  return (MCompositePart) curParent;

 private void unsplitPart(MCompositePart compositePart) {
  if (compositePart == null)

  List innerElements = ms.findElements(compositePart, null, MPart.class, null);
  if (innerElements.size() < 2)

  MPart originalEditor = innerElements.get(1); // '0' is the composite part

  MElementContainer compParent = compositePart.getParent();
  int index = compParent.getChildren().indexOf(compositePart);
  compParent.getChildren().add(index, originalEditor);

  if (ps.getActivePart() == originalEditor)

 private MCompositePart createCompositePart(MPart originalPart) {
  MCompositePart compPart = ms.createModelElement(MCompositePart.class);
  compPart.setElementId("Split Host(" + originalPart.getLabel() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
  compPart.setContributionURI("bundleclass://org.eclipse.e4.ui.workbench.addons.swt/org.eclipse.e4.ui.workbench.addons.splitteraddon.SplitHost"); //$NON-NLS-1$

  // Always remove the composite part from the model

  return compPart;

 void splitPart(MPart partToSplit, boolean horizontal) {
  MElementContainer parent = partToSplit.getParent();
  int index = parent.getChildren().indexOf(partToSplit);

  MPart editorClone = (MPart) ms.cloneElement(partToSplit, null);

  MCompositePart compPart = createCompositePart(partToSplit);

  // Add the new composite part to the model
  parent.getChildren().add(index, compPart);

  // Now, add the original part into the composite
  int orientation = horizontal ? EModelService.ABOVE : EModelService.LEFT_OF;
  ms.insert(partToSplit, editorClone, orientation, 0.5f);


Now we can take our original IDE command handler and replace the code that used to call the methods directly with code that adds or removes the appropriate tags on the MPart for the active editor. Here's the final code for the IDE handler:

public class SplitHandler extends AbstractHandler {
 private EModelService modelService;
 private IWorkbenchWindow window;

  * The constructor.
 public SplitHandler() {

 public Object execute(ExecutionEvent event) throws ExecutionException {
  // Only works for the active editor
  IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);
  if (activeEditor == null)
   return null;
  MPart editorPart = (MPart) activeEditor.getSite().getService(MPart.class);
  if (editorPart == null)
   return null;
  window = HandlerUtil.getActiveWorkbenchWindowChecked(event);

  // Get services
  modelService =  editorPart.getContext().get(EModelService.class);
  MPartStack stack = getStackFor(editorPart);
  if (stack == null)
   return null;

  try {
   MStackElement stackSelElement = stack.getSelectedElement();
   if (stackSelElement instanceof MCompositePart) {
    List innerElements = modelService.findElements(stackSelElement, null, MPart.class, null);
    MPart originalEditor = innerElements.get(1); // '0' is the composite part
   } else {
    if ("false".equals(event.getParameter("Splitter.isHorizontal"))) { //$NON-NLS-1$ //$NON-NLS-2$
    } else {
  } finally {
  return null;
 private MPartStack getStackFor(MPart part) {
  MUIElement presentationElement = part.getCurSharedRef() == null ? part : part.getCurSharedRef();
  MUIElement parent = presentationElement.getParent();
  while (parent != null && !(parent instanceof MPartStack))
   parent = parent.getParent();
  return (MPartStack) parent;

We also add a couple of key bindings for easy access...in this case Ctrl + '_' gives a horizontal split (one above the other) and Ctrl + '{' gives a side-by-side split.

Step 4: Release and Polish


Finally, we blog about it so that folks will know that it's available...;-).

Then we take the feedback and polish the feature (adding CSS to define the splitter's color...). The earlier we can release a new feature the more time we'll have to get the feedback and act on it before the actual release. If there's one thing as certain as death and taxes is that you won't  get it right the first time. I've learned that it's more productive to 'get it working, get it out',  then polish it rather than putting a ton of work into the polish up front just to trash it later based on feedback.

P.S. While the current implementation is specific to the Eclipse IDE and editors in particular we do expect to extend this feature to allow the proper splitting of any MPart. This will, however, require some more design work on allowing the MCompositePart to somehow 'host' the Toolbar and Menus from the currently active 'child' MPart so they appear in the stack and work correctly.

Alrighty then, on to the next one...different presentations based on how many monitors you have.

Sunday, April 7, 2013

Another Great EclipseCon

Well it's already been a week since I got back from Boston and I'd better get this out before the memories fade into the background. First off it was really nice for me to finally be able to meet Lars, Wim and \Sopot who've been so great at extending both e4's capabilities and exposure.After our excellent conversation on Sunday I'm sure that there will be more shared beers to come...;-). Unfortunately (for me) Brian De Alwis couldn't be there due to his wife being...well...due (congrats Brian !).

OK, on to the conference...this year I had more time to attend talks because I was only giving one myself. For those that have been asking the slides are here. All the ones I attended were interesting and quite informative. Wim and Lars'"Shake that FUD" talk on mixing e4 and IDE was great, demonstrating the advantages of e4's architecture and ability but presented in a hilarious Laurel and Hardy style. There was also an excellent talk on the real-world issues encountered while porting a large application to e4. This was a great indication that there is true enterprise adoption of Eclipse 4.

Tom Schindl's talk "Modern UIs with JavaFX" showing off his JavaFX work with cool animations was made even more interesting by his demonstration showing the adoption of parts of the Eclipse JDK, allowing his simple JavaFX IDE to provide code assisst...  This was a great example of the direction we want to go; moving code away from being tightly bound to the IDE in order to allow it to be re-used much more freely.

For me though the absolute tops was the talk from l33tlabs , "Bling: The GPU powered Game IDE" demo'd a re-write of SWT using OpenGL. These guys come from a gaming background so everything about the presentation was unique (like their business card). Slides ? Who needs 'em ? Their presentation was a room around which a camera roamed, zooming in on each 'slide' (a note on a wall...). To them using the static (dare I say 'uncool') Eclipise UI just wouldn't cut it artistically so they decided to do something about it...;-). The results were stunning, seeing stacks in a running Eclipse IDE jiggle, fade, zoom as 'simple' effects has given me hope that we can make the Eclipse UI palatable to today's tablet using crowd. Early days yet but stay tuned...

Finally, away from the presentation rooms I've got to give a shout out to Marcel Bruch from CodeTrails, the folks who've given us Code Recommders. They had a really fun and effective way to demonstrate what they're all about. The idea was a 'Family Feud' game where you'd have to come up with the most common uses for a new object of some type (such as the SaveFileDialog, System...). I finally understand what they are all about ( think), it's a case of 'big data' meets code assist. Marcel and I had a great talk after my (winning!) run at the game (sort of unfair since I've written a lot of code using 'vi'...;-). We're trying to see what can be done to provide some form of code assist for injection annotations; something that would really help mitigate a real issue for folks wanting to adopt DI (as everyone should...;-).

OK, back to getting Kepler together. It's always a pleasure for me to attend EclipseCon and see the energy in the community. Hope to see you all again soon.

Stay tuned !! I'll be blogging here much more regularly with examples on using the newly available API from within the Eclipse IDE.

Friday, November 11, 2011

Almost over the Jet Lag

I'd meant to post this somewhat earlier but between catching up on work and sleep this is the first chance I've had.

I was lucky enough to be able to go to EclipseCon Europe to give a presentation on the advantages of the Eclipse 4 API (as well as assisting Tom Schindl on his talk about 4.1 / 4.2). This is a great conference ! Kudos to Ralph and everybody involved for making this a wonderful experience.

First thing I did when I got back was to fix a couple of defects pointed out by folks while I was at ECE (see, I do listen...;-):

Bug 351230 - This one's for Ed. Here's the first part...tabs can now shrink to only showing 1 character as in 3.x. Be assured that the Tab ordering issue is under active...er...discussion...;-).

Kai, your CSS re-styling issue should be gone now as well...

Just finished doing my submissions for EclispeCon in Virginia, we've got cool coming !!

All in all it was an excellent trip. It was my first time to Europe and I'm definitely going back ! Great people and so much to see...

Finally,a side note just to keep things in perspective. While I was there my best friend and his wife had their first child...while I had a nice time it's got nothing on that ! He'll get my trip stories once he comes back down to earth...

Now I've gotta get back to it...do my expenses (and pay John for the 50 Euro I borrowed..;-)...

Thursday, October 27, 2011

Eclipse 4: Beyond Compatibility

The bulk of the work for the past two Eclipse 4 releases has been on getting the compatibility layer (which allows all API clean 3.x components to 'just work' in 4.x) complete, robust and scalable. This is, however, a 'one off' exercise (thank goodness...it's been a bear!!) so we can expect to be back to a more normal 'development' cycle in 4.3.

While we're not done yet by Juno's release we will be...so now is the time to start thinking about where we want to take the platform in 4.3 and on into the future. The underlying architecture (called e4) upon which Eclipse 4 is implemented is capable of doing far more than just what 3.x provides in its presentation, the question is how we can leverage these new abilities to enhance the Eclipse User Experience.

I've recently presented a webinar called "Leveraging Eclipse 4 API to Build Components for the Future" which can be found on Eclipse Live. It gives a fairly general description of the basic 'e4' architecture (Modeled UI and Dependency Injection), suitable for folks that are just getting their first look at Eclipse 4.

Here's a screen shot of the webinar's demo showing a real PackageExplorer view hosted within a WizardPage.

This is just one example of the flexibility inherent in Eclipse 4. This turns out to be easy to do, here's a ZIP file (WebinarProject.zip) containing the project used to implement this wizard. To run it though its paces:
  1. Install a recent version of Eclipse 4 and fire it up
  2. Unzip the file somewhere and Import the project into your workspace
  3. Make a new Run Configuration and fire up the inner
  4. You will see that there's a new entry in the 'New...' drop down called 'Local View', opening it will get you to the state captured in the image above.
  5. It'll look pretty boring since your inner won't have any projects...but it's the PackageExplorer, just right-click and create a new project...;-).

(Gratuitous Plug Warning...;-) I'm heading off next week to EclipseCon Europe where (along with helping Tom Schindl out with some of his presentations) I'll be giving a talk entitled "Eclipse 4: Where do we go from here ?" that will cover some of these same questions, albeit from a slightly different angle. Folks lucky enough to be going to the talk will still want to view the webinar which will fill in more background than I'll be able to cover in a 25 minute presentation.

Late Breaking News !! Here's a screen capture taken from work that Bogdan Gheorghe is doing on creating an XText based CSS editor. While folks writing new e4 RCP apps can use this as a regular editor to define their app's CSS file here it's presented under the Appearance Preference page, where it will modify the CSS of the currently running Eclipse 4 session (replacing a slew of formerly discreet preferences).

This demonstrates one of the new approaches we've already identified; the Eclipse 4 tooling will allow itself to be hosted in two places; as a regular editor to define content for projects within the workspace as well as in an appropriate preference page to facilitate changes to the currently running Eclipse session. That way users don't have to learn two different mechanisms (and we only have one piece of code to improve...;-).

Got any ideas ? Remember when you opened an enhancement request that was eventually closed as 'undo-able' ? Now is the time to dust them off again or open new ones. If you just want to discuss them you can reach us on IRC at "#eclipse-e4' or feel free to send me an email at emoffatt@ca.ibm.com, it's not only my pleasure to discuss cool ideas, it's my job !

Monday, June 27, 2011

Eclipse 4 ships with Indigo

How do we know ? Well for one thing I finally have time to start blogging...;-). This is just the first of many posts I expect to be making over the summer (and likely the least technical).

After almost 3 years of design and development the next version of Eclipse is ready for you to start using.

Is it perfect yet ? No, see the Known Issues page here but we are sure that none of these issues cannot be addressed during the 4.2 cycle. It's now time to pass the ball over to the community; we need your input to make this version of Eclipse even better..

The current PMC plans are that 4.2 should be the base platform for the Juno release and it will be our primary focus for 4.2 to ensure that this happens. Any defects found by the release train components will be top priority (actually any component, release train or not, if you're willing to spend the time testing we're ready to spend the time fixing your issues). Here's how you can help:

Testing Your Components:

We've already done our own 'ad hoc' testing of various components (CDT, Mylyn...) but only the actual component team knows enough about their features to ensure that our compatibility coverage is 100%. Testing your component in Eclipse 4 is easy (if it weren't I'd likely be updating my resume rather than writing this blog post...;-), even for something like the CDT the testing time required was under 3 hours:
  1. Download Eclipse 4.1
  2. Use it as you would normally and install / check out your component
  3. Run through a test of your component's features
    • Open any perspectives and check that everything's there
    • Ensure that all views / editors work correctly
    • Check the part's menu and toolbar items to make sure they're OK
* Please don't play the waiting game on this ("I'll let the other components go first to see what happens"). The amount of interest shown in Eclipse 4 will be a significant factor in its remaining the release train target.

We're here for you:

If you encounter any issues which prevent you from testing your component feel free to contact me directly (emoffatt@ca.ibm.com) and I'd be happy to help out in any way (including working through the issues directly with you on the phone as I did with Chris for CDT, here's his blog entry about it).

Report any defects against Eclipse -> Platform -> UI as you normally would (setting the target milestone to 4.1.1 will help us triage them). As I said above these will receive preferred treatment...It is worth noting that we are well positioned for this, the compatibility layer and the e4 core are much more compartmentalized so our ability for find and fix defects is faaar faster than the equivalent in the 3.x stream.

Also feel free to join us on IRC at '#eclipse-e4' or by posting to the mailing list 'e4-dev@eclipse.org' to join in discussions about where we should be taking the 4.x stream beyond simply being compatible or just to share anything Eclipse 4 related.

I'm really looking forward to this year and seeing Eclipse 4 mature into the IDE of the future...