*development-plugins.html*

Plugins
*******

Note: This guide is a work in progress. If in the process of writing
  a new plugin you find anything here that is unclear or missing,
  please don’t hesitate to post to the eclim-dev
  (http://groups.google.com/group/eclim-dev) mailing list with
  questions, suggestions, etc.

To allow eclim to support different languages, eclim is broken up into
eclipse plugins, each of which depend on a corresponding eclipse
feature which provides support for that language. When you install or
build eclim, it will examine your eclipse install to determine which
features are available and will add the corresponding eclim plugins to
expose those features. This page documents the core aspects of what
goes into the creation of a new eclim plugin.


Bootstrapping the plugin artifacts
==================================

Eclim includes a set of templates to help you bootstrap a new plugin.
To utilize them you can run the following ant target:

>

   $ ant plugin.create

<


You will be prompted to enter a name for this plugin along with some
guidelines on choosing an appropriate name.

Once you’ve chosen a name, the plugin’s directory structure will be
created and populated with bare bones version of the required
artifacts. Eclim’s build.xml file will also be updated to include a
target to the new plugin’s unit test target.


Updating the initial artifacts
==============================

After you’ve bootstrapped your plugin, you can now start updating the
generated artifacts:


build_<plugin_name>.gant
------------------------

The first file you’ll need to modify is a gant file for your plugin.
The main eclim build.gant script will load this file during the build
process to determine what the plugin’s eclipse dependency is, so it
knows whether it can be built against the target eclipse install. So
the first thing we need to do is to fill in that information by
updating the feature_<plugin_name> variable with the name of the
eclipse feature that this plugin depends on. For example, the eclim
jdt plugin has this set to 'org.eclipse.jdt'. The build script will
look in the features directory of your eclipse install (including the
dropins and your user local eclipse dir if set), to find this feature,
so the value you set, must be found in one of those locations (the
version suffixes will be removed from the features in order to match
it against the value you’ve set).

You’ll also notice that there is a unit test target in the gant file.
You can ignore that for now.


META-INF/MANIFEST.MF
--------------------

The next file to note is the plugin’s META-INF/MANIFEST.MF. This is
the file that eclipse will use to determine how to load the bundle and
what to include in its classpath. The only part of this file that you
should edit is the Require-Bundle: section. This is a comma separated
list of bundles (or plugins) which this bundle depends on. When this
bundle is loaded only those bundles listed here will be available in
the classpath. So when you start running commands you’ve written
later, if you receive a ClassNotFoundException, that is likely due to
the bundle containing that class not being listed in your plugin’s
Require-Bundle: list. At this point you probably don’t know yet what
bundles you need to add to this list. When you start writing commands
for your plugin, you’ll have to find out which bundles contain the
classes imported from the eclipse plugin you are integrating with, and
you’ll need to add those bundles accordingly.

It’s also worth noting that eclim provides a custom classpath
container which scans the manifest of each eclim plugin and loads the
required bundles of each into the classpath. So when adding new
bundles, if you want validation, search, code completion, etc to work
with classes from those new bundles, you’ll have to restart the eclim
daemon. While restarting can be annoying, this is generally better
than having to add/remove entries from the .classpath file or worrying
about one user having different bundle version numbers from another.


PluginResources.java
--------------------

At this point you’ll typically need to start customizing your plugin’s
org.eclim.<name>/java/org/eclim/plugin/<name>/PluginResources.java
file. Here is where you will map a short alias to the project nature,
or natures, of the plugin you are integrating with, register a project
manager for initializing project’s for this plugin, register any
plugin settings that users can configure, etc. You’ll be doing all
this inside of the initialize method which has been generated for you.


Project Nature
~~~~~~~~~~~~~~

You’ll first need to find out where the plugin’s nature id is defined.
Here are some examples that should give you an idea of where to look:

- jdt: org.eclipse.jdt.core.JavaCore.NATURE_ID
- cdt:
  - org.eclipse.cdt.core.CProjectNature.CNATURE_ID
  - org.eclipse.cdt.core.CCProjectNature.CC_NATURE_ID
- dltkruby: org.eclipse.dltk.ruby.core.RubyNature.NATURE_ID
- adt: com.android.ide.eclipse.adt.AdtConstants.NATURE_DEFAULT
One way to find it is to open up the .project file in a project
containing the nature, locate the fully qualified name in the
<natures> section, then grep the plugin’s code for that name.

Once you have the reference to the nature id, you can then create a
public static variable called NATURE:

>

   public static final String NATURE = SomeClass.NATURE_ID;

<


You’ll be using this constant as the key to register features for
project containing this nature, but first we’ll register a short alias
for this nature since the actual nature id tends to be long and
unstandardized, and we don’t want users to have to type it out when
creating projects from eclim:

>

   ProjectNatureFactory.addNature("shortname", NATURE);

<



Project Manager
~~~~~~~~~~~~~~~

The next thing you’ll probably need to do is to create a project
manager for your project
(org.eclim.<name>/java/org/eclim/plugin/<name>/project/SomeProjectManager.java).
The project manager is responsible for performing any post create,
update, delete, or refresh logic required for projects of this nature.
This logic can include things such as creating an initial
classpath/buildpath, validate the classpath/buildpath on update,
forcing a full update of the search index on refresh, or any number of
other things.

Overriding the create method will almost certainly be necessary, but
the logic you’ll need here varies widely.  Finding what you’ll need is
a matter of digging through the parent plugin’s source code, typically
looking for the project creation wizard class, to see what it does to
create a project of this nature and later comparing the created
artifacts from your code against those of a project created from the
eclipse gui. This can be a difficult hurdle to get past for someone
doing this the first time, so please don’t be shy about asking for
help on the eclim-dev (http://groups.google.com/group/eclim-dev)
mailing list.

Eclim does provide a couple ant tasks to at least help you to quickly
extract any docs and source code found in your eclipse install:

- eclipse.doc: This target will extract any doc jars from your
  eclipse install to a ‘doc’ directory in your eclipse home (or user
  local eclipse home).
- eclipse.src: This target will extract any src jars from your
  eclipse install to a ‘src’ directory in your eclipse home (or user
  local eclipse home). If you download the sdk version of eclipse then
  the jdt and all the core eclipse source will be available. Some
  other plugins provide sdk versions which include the source code and
  this target can extract those as well, but some plugins don’t seem
  to have this option when installing via eclipse’s update manager
  (and may not include the source when installed from a system package
  manager). For those you can often download a zip version of their
  update site which should include source bundles. Once you’ve
  extracted that file, you can tell this target to extract source
  bundles from a specified directory. Here is an example of extracting
  the source from an unpacked dltk update site:
  >
     $ ant -Dsrc.dir=/home/ervandew/downloads/dltk-core-5.0.0/plugins eclipse.src

  <

Once you’ve created your project manager, you then map it to your
plugin’s nature inside of your PluginResources.initialize method like
so:

>

   ProjectManagement.addProjectManager(NATURE, new SomeProjectManager());

<



Project Settings
~~~~~~~~~~~~~~~~

At this point you should have the minimum of what is needed for a new
plugin. Hopefully you can now create new projects with your plugin’s
defined nature. The next step would be to start adding commands
(development-commands) to provide validation, code completion, etc.
The remaining items in this list are not required to continue. They
provide you with the ability to setup your own preferences or to
expose the parent plugin’s defined preferences inside of vim. When
you’ve come to the point that you need to work with preferences, then
feel free to come back here and continue reading.

To Be Continued…

vim:ft=eclimhelp