howdy,

OK, here's a patch I'd like to propose. It does the following:
Launching:
 -  Enhances RubyInterpreter class to have an executorID
 - adds an extension point to add CommandExecutors (these call Ruby)
   This is necessary so plugins can add their own Command Executors;
   I'll need this for the JRuby plugin, so that it can set JAVA_HOME,
etc when calling JRuby;
   I guess this might be handy for other stuff too;
 - updated the exec call in CommandExecutor to take an IProject (so the
launch can make use of information in the IProject)
 - changed the StandardCommandExecutor for the updates to the interface;

 - change to eclipseDebug.rb
  I removed one character from the breakpoint command handling code in
eclipseDebug.rb; the character is a '+' in a Regex, that
  doesn't seem to belong there; it doesn't change the behavior of the
code (C/Ruby debugging works normally), but it tripped up
  JRuby (http://jira.codehaus.org/browse/JRUBY-283).

Debug UI Plugin
 - a GUI change: I added something to the dialog that allows you to add
Ruby Interpreters,
   a ComboBox that lists all the installed CommandExecutors; for now it
should just show "Standard";
   the chosen CommandExecutor information is also persisted with the
RubyInterpreter information;

UI Plugin:
 - updated RI View & Friends to use the updated exec call of CommandExecutor
 - addded HyperLinkProvider extension point
 - added RubyElement HyperlinkProvider that handles links to Ruby
classes & friends
   (this uses the code that Chris recently committed and updated BUT I
moved it to an .internal package) and
   fiddled a bit with it;
 

Question:
There seems to be a bug in the way these RubyInterpreters are handled in
the Preferences; if you add one in the Installed Interpreters page,
they're not persisted. However: if you add them in the
LaunchConfiguration page, their information get's written to some XML
configuration file.  The code for this seems to be missing in the
Preferences page for this.
Can somebody confirm this?

@RadRails guys: the Hyperlink extension point is probably useful for
you, if you want to handle things like  'render :template, "foo/bar"' 
(or whatever the arguments are). I can send you a sample
HyperlinkProvider for JRuby's include_class  if you want some idea how
to implement this;


OK, I hope I added everything that's necessary.

murphee

-- 

Blog @ http://jroller.com/page/murphee 
Maintainer of EclipseShell @ http://eclipse-shell.sourceforge.net/


Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/plugin.xml
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/plugin.xml 
    (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/plugin.xml 
    (working copy)
@@ -7,6 +7,8 @@
    provider-name="RubyPeople, Inc."
    class="org.rubypeople.rdt.internal.launching.RdtLaunchingPlugin">
 
+<extension-point id="commandExecutorProvider" name="Command Executor Provider" 
schema="schema/commandExecutorProvider.exsd"/>  
+
    <runtime>
       <library name="launching.jar">
          <export name="*"/>
@@ -31,4 +33,13 @@
       </launchConfigurationType>
    </extension>
 
+  <extension
+         point="org.rubypeople.rdt.launching.commandExecutorProvider">
+         <commandExecutor 
class="org.rubypeople.rdt.extensions.StandardCommandExecutor" 
+          id = "Standard"
+          name = "Default Ruby"
+         />
+   </extension>
+
+
 </plugin>
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/ruby/eclipseDebug.rb
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/ruby/eclipseDebug.rb
   (revision 1716)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/ruby/eclipseDebug.rb
   (working copy)
@@ -548,7 +548,7 @@
             stdout.print "Trace off.\n"
           end
           
-        when /^\s*b(?:reak)?\s+(?:(add|remove)\s+)?((?:.*?+:)?.+)$/
+        when /^\s*b(?:reak)?\s+(?:(add|remove)\s+)?((?:.*?:)?.+)$/
           if $1 then
             mode = $1
           else
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/schema/commandExecutorProvider.exsd
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/schema/commandExecutorProvider.exsd
    (revision 0)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/schema/commandExecutorProvider.exsd
    (revision 0)
@@ -0,0 +1,117 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.rubypeople.rdt.launching">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.rubypeople.rdt.launching" 
id="commandExecutorProvider" name="CommandExecutor Provider"/>
+      </appInfo>
+      <documentation>
+         Provides the a CommandExecutor that can launch Ruby processes.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="commandExecutor"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="commandExecutor">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The class that implements 
org.rubypeople.rdt.extensions.CommandExecutor.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" 
basedOn="org.rubypeople.rdt.extensions.CommandExecutor"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+            <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  User readable name.
+               </documentation>               
+            </annotation>
+         </attribute>
+            <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Unique id.
+               </documentation>
+               
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension 
point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+</schema>
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/AbstractCommandExecutor.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/AbstractCommandExecutor.java
 (revision 0)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/AbstractCommandExecutor.java
 (revision 0)
@@ -0,0 +1,29 @@
+package org.rubypeople.rdt.extensions;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.rubypeople.rdt.internal.core.RubyProject;
+
+public abstract class AbstractCommandExecutor implements CommandExecutor {
+
+       private String name;
+       private String id;
+
+       public String getId() {
+               return id;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setId(String id) {
+               this.id = id;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+       
+}
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/CommandExecutor.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/CommandExecutor.java
 (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/CommandExecutor.java
 (working copy)
@@ -1,4 +1,4 @@
-package org.rubypeople.rdt.internal.launching;
+package org.rubypeople.rdt.extensions;
 
 import java.io.File;
 import java.io.IOException;
@@ -3,6 +3,18 @@
 import java.io.File;
 import java.io.IOException;
 
+import org.rubypeople.rdt.internal.core.RubyProject;
+
 public interface CommandExecutor {
-    public Process exec(String[] command, File workingDirectory) throws 
IOException;
+       /**
+        * 
+        * @return a String ID for this type of CommandExecutor 
+        */
+       public String getId();
+       /**
+        * 
+        * @return a short, descriptive name that can be to users in a list 
+        */
+       public String getName();
+    public Process exec(String[] command, RubyProject project, File 
workingDirectory) throws IOException;
 }

Property changes on: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/CommandExecutor.java
___________________________________________________________________
Name: svn:eol-style
   + native
Name: svn:keywords
   + Author Date Id Revision

Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/CommandExecutorManager.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/CommandExecutorManager.java
  (revision 0)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/CommandExecutorManager.java
  (revision 0)
@@ -0,0 +1,90 @@
+package org.rubypeople.rdt.extensions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.rubypeople.rdt.internal.launching.RdtLaunchingPlugin;
+
+public class CommandExecutorManager {
+       
+       public static final String RDT_LAUNCHING_NAMESPACE = 
"org.rubypeople.rdt.launching";
+       public static final String RDT_lAUNCHING_COMMANDEXECUTORPROVIDER = 
"commandExecutorProvider";
+
+       private static Map fExtensions;
+       
+       public static Collection getCommandExecutors() throws CoreException{
+               initExtensions();
+               return fExtensions.values();
+       }
+
+       public static Collection getIds() throws CoreException{
+               initExtensions();
+               return fExtensions.keySet();
+       }
+       public static CommandExecutor getCommandExecutorForId(String id) throws 
CoreException{
+               initExtensions();
+               return (CommandExecutor) fExtensions.get(id);
+       }
+
+       
+       public static void initExtensions() throws CoreException {
+               if(fExtensions == null){
+                       fExtensions = new HashMap();
+
+                       IExtensionRegistry reg = 
Platform.getExtensionRegistry();
+                       IExtensionPoint[] points = 
reg.getExtensionPoints(RDT_LAUNCHING_NAMESPACE);
+                       // TODO: Look for textProvider!
+                       IExtensionPoint point = null;
+                       
+                       if(points != null){
+                               for (int i = 0; i < points.length; i++) {
+                                       IExtensionPoint currentPoint = 
points[i];
+                                       String uniqueIdentifier = 
currentPoint.getUniqueIdentifier();
+                                       
if(uniqueIdentifier.endsWith(RDT_lAUNCHING_COMMANDEXECUTORPROVIDER)){
+                                               point = currentPoint;
+                                               break;
+                                       }                               
+                               }
+                               if(point != null){
+                                       IExtension[] exts = 
point.getExtensions();
+                                       
+                                       CommandExecutor prov = null;
+                                       
+                                       for (int i = 0; i < exts.length; i++) {
+                                               IConfigurationElement[] elem = 
exts[i].getConfigurationElements();
+                                               String attrs[] = 
elem[0].getAttributeNames();
+                                               try {
+                                                       Object tempProv = 
elem[0].createExecutableExtension("class");
+                                                       if (tempProv instanceof 
CommandExecutor ) {
+                                                               prov = 
(CommandExecutor ) tempProv;
+                                                               if (prov 
instanceof AbstractCommandExecutor) {
+                                                                       
AbstractCommandExecutor ace = (AbstractCommandExecutor) prov;
+                                                                       
ace.setId(elem[0].getAttribute("id"));
+                                                                       
ace.setName(elem[0].getAttribute("name"));
+                                                               }
+                                                               
fExtensions.put(prov.getId(), prov);
+                                                       }
+//                                                     }
+                                               } catch (Exception e) {
+                                                       IStatus errorStatus = 
new Status(IStatus.ERROR, RdtLaunchingPlugin.PLUGIN_ID, IStatus.OK, 
e.getMessage(), e);
+                                                       throw new 
CoreException(errorStatus) ;
+                                               }
+                                               
+                                       }
+                               }
+                       }
+                       
+               }
+       }
+}
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/StandardCommandExecutor.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/StandardCommandExecutor.java
 (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/StandardCommandExecutor.java
 (working copy)
@@ -1,7 +1,7 @@
 /**
  * 
  */
-package org.rubypeople.rdt.internal.launching;
+package org.rubypeople.rdt.extensions;
 
 import java.io.File;
 import java.io.IOException;
@@ -6,8 +6,12 @@
 import java.io.File;
 import java.io.IOException;
 
-class StandardCommandExecutor implements CommandExecutor {
-    public Process exec(String[] command, File workingDirectory) throws 
IOException {
+import org.rubypeople.rdt.internal.core.RubyProject;
+
+public class StandardCommandExecutor extends AbstractCommandExecutor {
+       public Process exec(String[] command, RubyProject project, File 
workingDirectory) throws IOException {
         return Runtime.getRuntime().exec(command, null, workingDirectory);
     }
+
+
 }
\ No newline at end of file

Property changes on: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/extensions/StandardCommandExecutor.java
___________________________________________________________________
Name: svn:eol-style
   + native
Name: svn:keywords
   + Author Date Id Revision

Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/CommandExecutor.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/CommandExecutor.java
 (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/CommandExecutor.java
 (working copy)
@@ -1,8 +0,0 @@
-package org.rubypeople.rdt.internal.launching;
-
-import java.io.File;
-import java.io.IOException;
-
-public interface CommandExecutor {
-    public Process exec(String[] command, File workingDirectory) throws 
IOException;
-}
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/InterpreterRunner.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/InterpreterRunner.java
       (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/InterpreterRunner.java
       (working copy)
@@ -18,9 +18,10 @@
        public IProcess run(InterpreterRunnerConfiguration configuration, 
ILaunch launch) throws CoreException {
                List commandLine = renderCommandLine(configuration);
                File workingDirectory = 
configuration.getAbsoluteWorkingDirectory();
-
+               
+               
                RubyInterpreter interpreter = 
convertInterpreter(configuration.getInterpreter()) ;
-               Process nativeRubyProcess = interpreter.exec(commandLine, 
workingDirectory);
+               Process nativeRubyProcess = interpreter.exec(commandLine, 
workingDirectory,configuration.getProject());
         Map defaultAttributes = new HashMap();
         defaultAttributes.put(IProcess.ATTR_PROCESS_TYPE, "ruby");
                IProcess process = DebugPlugin.newProcess(launch, 
nativeRubyProcess, renderLabel(configuration), defaultAttributes);
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RubyInterpreter.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RubyInterpreter.java
 (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RubyInterpreter.java
 (working copy)
@@ -10,6 +10,10 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
+import org.rubypeople.rdt.extensions.CommandExecutor;
+import org.rubypeople.rdt.extensions.CommandExecutorManager;
+import org.rubypeople.rdt.extensions.StandardCommandExecutor;
+import org.rubypeople.rdt.internal.core.RubyProject;
 
 public class RubyInterpreter {
        public static final String END_OF_OPTIONS_DELIMITER = "--";
@@ -17,10 +21,12 @@
        protected IPath installLocation;
        protected String name;
 
-    private final CommandExecutor commandExecutor;
+    private CommandExecutor commandExecutor;
+
+       private String id;
 
        public RubyInterpreter(String aName, IPath validInstallLocation) {
-        this(aName, validInstallLocation, new StandardCommandExecutor());
+        this(aName, validInstallLocation, null);
        }
 
        public RubyInterpreter(String aName, IPath validInstallLocation, 
CommandExecutor commandExecutor) {
@@ -29,6 +35,20 @@
         this.commandExecutor = commandExecutor;
     }
 
+       private CommandExecutor getCommandExecutor() throws CoreException{
+               if(commandExecutor == null ){
+                       if(id == null){
+                               this.commandExecutor = new 
StandardCommandExecutor();
+                       } else {
+                               this.commandExecutor = 
CommandExecutorManager.getCommandExecutorForId(id);
+                               if(commandExecutor == null){
+                                       this.commandExecutor = new 
StandardCommandExecutor();
+                               }
+                       }
+               } 
+               return commandExecutor;
+       }
+       
     public IPath getInstallLocation() {
                return installLocation;
        }
@@ -53,7 +73,7 @@
                throw new IllegalCommandException(errorMessage) ;
        }
        
-       public Process exec(List args, File workingDirectory) throws 
CoreException {
+       public Process exec(List args, File workingDirectory, RubyProject 
project) throws CoreException {
 
                try {
                        RdtLaunchingPlugin.debug("Launching: " + args) ;
@@ -61,7 +81,7 @@
             List rubyCmd = new ArrayList();
             rubyCmd.add(this.getCommand());
             rubyCmd.addAll(args);
-            return commandExecutor.exec((String[]) rubyCmd.toArray(new 
String[] {}), workingDirectory);
+            return getCommandExecutor().exec((String[]) rubyCmd.toArray(new 
String[] {}), project,workingDirectory);
                } catch (IOException e) {
             IStatus errorStatus = new Status(IStatus.ERROR, 
RdtLaunchingPlugin.PLUGIN_ID, IStatus.OK, 
                     "Unable to execute interpreter: " + args + 
workingDirectory, e);
@@ -83,4 +103,24 @@
                
                return false;
        }
+
+       
+       public String getExecutorId() {
+               return id;
+       }
+
+       public void setExecutorId(String id) {
+       this.id = id;   
+       }
+
+       
+       
+       
+       
+
+       
+
+       
+       
+       
 }
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RubyRuntime.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RubyRuntime.java
     (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/RubyRuntime.java
     (working copy)
@@ -168,6 +168,13 @@
                                writer.write("\" path=\"");
                                
writer.write(entry.getInstallLocation().toString());
                                writer.write("\"");
+                               
+
+                               writer.write("  executorId=\"");
+                               String executorId = entry.getExecutorId();
+                               
writer.write(executorId==null?"Standard":executorId);
+                               writer.write("\"");
+                               
                                if (entry.equals(selectedInterpreter))
                                        writer.write(" selected=\"true\"");
                                        
@@ -190,8 +197,10 @@
                        public void startElement(String namespaceURI, String 
localName, String qName, Attributes atts) throws SAXException {
                                if ("interpreter".equals(qName)) {
                                        String interpreterName = 
atts.getValue("name");
+                                       String advancedInformation = 
atts.getValue("executorId");
                                        IPath installLocation = new 
Path(atts.getValue("path"));
                                        RubyInterpreter interpreter = new 
RubyInterpreter(interpreterName, installLocation);
+                                       
interpreter.setExecutorId(advancedInformation);
                                        installedInterpreters.add(interpreter);
                                        if (atts.getValue("selected") != null)
                                                selectedInterpreter = 
interpreter;
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardCommandExecutor.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardCommandExecutor.java
 (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.launching/src/org/rubypeople/rdt/internal/launching/StandardCommandExecutor.java
 (working copy)
@@ -1,13 +0,0 @@
-/**
- * 
- */
-package org.rubypeople.rdt.internal.launching;
-
-import java.io.File;
-import java.io.IOException;
-
-class StandardCommandExecutor implements CommandExecutor {
-    public Process exec(String[] command, File workingDirectory) throws 
IOException {
-        return Runtime.getRuntime().exec(command, null, workingDirectory);
-    }
-}
\ No newline at end of file
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.debug.ui/src/org/rubypeople/rdt/internal/debug/ui/preferences/EditInterpreterDialog.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.debug.ui/src/org/rubypeople/rdt/internal/debug/ui/preferences/EditInterpreterDialog.java
 (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.debug.ui/src/org/rubypeople/rdt/internal/debug/ui/preferences/EditInterpreterDialog.java
 (working copy)
@@ -1,7 +1,10 @@
 package org.rubypeople.rdt.internal.debug.ui.preferences;
 
 import java.io.File;
+import java.util.Collection;
+import java.util.Iterator;
 
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
@@ -16,15 +19,21 @@
 import org.eclipse.swt.layout.RowData;
 import org.eclipse.swt.layout.RowLayout;
 import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.FileDialog;
 import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
+import org.rubypeople.rdt.extensions.CommandExecutor;
+import org.rubypeople.rdt.extensions.CommandExecutorManager;
 import org.rubypeople.rdt.internal.debug.ui.RdtDebugUiMessages;
 import org.rubypeople.rdt.internal.debug.ui.RdtDebugUiPlugin;
 import org.rubypeople.rdt.internal.launching.RubyInterpreter;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
 import org.rubypeople.rdt.internal.ui.dialogs.StatusDialog;
 
 public class EditInterpreterDialog extends StatusDialog {
@@ -31,6 +40,8 @@
        protected RubyInterpreter interpreterToEdit;
        protected Text interpreterNameText, interpreterLocationText;
        protected IStatus[] allStatus = new IStatus[2];
+       protected String advancedInformation;
+       private Combo typeCombo;
 
        public EditInterpreterDialog(Shell parentShell, String aDialogTitle) {
                super(parentShell);
@@ -140,11 +151,13 @@
        }
 
        protected void okPressed() {
-               if (interpreterToEdit == null)
+               if (interpreterToEdit == null) {
                        interpreterToEdit = new RubyInterpreter(null, null);
+               }
 
                interpreterToEdit.setName(interpreterNameText.getText());
                interpreterToEdit.setInstallLocation(new 
Path(interpreterLocationText.getText()));
+               
interpreterToEdit.setExecutorId(typeCombo.getItem(typeCombo.getSelectionIndex()));
                super.okPressed();
        }
        protected Control createDialogArea(Composite parent) {
@@ -155,6 +168,8 @@
 
                createNameEntryField(composite);
                createLocationEntryField(composite);
+//             createAdvancedButton(composite);
+               createTypeCombo(composite);
                
                return composite;
        }
@@ -159,4 +174,40 @@
                return composite;
        }
 
+       private void createTypeCombo(Composite parent) {
+               typeCombo = new Combo(parent,SWT.DEFAULT);
+               try {
+                       Collection ids = 
CommandExecutorManager.getCommandExecutors();
+                       int index = 0;
+                       for (Iterator iterator = ids.iterator(); 
iterator.hasNext();) {
+                               CommandExecutor ce = (CommandExecutor) 
iterator.next();
+                               if(ce != null){
+                                       typeCombo.add(ce.getId());
+                                       // TODO: HACK! This just sets up the 
default as .. well, 'Standard'
+                                       if(ce.getId().equals("Standard")){
+                                               typeCombo.select(index);
+                                       }
+                                       index++;
+                               }
+                       }
+               } catch (CoreException e) {
+                       RubyPlugin.log(e);
+               }
+               
+       }
+
+
+//     private void createAdvancedButton(Composite composite) {
+//             advanced = new Button(composite, SWT.PUSH);
+//             advanced.setText("Advanced...");
+//             advanced.addListener(SWT.Selection, new Listener(){
+//                     public void handleEvent(Event event) {
+//                             System.out.println("AH... so it begins... 
Jruby...");
+//                             advancedInformation = "JRuby";
+//                     }
+//             }       
+//             );
+//             
+//     }
+
 }
\ No newline at end of file
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/infoviews/RIView.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/infoviews/RIView.java
      (revision 1715)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/infoviews/RIView.java
      (working copy)
@@ -370,7 +370,7 @@
                try {                           
                 List args = getArgList();
                 args.add(0, riPath.toString());
-                       final Process p = 
RubyRuntime.getDefault().getSelectedInterpreter().exec(args, null);
+                       final Process p = 
RubyRuntime.getDefault().getSelectedInterpreter().exec(args, null,null);
                 handleOutput(p); 
                } catch (CoreException coreException)  {
                        // message of RuntimeException will be displayed in the 
RI View
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rdocexport/RDocUtility.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rdocexport/RDocUtility.java
        (revision 1715)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rdocexport/RDocUtility.java
        (working copy)
@@ -110,7 +110,7 @@
                        args.add("-r");
                        args.add(resource.getLocation().toOSString());
                        try {
-                               final Process p = interpreter.exec(args, null);
+                               final Process p = interpreter.exec(args, null, 
null);
                                handleOutput(p, args);
                        } catch (CoreException e) {
                                RubyPlugin.log(e);
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java
    (revision 1715)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java
    (working copy)
@@ -12,6 +12,7 @@
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.IEditorInput;
 import org.rubypeople.rdt.internal.launching.RubyInterpreter;
 import org.rubypeople.rdt.internal.launching.RubyRuntime;
 import org.rubypeople.rdt.internal.ui.RubyPlugin;
@@ -20,7 +21,7 @@
 
 
 public class RiDocHoverProvider implements ITextHoverProvider {
-       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion){
+       public String getHoverInfo(IEditorInput iei, ITextViewer textViewer, 
IRegion hoverRegion){
        IPath riPath = new Path( 
RubyPlugin.getDefault().getPreferenceStore().getString( 
PreferenceConstants.RI_PATH ) );
        List args = new ArrayList();
        args.add(0, riPath.toString());
@@ -35,7 +36,7 @@
                        args.add(symbol);
             RubyInterpreter selectedInterpreter = 
RubyRuntime.getDefault().getSelectedInterpreter();
                        if (selectedInterpreter == null) return null;
-            Process p = selectedInterpreter.exec(args, null);
+            Process p = selectedInterpreter.exec(args, null, null);
                        br = new BufferedReader(new 
InputStreamReader(p.getInputStream()));
                        // TODO: format the documentation that was fetched from 
RI 
                        // for now: read the first 15 lines so 
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java
     (revision 1715)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java
     (working copy)
@@ -11,6 +11,7 @@
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.texteditor.ITextEditor;
 import org.rubypeople.rdt.internal.ui.RubyPlugin;
 import org.rubypeople.rdt.ui.extensions.ITextHoverProvider;
 
@@ -29,6 +30,11 @@
        public static final String RDT_UI_TEXTHOVERPROVIDER = 
"textHoverProvider";
        
        private List fExtensions;
+       private final ITextEditor fEditor;
+
+       public RubyCodeTextHover(ITextEditor editor) {
+               this.fEditor = editor;
+       }
 
        public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) 
{
                List extensions = initExtensions();
@@ -38,7 +44,7 @@
                        if(extensions.size() > 0){
                                for(int i=0; i< extensions.size(); i++){
                                        ITextHoverProvider currentProvider = 
(ITextHoverProvider) extensions.get(i);
-                                       String hoverText = 
currentProvider.getHoverInfo(textViewer, hoverRegion);
+                                       String hoverText = 
currentProvider.getHoverInfo(fEditor.getEditorInput(), textViewer, hoverRegion);
                                        if(hoverText != null){
                                                return hoverText;
                                        }                                       
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/extensions/ITextHoverProvider.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/extensions/ITextHoverProvider.java
  (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/extensions/ITextHoverProvider.java
  (working copy)
@@ -2,6 +2,7 @@
 
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.IEditorInput;
 
 
 /**
@@ -17,5 +18,5 @@
         * @param hoverRegion the region that was preselected by the Ruby Hover 
system
         * @return the hover text OR null if no text was found 
         */
-       public String getHoverInfo(ITextViewer textViewer, IRegion 
hoverRegion);        
+       public String getHoverInfo(IEditorInput iei,ITextViewer textViewer, 
IRegion hoverRegion);       
 }
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
     (revision 1716)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
     (working copy)
@@ -539,7 +539,7 @@
        public ITextHover getTextHover(ISourceViewer sourceViewer,
                        String contentType) {
                if (fRubyTextHover == null) {
-                       fRubyTextHover = new RubyCodeTextHover();
+                       fRubyTextHover = new RubyCodeTextHover(getEditor());
                }
                return fRubyTextHover;
        }
ndex: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/META-INF/MANIFEST.MF
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/META-INF/MANIFEST.MF
  (revision 1715)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/META-INF/MANIFEST.MF
  (working copy)
@@ -33,6 +33,7 @@
  org.rubypeople.rdt.ui.rubyeditor,
  org.rubypeople.rdt.ui.text,
  org.rubypeople.rdt.ui.text.folding,
+ org.rubypeople.rdt.ui.text.hyperlinks,
  org.rubypeople.rdt.ui.text.ruby.hover,
  org.rubypeople.rdt.ui.wizards
 Require-Bundle: org.eclipse.ui.ide,
Index: /home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/plugin.xml
===================================================================
--- /home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/plugin.xml    
(revision 1716)
+++ /home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/plugin.xml    
(working copy)
@@ -3,6 +3,7 @@
 <plugin>
   
    <extension-point id="textHoverProvider" name="%textHoverProvider" 
schema="schema/textHoverProvider.exsd"/>  
+   <extension-point id="hyperlinkProvider" name="%hyperlinkProvider" 
schema="schema/hyperlinkProvider.exsd"/>  
    <extension-point id="foldingStructureProviders" 
name="%foldingStructureProviders" 
schema="schema/foldingStructureProviders.exsd"/>
    <extension-point id="editorPopupExtender" name="%editorPopupExtender" 
schema="schema/org.rubypeople.rdt.ui.editorPopupExtender.exsd"/>
    <extension-point id="rubyTemplateProvider" name="Ruby template provider" 
schema="schema/rubyTemplateProvider.exsd"/>
@@ -872,6 +873,12 @@
          <textHoverProvider 
class="org.rubypeople.rdt.internal.ui.text.ruby.hover.RiDocHoverProvider" />
   </extension>
   
+   <extension
+         point="org.rubypeople.rdt.ui.hyperlinkProvider">
+         <hyperlinkProvider 
class="org.rubypeople.rdt.internal.ui.text.ruby.hyperlinks.RubyElementsHyperlinkProvider"
 />
+  </extension>
+
+
   <extension
          point="org.eclipse.ui.popupMenus">
       <viewerContribution
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/schema/hyperlinkProvider.exsd
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/schema/hyperlinkProvider.exsd
 (revision 0)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/schema/hyperlinkProvider.exsd
 (revision 0)
@@ -0,0 +1,103 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.rubypeople.rdt.ui">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.rubypeople.rdt.ui" id="hyperlinkProvider" 
name="HyperLink Provider"/>
+      </appInfo>
+      <documentation>
+         Provides the detector and behavior for Code Browsing Hyperlinks.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="hyperlinkProvider"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="hyperlinkProvider">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The class that implements 
org.rubypeople.rdt.ui.extensions.IHyperlinkProvider.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" 
basedOn="org.rubypeople.rdt.ui.extensions.IHyperlinkProvider"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension 
point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+</schema>
ndex: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java
    (revision 1715)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RiDocHoverProvider.java
    (working copy)
@@ -12,6 +12,7 @@
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.IEditorInput;
 import org.rubypeople.rdt.internal.launching.RubyInterpreter;
 import org.rubypeople.rdt.internal.launching.RubyRuntime;
 import org.rubypeople.rdt.internal.ui.RubyPlugin;
@@ -20,7 +21,7 @@
 
 
 public class RiDocHoverProvider implements ITextHoverProvider {
-       public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion){
+       public String getHoverInfo(IEditorInput iei, ITextViewer textViewer, 
IRegion hoverRegion){
        IPath riPath = new Path( 
RubyPlugin.getDefault().getPreferenceStore().getString( 
PreferenceConstants.RI_PATH ) );
        List args = new ArrayList();
        args.add(0, riPath.toString());
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java
     (revision 1715)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hover/RubyCodeTextHover.java
     (working copy)
@@ -11,6 +11,7 @@
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.texteditor.ITextEditor;
 import org.rubypeople.rdt.internal.ui.RubyPlugin;
 import org.rubypeople.rdt.ui.extensions.ITextHoverProvider;
 
@@ -29,6 +30,11 @@
        public static final String RDT_UI_TEXTHOVERPROVIDER = 
"textHoverProvider";
        
        private List fExtensions;
+       private final ITextEditor fEditor;
+
+       public RubyCodeTextHover(ITextEditor editor) {
+               this.fEditor = editor;
+       }
 
        public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) 
{
                List extensions = initExtensions();
@@ -38,7 +44,7 @@
                        if(extensions.size() > 0){
                                for(int i=0; i< extensions.size(); i++){
                                        ITextHoverProvider currentProvider = 
(ITextHoverProvider) extensions.get(i);
-                                       String hoverText = 
currentProvider.getHoverInfo(textViewer, hoverRegion);
+                                       String hoverText = 
currentProvider.getHoverInfo(fEditor.getEditorInput(), textViewer, hoverRegion);
                                        if(hoverText != null){
                                                return hoverText;
                                        }                                       
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hyperlinks/RubyElementsHyperlinkProvider.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hyperlinks/RubyElementsHyperlinkProvider.java
    (revision 0)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hyperlinks/RubyElementsHyperlinkProvider.java
    (revision 0)
@@ -0,0 +1,126 @@
+package org.rubypeople.rdt.internal.ui.text.ruby.hyperlinks;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+import org.jruby.ast.Node;
+import org.rubypeople.rdt.core.IMember;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.ISourceRange;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.codeassist.SelectionEngine;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
+import org.rubypeople.rdt.internal.ui.text.RubyWordFinder;
+import org.rubypeople.rdt.ui.IWorkingCopyManager;
+import org.rubypeople.rdt.ui.text.hyperlinks.IHyperlinkProvider;
+
+public class RubyElementsHyperlinkProvider implements IHyperlinkProvider {
+
+       public RubyElementsHyperlinkProvider (){}
+
+       class RubyElementsHyperlink implements IHyperlink {
+               private IRegion fRegion;
+               private final IEditorInput fEditorInput;
+               private final IRubyElement[] fElements;
+
+               public RubyElementsHyperlink(IEditorInput editorInput, IRegion 
region, String symbol, IRubyElement[] elements) {
+                       this.fEditorInput = editorInput;
+//                     fRegion = new Region(region.getOffset(), 5);
+                       fRegion = region;
+                       this.fElements = elements;
+               }
+
+               public IRegion getHyperlinkRegion() {
+                       return fRegion;
+               }
+
+               public String getHyperlinkText() {
+                       // TODO Auto-generated method stub
+                       return null;
+               }
+
+               public String getTypeLabel() {
+                       // TODO Auto-generated method stub
+                       return null;
+               }
+
+
+               public void open() {                    
+                       try {
+                               // FIXME Check for first element which is an 
instanceof of IMember, don't just try to access the first element!
+                               if(fElements != null && fElements.length > 0){
+                                       ISourceRange sourceRange = ((IMember) 
fElements[0]).getSourceRange();
+                                       IFile file = null;
+                                       if (fEditorInput instanceof 
IFileEditorInput) {
+                                               IFileEditorInput fileInput = 
(IFileEditorInput) fEditorInput;
+                                               file = fileInput.getFile();
+                                       }
+                                       openFileAndLocation(sourceRange, file);
+                               }
+                       } catch (PartInitException e) {
+                               RubyPlugin.log(e);
+                       } catch (RubyModelException e) {
+                               RubyPlugin.log(e);
+                       } catch (CoreException e) {
+                               RubyPlugin.log(e);
+                       }                       
+               }
+
+               private void openFileAndLocation(ISourceRange sourceRange, 
IFile file)
+               throws PartInitException, CoreException {
+                       if (file == null) {
+                               return;
+                       }
+                       if (sourceRange == null) {
+                               return;
+                       }
+                       IEditorPart editorPart = 
IDE.openEditor(PlatformUI.getWorkbench()
+                                       
.getActiveWorkbenchWindow().getActivePage(), file, true);
+
+                       IMarker mark = file.createMarker(IMarker.TEXT);
+                       mark.setAttribute(IMarker.CHAR_START, 
sourceRange.getOffset());
+                       mark.setAttribute(IMarker.CHAR_END, 
sourceRange.getOffset()
+                                       + sourceRange.getLength());
+                       IDE.gotoMarker(editorPart, mark);
+                       mark.delete();
+                       IDE.gotoMarker(editorPart, mark);
+               }
+
+       }
+
+
+       public IHyperlink getHyperlink(IEditorInput input, ITextViewer 
textViewer, Node node,
+                       IRegion region, boolean canShowMultipleHyperlinks) {
+               IRegion newRegion = 
RubyWordFinder.findWord(textViewer.getDocument(), region.getOffset());
+               try {
+                       String symbol = 
textViewer.getDocument().get(newRegion.getOffset(), newRegion.getLength());
+                       // Let's see if this is a RubyElement
+                       SelectionEngine engine = new SelectionEngine();
+                       IWorkingCopyManager manager = 
RubyPlugin.getDefault().getWorkingCopyManager();
+                       IRubyScript script = manager.getWorkingCopy(input);
+                       IRubyElement[] elements = engine.select(script, 
newRegion.getOffset(), newRegion.getOffset() + newRegion.getLength());
+                       if(elements == null){
+                               return null;
+                       }
+                       if(elements.length > 0){
+                               // TODO: check if it's a RubyElement, if not, 
return null
+                               return new RubyElementsHyperlink(input, 
newRegion, symbol, elements);
+                       }
+                       return null;
+               } catch (Exception e) {
+                       RubyPlugin.log(e);
+               }
+               return null;
+       }
+
+}
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hyperlinks/RubyHyperLinkDetector.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hyperlinks/RubyHyperLinkDetector.java
    (revision 0)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/hyperlinks/RubyHyperLinkDetector.java
    (revision 0)
@@ -0,0 +1,135 @@
+package org.rubypeople.rdt.internal.ui.text.ruby.hyperlinks;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.ui.IEditorInput;
+import org.jruby.ast.Node;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.codeassist.SelectionEngine;
+import org.rubypeople.rdt.internal.core.parser.RubyParser;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
+import org.rubypeople.rdt.ui.IWorkingCopyManager;
+import org.rubypeople.rdt.ui.extensions.ITextHoverProvider;
+import org.rubypeople.rdt.ui.text.hyperlinks.IHyperlinkProvider;
+
+public class RubyHyperLinkDetector implements IHyperlinkDetector {
+
+       public static final String RDT_UI_NAMESPACE = "org.rubypeople.rdt.ui";
+       public static final String RDT_UI_HYPERLINKPROVIDER = 
"hyperlinkProvider";
+       
+       
+       private List fExtensions;
+       private final IEditorInput fEditorInput;
+
+       
+       public RubyHyperLinkDetector(IEditorInput editorInput) {
+               this.fEditorInput = editorInput;
+       }
+
+       private List initExtensions() {
+               if(fExtensions == null){
+                       fExtensions = new ArrayList();
+                       IExtensionRegistry reg = 
Platform.getExtensionRegistry();
+                       IExtensionPoint[] points = 
reg.getExtensionPoints(RDT_UI_NAMESPACE);
+                       // TODO: Look for textProvider!
+                       IExtensionPoint point = null;
+                       
+                       if(points != null){
+                               for (int i = 0; i < points.length; i++) {
+                                       IExtensionPoint currentPoint = 
points[i];
+                                       String uniqueIdentifier = 
currentPoint.getUniqueIdentifier();
+                                       
if(uniqueIdentifier.endsWith(RDT_UI_HYPERLINKPROVIDER)){
+                                               point = currentPoint;
+                                               break;
+                                       }                               
+                               }
+                               
+                               if(point != null){
+                                       IExtension[] exts = 
point.getExtensions();
+                                       
+                                       IHyperlinkProvider prov = null;
+                                       
+                                       for (int i = 0; i < exts.length; i++) {
+                                               IConfigurationElement[] elem = 
exts[i].getConfigurationElements();
+                                               String attrs[] = 
elem[0].getAttributeNames();
+                                               try {
+                                                       Object tempProv = 
elem[0].createExecutableExtension("class");
+                                                       if (tempProv instanceof 
IHyperlinkProvider) {
+                                                               prov = 
(IHyperlinkProvider) tempProv;
+                                                               
fExtensions.add(prov);
+                                                       }
+//                                                     }
+                                               } catch (Exception e) {
+                                                       RubyPlugin.log(e);
+                                               }
+                                               
+                                       }
+                               }
+                       }
+                       
+               }
+               return fExtensions;
+               
+       }
+
+       
+       
+       public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
+                       IRegion region, boolean canShowMultipleHyperlinks) {
+               String symbol = "";
+               IRegion newRegion = region;
+//             newRegion = RubyWordFinder.findWord(textViewer.getDocument(), 
region.getOffset());
+//             try {
+//                     symbol = 
textViewer.getDocument().get(newRegion.getOffset(), newRegion.getLength());
+//             } catch (BadLocationException e) {
+//                     // TODO Auto-generated catch block
+//                     e.printStackTrace();
+//             }
+//             System.out.println("Symbol:" + symbol);
+//             return new IHyperlink[]{new RubyHyperLinkDetector(fEditorInput, 
newRegion, symbol)};
+
+               List extensions = initExtensions();
+//             final String symbol = 
textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength());
+               // first ask the extensions
+               if(extensions.size() > 0){
+                       SelectionEngine engine = new SelectionEngine();
+                       IWorkingCopyManager manager = 
RubyPlugin.getDefault().getWorkingCopyManager();
+                       IRubyScript script = 
manager.getWorkingCopy(fEditorInput);
+                       RubyParser parser = new RubyParser();
+                       try {
+                               Node root = parser.parse((IFile) 
script.getResource(),new StringReader(script.getSource()));
+                       //                              IRubyElement[] elements 
= engine.select(script, newRegion.getOffset(), newRegion.getOffset() + 
newRegion.getLength());
+                               for(int i=0; i< extensions.size(); i++){
+                                       IHyperlinkProvider currentProvider = 
(IHyperlinkProvider) extensions.get(i);
+                                       IHyperlink link = 
currentProvider.getHyperlink(fEditorInput, textViewer, root, newRegion, true);
+                                       // TODO: either do that or query all 
HyperlinkProviders and return a list of hyperlinks?
+                                       if(link != null){
+                                               return new IHyperlink[]{link};
+                                       }                                       
+                               }
+                       } catch (RubyModelException e) {
+                               RubyPlugin.log(e);
+                       }
+               }               
+
+               return null;
+               
+       }
+
+       
+
+}
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/extensions/ITextHoverProvider.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/extensions/ITextHoverProvider.java
  (revision 1673)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/extensions/ITextHoverProvider.java
  (working copy)
@@ -2,6 +2,7 @@
 
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.ui.IEditorInput;
 
 
 /**
@@ -17,5 +18,5 @@
         * @param hoverRegion the region that was preselected by the Ruby Hover 
system
         * @return the hover text OR null if no text was found 
         */
-       public String getHoverInfo(ITextViewer textViewer, IRegion 
hoverRegion);        
+       public String getHoverInfo(IEditorInput iei,ITextViewer textViewer, 
IRegion hoverRegion);       
 }
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
     (revision 1716)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/RubySourceViewerConfiguration.java
     (working copy)
@@ -62,7 +62,7 @@
 import org.rubypeople.rdt.internal.ui.text.ruby.RubyReconcilingStrategy;
 import org.rubypeople.rdt.internal.ui.text.ruby.SingleTokenRubyCodeScanner;
 import org.rubypeople.rdt.internal.ui.text.ruby.hover.RubyCodeTextHover;
-import org.rubypeople.rdt.ui.text.hyperlinks.RubyHyperLinkDetector;
+import 
org.rubypeople.rdt.internal.ui.text.ruby.hyperlinks.RubyHyperLinkDetector;
 
 public class RubySourceViewerConfiguration extends
                TextSourceViewerConfiguration {
@@ -159,12 +159,12 @@
                if (fTextEditor == null)
                        return inheritedDetectors;
 
-               int inheritedDetectorsLength = inheritedDetectors != null ? 
inheritedDetectors.length
-                               : 0;
+               int inheritedDetectorsLength = inheritedDetectors != null ? 
inheritedDetectors.length: 0;
                IHyperlinkDetector[] detectors = new 
IHyperlinkDetector[inheritedDetectorsLength + 1];
                detectors[0] = new 
RubyHyperLinkDetector(fTextEditor.getEditorInput());
-               for (int i = 0; i < inheritedDetectorsLength; i++)
+               for (int i = 0; i < inheritedDetectorsLength; i++) {
                        detectors[i + 1] = inheritedDetectors[i];
+               }
 
                return detectors;
        }
@@ -539,7 +539,7 @@
        public ITextHover getTextHover(ISourceViewer sourceViewer,
                        String contentType) {
                if (fRubyTextHover == null) {
-                       fRubyTextHover = new RubyCodeTextHover();
+                       fRubyTextHover = new RubyCodeTextHover(getEditor());
                }
                return fRubyTextHover;
        }
Index: 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/hyperlinks/IHyperlinkProvider.java
===================================================================
--- 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/hyperlinks/IHyperlinkProvider.java
     (revision 0)
+++ 
/home/murphee/projects/coding/workspace/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/text/hyperlinks/IHyperlinkProvider.java
     (revision 0)
@@ -0,0 +1,11 @@
+package org.rubypeople.rdt.ui.text.hyperlinks;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.IEditorInput;
+import org.jruby.ast.Node;
+
+public interface IHyperlinkProvider {
+   public IHyperlink getHyperlink(IEditorInput input,ITextViewer textViewer, 
Node node, IRegion region, boolean canShowMultipleHyperlinks);
+}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Rubyeclipse-development mailing list
Rubyeclipse-development@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rubyeclipse-development

Reply via email to