Commits

Anonymous committed 000db0a Merge

Merge replview with lispdev.

  • Participants
  • Parent commits be47ea9, fb50649

Comments (0)

Files changed (15)

+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.lispdev.replview</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

.settings/org.eclipse.jdt.core.prefs

+#Sun Jun 27 20:41:25 CDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6

META-INF/MANIFEST.MF

+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Replview
+Bundle-SymbolicName: org.lispdev.replview;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.lispdev.replview.ReplViewPlugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jface.text;bundle-version="3.5.2",
+ org.eclipse.debug.core;bundle-version="3.5.1",
+ org.eclipse.debug.ui;bundle-version="3.5.2",
+ org.eclipse.ui.console;bundle-version="3.4.0",
+ org.lispdev.console;bundle-version="1.0.0",
+ org.lispdev.swank;bundle-version="1.0.0",
+ org.lispdev.log;bundle-version="1.0.0",
+ org.lispdev.repl;bundle-version="1.0.0",
+ org.lispdev.main;bundle-version="1.0.0",
+ org.lispdev.console.core;bundle-version="1.0.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml

icons/exec-lisp.gif

Added
New image
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.debug.core.launchConfigurationTypes">
+      <launchConfigurationType
+            delegate="org.lispdev.replview.LocalLispLaunchDelegate"
+            id="org.lispdev.replview.localLaunchConfigurationType"
+            modes="run, debug"
+            name="Local Lisp"
+            public="true">
+      </launchConfigurationType>
+   </extension>
+   <extension
+         point="org.eclipse.ui.viewActions">
+      <viewContribution
+            id="org.lispdev.replview.debugViewContribution"
+            targetID="org.eclipse.debug.ui.DebugView">
+         <action
+               class="org.lispdev.replview.RestartActionDelegate"
+               id="org.lispdev.replview.restartaction"
+               label="Restarts"
+               style="pulldown"
+               toolbarPath="additions"
+               tooltip="Press for Default Restart">
+         </action>
+      </viewContribution>
+   </extension>
+   <extension
+         point="org.eclipse.debug.ui.launchConfigurationTypeImages">
+      <launchConfigurationTypeImage
+            configTypeID="org.lispdev.replview.localLaunchConfigurationType"
+            icon="icons/exec-lisp.gif"
+            id="org.lispdev.replview.lispLaunchConfigurationTypeImage">
+      </launchConfigurationTypeImage>
+   </extension>
+   <extension
+         point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+      <launchConfigurationTabGroup
+            class="org.lispdev.replview.LocalLaunchConfigurationTabGroup"
+            id="org.lispdev.replview.localLaunchConfigurationTabGroup"
+            type="org.lispdev.replview.localLaunchConfigurationType">
+      </launchConfigurationTabGroup>
+   </extension>
+   <extension
+         point="org.eclipse.debug.ui.debugModelPresentations">
+      <debugModelPresentation
+            class="org.lispdev.replview.DebugModelPresentation"
+            id="org.lispdev.debug.model">
+      </debugModelPresentation>
+   </extension>
+
+</plugin>

src/org/lispdev/replview/DebugModelPresentation.java

+package org.lispdev.replview;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.debug.ui.IDebugModelPresentationExtension;
+import org.eclipse.debug.ui.IValueDetailListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.ui.IEditorInput;
+import org.lispdev.log.Log;
+import org.lispdev.swank.debug.LispThread;
+
+public class DebugModelPresentation extends LabelProvider implements
+    IDebugModelPresentation, IDebugModelPresentationExtension
+{
+
+  @Override
+  public String getText(Object element)
+  {
+    if( element instanceof LispThread )
+    {
+      return getThreadText((LispThread)element);
+    }
+    return null;
+  }
+
+  private String getThreadText(LispThread thread)
+  {
+    String label = "";
+    try
+    {
+      label = thread.getName();
+    }
+    catch(DebugException e)
+    {
+      Log.logException(e);
+    }
+    if( thread.isSuspended() )
+    {
+      label += " : " + thread.getError();
+    }
+    return label;
+  }
+
+  @Override
+  public IEditorInput getEditorInput(Object element)
+  {
+    return null;
+  }
+
+  @Override
+  public String getEditorId(IEditorInput input, Object element)
+  {
+    return null;
+  }
+
+  @Override
+  public void setAttribute(String attribute, Object value)
+  {}
+
+  @Override
+  public void computeDetail(IValue value, IValueDetailListener listener)
+  {}
+
+  @Override
+  public boolean requiresUIThread(Object element)
+  {
+    return (element instanceof LispThread);
+  }
+
+}

src/org/lispdev/replview/LocalLaunchConfigurationTabGroup.java

+package org.lispdev.replview;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.EnvironmentTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+
+public class LocalLaunchConfigurationTabGroup extends
+    AbstractLaunchConfigurationTabGroup
+{
+
+  @Override
+  public void createTabs(ILaunchConfigurationDialog dialog, String mode)
+  {
+    setTabs(new ILaunchConfigurationTab[]{
+        new MainLocalLaunchConfigurationTab(),
+        new EnvironmentTab(),
+        new CommonTab()});
+  }
+
+}

src/org/lispdev/replview/LocalLispLaunchDelegate.java

+package org.lispdev.replview;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.lispdev.main.LispPerspectiveFactory;
+import org.lispdev.repl.SwankRunnableDriver;
+import org.lispdev.swank.BaseLocalLispLaunchDelegate;
+import org.lispdev.swank.debug.LispProcess;
+
+public class LocalLispLaunchDelegate extends BaseLocalLispLaunchDelegate
+    implements ILaunchConfigurationDelegate
+{
+  public final static String ID = BaseLocalLispLaunchDelegate.LOCAL_ID;
+
+  @Override
+  public void launch(ILaunchConfiguration config, String mode,
+      ILaunch launch, IProgressMonitor monitor) throws CoreException
+  {
+    Assert.isLegal(ILaunchManager.DEBUG_MODE.equals(mode) ||
+        ILaunchManager.RUN_MODE.equals(mode),
+        "Wrong mode");
+    LispProcess p = launch(config,launch,new SwankRunnableDriver());
+    final ReplConsole c = new ReplConsole("REPL: "+config.getName(), null, p);
+    final IConsoleManager cm = ConsolePlugin.getDefault().getConsoleManager();
+    cm.addConsoles(new IConsole[] {c});
+    final IWorkbench wk = PlatformUI.getWorkbench();
+    wk.getDisplay().asyncExec(new Runnable(){
+      @Override
+      public void run()
+      {
+        try
+        {
+          final IWorkbenchWindow w = wk.getActiveWorkbenchWindow();
+          wk.showPerspective(LispPerspectiveFactory.ID,w);
+          cm.showConsoleView(c);
+          c.setFocus();
+        }
+        catch(WorkbenchException e)
+        {
+          e.printStackTrace();
+        }
+      }
+    });
+  }
+
+}

src/org/lispdev/replview/MainLocalLaunchConfigurationTab.java

+package org.lispdev.replview;
+
+import java.io.File;
+import java.util.HashMap;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+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.Text;
+import org.lispdev.swank.AvailablePortFinder;
+import org.lispdev.swank.BaseLocalLispLaunchDelegate;
+
+public class MainLocalLaunchConfigurationTab extends
+    AbstractLaunchConfigurationTab
+{
+  private Text exeText;
+  private Text swankText;
+  private Text portText;
+  private Button startReplThreadBox;
+
+  @Override
+  public void createControl(Composite parent)
+  {
+    Font font = parent.getFont();
+
+    Composite comp = new Composite(parent, SWT.NONE);
+    setControl(comp);
+    GridLayout topLayout = new GridLayout();
+    topLayout.verticalSpacing = 0;
+    topLayout.numColumns = 3;
+    comp.setLayout(topLayout);
+    comp.setFont(font);
+
+    createVerticalSpacer(comp, 3);
+
+    Label exeLabel = new Label(comp, SWT.NONE);
+    exeLabel.setText("&Lisp Executable:");
+    GridData gd = new GridData(GridData.BEGINNING);
+    exeLabel.setLayoutData(gd);
+    exeLabel.setFont(font);
+
+    exeText = new Text(comp, SWT.SINGLE | SWT.BORDER);
+    gd = new GridData(GridData.FILL_HORIZONTAL);
+    exeText.setLayoutData(gd);
+    exeText.setFont(font);
+    exeText.addModifyListener(new ModifyListener(){
+      public void modifyText(ModifyEvent e)
+      {
+        updateLaunchConfigurationDialog();
+      }
+    });
+
+    final Button exeButton = createPushButton(comp, "&Browse...", null);
+    exeButton.addSelectionListener(new SelectionAdapter() {
+      @Override
+      public void widgetSelected(SelectionEvent e)
+      {
+        final FileDialog fd = new FileDialog(getShell(), SWT.OPEN);
+        fd.setText("Open Lisp Executable");
+
+        if( System.getProperty("os.name").toLowerCase().contains("windows"))
+        {
+          fd.setFilterExtensions(new String[] {"*.exe"});
+        }
+        exeText.setText(fd.open());
+      }
+    });
+
+    createVerticalSpacer(comp, 3);
+
+    Label swankLabel = new Label(comp, SWT.NONE);
+    swankLabel.setText("&Swank Loader Folder:");
+    gd = new GridData(GridData.BEGINNING);
+    swankLabel.setLayoutData(gd);
+    swankLabel.setFont(font);
+
+    swankText = new Text(comp, SWT.SINGLE | SWT.BORDER);
+    gd = new GridData(GridData.FILL_HORIZONTAL);
+    swankText.setLayoutData(gd);
+    swankText.setFont(font);
+    swankText.addModifyListener(new ModifyListener(){
+      public void modifyText(ModifyEvent e)
+      {
+        updateLaunchConfigurationDialog();
+      }
+    });
+
+    final Button swankButton = createPushButton(comp, "B&rowse...", null);
+    swankButton.addSelectionListener(new SelectionAdapter(){
+      @Override
+      public void widgetSelected(SelectionEvent e)
+      {
+        final DirectoryDialog dd = new DirectoryDialog(getShell(), SWT.OPEN);
+        dd.setText("Open folder containing swank-loader.lisp");
+        swankText.setText(dd.open());
+      }
+    });
+
+    createVerticalSpacer(comp, 3);
+
+    Label portLabel = new Label(comp, SWT.NONE);
+    portLabel.setText("&Port:");
+    gd = new GridData(GridData.BEGINNING);
+    portLabel.setLayoutData(gd);
+    portLabel.setFont(font);
+
+    portText = new Text(comp,SWT.BORDER);
+    gd = new GridData(GridData.FILL_HORIZONTAL);
+    portText.setLayoutData(gd);
+    portText.setFont(font);
+    portText.addListener(SWT.Verify, new Listener(){
+      public void handleEvent(Event e)
+      {
+        String string = e.text;
+        char[] chars = new char[string.length()];
+        string.getChars(0, chars.length, chars, 0);
+        for(int i = 0; i < chars.length; i++)
+        {
+          if( !('0' <= chars[i] && chars[i] <= '9') )
+          {
+            e.doit = false;
+            return;
+          }
+        }
+      }
+    });
+    portText.addModifyListener(new ModifyListener() {
+      public void modifyText(ModifyEvent e) {
+        updateLaunchConfigurationDialog();
+      }
+    });
+    new Label(comp, SWT.NONE).setText("");
+
+    createVerticalSpacer(comp, 3);
+    startReplThreadBox =
+      createCheckButton(comp, "&Explicitely start repl thread");
+    startReplThreadBox.addSelectionListener(new SelectionAdapter(){
+      @Override
+      public void widgetSelected(SelectionEvent e)
+      {
+        updateLaunchConfigurationDialog();
+      }
+    });
+    new Label(comp, SWT.NONE).setText("");
+    new Label(comp, SWT.NONE).setText("");
+  }
+
+  @Override
+  public String getName()
+  {
+    return "Main";
+  }
+
+  @Override
+  public void initializeFrom(ILaunchConfiguration c)
+  {
+    try
+    {
+      exeText.setText(BaseLocalLispLaunchDelegate.getExePath(c));
+      swankText.setText(BaseLocalLispLaunchDelegate.getSwankLoaderDir(c));
+      portText.setText(String.valueOf(BaseLocalLispLaunchDelegate.getPort(c)));
+      startReplThreadBox.setSelection(
+          BaseLocalLispLaunchDelegate.getStartReplThread(c));
+    }
+    catch(CoreException e)
+    {
+      setErrorMessage(e.getMessage());
+    }
+  }
+
+  @Override
+  public void performApply(ILaunchConfigurationWorkingCopy wc)
+  {
+    BaseLocalLispLaunchDelegate.setExePath(wc, exeText.getText());
+    BaseLocalLispLaunchDelegate.setSwankLoaderDir(wc, swankText.getText());
+    BaseLocalLispLaunchDelegate.setPort(wc,
+        Integer.parseInt(portText.getText()));
+    BaseLocalLispLaunchDelegate.setStartReplThread(wc,
+        startReplThreadBox.getSelection());
+  }
+
+  @Override
+  public void setDefaults(ILaunchConfigurationWorkingCopy wc)
+  {
+    BaseLocalLispLaunchDelegate.setExePath(wc,
+        "D:\\projects\\lispdev\\ws\\org.lispdev.swank\\sbcl\\sbcl.exe");
+    BaseLocalLispLaunchDelegate.setSwankLoaderDir(wc,
+        "D:\\projects\\lispdev\\ws\\org.lispdev.swank\\slime\\");
+    BaseLocalLispLaunchDelegate.setEnvVars(wc,
+        new HashMap<String, String>(){
+          private static final long serialVersionUID = 1L;
+          {
+            put("SBCL_HOME",
+                "D:\\projects\\lispdev\\ws\\org.lispdev.swank\\sbcl\\");
+          }
+        });
+    BaseLocalLispLaunchDelegate.setLispExtDir(wc,
+        "D:\\projects\\lispdev\\ws\\org.lispdev.swank\\");
+    BaseLocalLispLaunchDelegate.setPort(wc, 4005);
+    BaseLocalLispLaunchDelegate.setStartReplThread(wc,false);
+  }
+
+  @Override
+  public boolean isValid(ILaunchConfiguration launchConfig)
+  {
+    setErrorMessage(null);
+    setMessage(null);
+    if( exeText.getText().length() > 0 )
+    {
+      File cmd = new File(exeText.getText());
+      if( !cmd.exists() )
+      {
+        setErrorMessage("The lisp program file does not exist");
+        return false;
+      }
+      if( !cmd.canExecute() )
+      {
+        setErrorMessage("The lisp program file is not executable");
+        return false;
+      }
+    }
+    if ( swankText.getText().length() > 0 )
+    {
+      File swankf = new File(swankText.getText(),"swank-loader.lisp");
+      if( !swankf.exists() )
+      {
+        setErrorMessage("Swank was not found in the specified folder");
+        return false;
+      }
+    }
+    if ( portText.getText().length() > 0 )
+    {
+      try
+      {
+        int p = Integer.parseInt(portText.getText());
+        if( p < AvailablePortFinder.MIN_PORT_NUMBER
+            || p > AvailablePortFinder.MAX_PORT_NUMBER )
+        {
+          setErrorMessage("Port should be an integer between "+
+              AvailablePortFinder.MIN_PORT_NUMBER + " and " +
+              AvailablePortFinder.MAX_PORT_NUMBER);
+          return false;
+        }
+      }
+      catch(NumberFormatException e)
+      {
+        setErrorMessage("Port should be an integer number");
+        return false;
+      }
+    }
+    if( exeText.getText().length() == 0 )
+    {
+      setMessage("Specify lisp program");
+    }
+    else if ( swankText.getText().length() == 0 )
+    {
+      setMessage("Specify swank folder");
+    }
+    else if ( portText.getText().length() == 0 )
+    {
+      setMessage("Specify port");
+    }
+    return true;
+  }
+}

src/org/lispdev/replview/ReplConsole.java

+package org.lispdev.replview;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.console.AbstractConsole;
+import org.eclipse.ui.console.IConsoleView;
+import org.eclipse.ui.part.IPageBookViewPage;
+import org.lispdev.swank.debug.LispProcess;
+
+public class ReplConsole extends AbstractConsole
+{
+  private final LispProcess process;
+  private IPageBookViewPage page;
+
+  public ReplConsole(String name, ImageDescriptor imageDescriptor,
+      LispProcess pr)
+  {
+    super(name, imageDescriptor);
+    process = pr;
+  }
+
+  @Override
+  public IPageBookViewPage createPage(IConsoleView view)
+  {
+    page = new ReplConsolePage(process);
+    return page;
+  }
+
+  public void setFocus()
+  {
+    if( page != null )
+    {
+      page.setFocus();
+    }
+  }
+
+  @Override
+  protected void dispose()
+  {
+    super.dispose();
+    try
+    {
+      process.terminate();
+    }
+    catch(DebugException e)
+    {
+      e.printStackTrace();
+    }
+  }
+
+}

src/org/lispdev/replview/ReplConsolePage.java

+package org.lispdev.replview;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.source.VerticalRuler;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.IPageBookViewPage;
+import org.eclipse.ui.part.IPageSite;
+import org.lispdev.console.ConsoleEnterTrigger;
+import org.lispdev.console.IConsoleInputListener;
+import org.lispdev.console.LispConsoleViewer;
+import org.lispdev.console.PartitionData;
+import org.lispdev.console.Prompt;
+import org.lispdev.console.core.IPartitionData;
+import org.lispdev.console.core.IVariableResolver;
+import org.lispdev.log.Log;
+import org.lispdev.repl.AbstractRepl;
+import org.lispdev.repl.IState;
+import org.lispdev.repl.ReadState;
+import org.lispdev.swank.ISwank;
+import org.lispdev.swank.debug.LispDebugTarget;
+import org.lispdev.swank.debug.LispProcess;
+import org.lispdev.swank.debug.LispThread;
+import org.lispdev.swank.runnables.SwankDebugRunnable.DebugInfo;
+
+public class ReplConsolePage implements IPageBookViewPage
+{
+  private IPageSite fSite;
+
+  private LispConsoleViewer replConsole; //viewer
+  private Repl repl;
+  private final LispProcess process;
+  private ConsoleEnterTrigger enterTrigger;
+
+  private void setStatusMessage(String msg)
+  {
+    fSite.getActionBars().getStatusLineManager().setMessage(msg);
+  }
+
+  /**
+   * Constructs a repl console page corresponding to given process
+   */
+  public ReplConsolePage(LispProcess pr)
+  {
+    process = pr;
+  }
+
+
+  private class Repl extends AbstractRepl implements IConsoleInputListener
+  {
+    public Repl(ISwank s)
+    {
+      super(s);
+    }
+
+    @Override
+    public void appendOut(String text)
+    {
+      replConsole.appendText(text, null, true);
+    }
+
+    @Override
+    public void appendOutInspectable(String text, String id)
+    {
+      replConsole.appendText(text,"inspectable",id, null, true);
+    }
+
+    @Override
+    protected void applyState(IState s)
+    {
+      if( s instanceof ReadState )
+      {
+        replConsole.setPrompt(new Prompt("", "read-context","1",null,false));
+        enterTrigger.setDoIt(true);
+        enterTrigger.setStateMask(SWT.NONE);
+        doInput();
+      }
+    }
+
+    @Override
+    public void packageChanged(String pkg)
+    {
+      replConsole.setPrompt(
+          new Prompt(pkg.toUpperCase()+">", pkg, "1", null,null,SWT.BOLD,false));
+    }
+
+    @Override
+    public void saveCommandToHistory(String command)
+    {
+    }
+
+    @Override
+    public void run(String msg, int offset, PartitionData pd, VerifyEvent event)
+    {
+      replConsole.setPrompt(
+          new Prompt(swank.getCurrPackage().toUpperCase()+">",
+              swank.getCurrPackage(), "1", null,null,SWT.BOLD,false));
+      enterTrigger.setDoIt(false);
+      enterTrigger.setStateMask(SWT.SHIFT);
+      eval(msg);
+    }
+
+    @Override
+    public void doInput()
+    {
+      replConsole.startEdit();
+    }
+
+    @Override
+    public void disconnected()
+    {
+      setStatusMessage("Not connected");
+    }
+
+    @Override
+    public void connected()
+    {
+      setStatusMessage(swank.getLispVersion());
+    }
+
+    @Override
+    public void connecting()
+    {
+      setStatusMessage("Connecting to Lisp ...");
+    }
+
+    @Override
+    public void disconnecting()
+    {
+      replConsole.appendText("Quitting Lisp ...\n", null, true);
+    }
+
+    @Override
+    public void debugStoped()
+    {
+      try
+      {
+        process.getLaunch().getDebugTarget().getThreads()[0].resume();
+        process.getLaunch().getDebugTarget().resume();
+        try
+        {
+          IDebugView view = (IDebugView)PlatformUI.getWorkbench()
+            .getActiveWorkbenchWindow().getActivePage()
+            .showView(IDebugUIConstants.ID_DEBUG_VIEW,
+                null,IWorkbenchPage.VIEW_CREATE);
+          Viewer viewer = view.getViewer();
+          viewer.refresh();
+          viewer.getControl().setToolTipText(null);
+        }
+        catch(PartInitException e)
+        {
+          Log.logException("Could not get debug view", e);
+        }
+      }
+      catch(DebugException e)
+      {
+        Log.logException(e);
+      }
+    }
+
+    @Override
+    public void startDebug(DebugInfo debugInfo)
+    {
+      try
+      {
+        ((LispThread)process.getLaunch().getDebugTarget().getThreads()[0])
+          .setSuspended(debugInfo);
+        try
+        {
+          IDebugView view = (IDebugView)PlatformUI.getWorkbench()
+            .getActiveWorkbenchWindow().getActivePage()
+            .showView(IDebugUIConstants.ID_DEBUG_VIEW);
+          Viewer viewer = view.getViewer();
+          viewer.getControl().setToolTipText(debugInfo.description);
+        }
+        catch(PartInitException e)
+        {
+          Log.logException("Could not get debug view", e);
+        }
+      }
+      catch(DebugException e)
+      {
+        Log.logException(e);
+      }
+    }
+
+  }
+
+  final IPropertyChangeListener fontListener = new IPropertyChangeListener(){
+
+    @Override
+    public void propertyChange(PropertyChangeEvent event)
+    {
+      if( event.getProperty().equals("org.eclipse.jface.textfont")
+          && replConsole != null )
+      {
+        replConsole.getTextWidget().setFont(JFaceResources.getTextFont());
+      }
+    }
+  };
+
+  @Override
+  public IPageSite getSite()
+  {
+    return fSite;
+  }
+
+  @Override
+  public void init(IPageSite site) throws PartInitException
+  {
+    fSite = site;
+  }
+
+  @Override
+  public void createControl(Composite parent)
+  {
+    repl = new Repl(process.getSwank());
+    replConsole = new LispConsoleViewer(parent/*comp*/, new VerticalRuler(10),
+        SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.LEFT | SWT.BORDER,
+        new IVariableResolver(){
+
+          @Override
+          public IVariable resolve(String txt, IPartitionData data)
+          {
+            if( data == null || data.getContext() == null
+                || !data.getContext().equals("inspectable") )
+            {
+              return null;
+            }
+            return process.getSwank().getLispImplementation().
+              inspectReplResult(
+                  (LispDebugTarget)process.getLaunch().getDebugTarget(),
+                  txt, data);
+          }
+        });
+    replConsole.getTextWidget().setFont(JFaceResources.getTextFont());
+    JFaceResources.getFontRegistry().addListener(fontListener);
+
+    enterTrigger =
+      new ConsoleEnterTrigger(replConsole,SWT.SHIFT,
+          LispConsoleViewer.BEFORE,false);
+
+    enterTrigger.addInputListener(repl);
+    replConsole.getTextWidget().addVerifyKeyListener(enterTrigger);
+    replConsole.setPrompt(
+        new Prompt("CL-USER>","prompt","0",null,null,SWT.BOLD,false));
+    replConsole.startEdit();
+    repl.disconnected();
+    if( process.getSwank().isConnected() )
+    {
+      repl.packageChanged(repl.swank.getCurrPackage());
+      repl.connected();
+    }
+  }
+
+  @Override
+  public void dispose()
+  {
+    JFaceResources.getFontRegistry().removeListener(fontListener);
+    repl.dispose();
+  }
+
+  @Override
+  public Control getControl()
+  {
+    return replConsole != null ? replConsole.getControl() : null;
+  }
+
+  @Override
+  public void setActionBars(IActionBars actionBars)
+  {
+  }
+
+  @Override
+  public void setFocus()
+  {
+    if( replConsole != null )
+    {
+      replConsole.getTextWidget().setFocus();
+    }
+  }
+
+}

src/org/lispdev/replview/ReplViewPlugin.java

+package org.lispdev.replview;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class ReplViewPlugin extends AbstractUIPlugin
+{
+
+  // The plug-in ID
+  public static final String ID = "org.lispdev.replview";
+
+  // The shared instance
+  private static ReplViewPlugin plugin;
+
+  public ReplViewPlugin()
+  {}
+
+  @Override
+  public void start(BundleContext context) throws Exception
+  {
+    super.start(context);
+    plugin = this;
+  }
+
+  @Override
+  public void stop(BundleContext context) throws Exception
+  {
+    plugin = null;
+    super.stop(context);
+  }
+
+  /**
+   * Returns the shared instance
+   *
+   * @return the shared instance
+   */
+  public static ReplViewPlugin get()
+  {
+    return plugin;
+  }
+
+}

src/org/lispdev/replview/RestartActionDelegate.java

+package org.lispdev.replview;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.window.DefaultToolTip;
+import org.eclipse.jface.window.ToolTip;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ArmEvent;
+import org.eclipse.swt.events.ArmListener;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.ui.IViewActionDelegate;
+import org.eclipse.ui.IViewPart;
+import org.lispdev.swank.debug.LispDebugTarget;
+import org.lispdev.swank.debug.LispStackFrame;
+import org.lispdev.swank.debug.LispThread;
+import org.lispdev.swank.runnables.SwankDebugRunnable.DebugInfo;
+import org.lispdev.swank.runnables.SwankDebugRunnable.DebugInfo.SwankDebugRestart;
+
+public class RestartActionDelegate implements IViewActionDelegate, IMenuCreator
+{
+  private IAction action;
+  private IViewPart view;
+  private Menu menu;
+  private LispThread thread = null;
+
+  private class MenuTooltipListener implements ArmListener, MenuListener
+  {
+    private final DefaultToolTip tip;
+    private final Control control;
+
+    public MenuTooltipListener(Control control)
+    {
+      this.control = control;
+      tip = new DefaultToolTip(control, ToolTip.RECREATE, true);
+    }
+
+    public void widgetArmed(ArmEvent e)
+    {
+      tip.setText(((ActionContributionItem)((MenuItem)e.widget).getData())
+          .getAction().getToolTipText());
+      tip.setPopupDelay(200);
+      tip.setHideDelay(3000);
+      Point p = control.toControl(control.getDisplay().getCursorLocation());
+      p.x += 60;
+      tip.show(p);
+    }
+
+    public void menuHidden(MenuEvent e)
+    {
+      tip.hide();
+    }
+
+    public void menuShown(MenuEvent e)
+    {
+    }
+  }
+
+  @Override
+  public void init(IViewPart view)
+  {
+    this.view = view;
+  }
+
+  @Override
+  public void run(IAction action)
+  {
+    if( thread != null && thread.isSuspended() )
+    {
+      thread.getSwank().sendQuitDebug(null, thread.getDebugInfo().thread);
+    }
+    else
+    {
+      MessageBox box =
+        new MessageBox(view.getSite().getShell(),SWT.ICON_INFORMATION);
+      box.setMessage("Thread is not suspended");
+      box.open();
+    }
+  }
+
+  @Override
+  public void selectionChanged(IAction action, ISelection selection)
+  {
+    if( action != this.action )
+    {
+      action.setMenuCreator(this);
+      this.action = action;
+    }
+    thread = null;
+    if( selection instanceof TreeSelection )
+    {
+      Object obj = ((TreeSelection)selection).getFirstElement();
+      if(obj instanceof LispDebugTarget)
+      {
+        thread = ((LispDebugTarget)obj).getMainThread();
+      }
+      else if( obj instanceof LispThread )
+      {
+        thread = (LispThread)obj;
+      }
+      else if( obj instanceof LispStackFrame )
+      {
+        thread = (LispThread)((LispStackFrame)obj).getThread();
+      }
+    }
+    action.setEnabled(thread != null && thread.isSuspended());
+  }
+
+  @Override
+  public void dispose()
+  {
+    if(menu != null)
+    {
+      menu.dispose();
+      menu = null;
+    }
+  }
+
+  @Override
+  public Menu getMenu(Control parent)
+  {
+    if(menu != null)
+    {
+      menu.dispose();
+      menu = null;
+    }
+
+    if( thread != null && thread.isSuspended() )
+    {
+      menu = new Menu(parent);
+      MenuTooltipListener listener = new MenuTooltipListener(menu.getShell());
+      int i = 0;
+      final DebugInfo info = thread.getDebugInfo();
+      for( SwankDebugRestart r : info.restarts )
+      {
+        final int ii = i;
+        Action a = new Action(r.name){
+          @Override
+          public void run()
+          {
+            thread.getSwank().sendDebug(ii, info, null);
+          }
+        };
+        ++i;
+        a.setDescription(r.description);
+        a.setToolTipText(r.description);
+        addActionToMenu(menu, a, listener);
+      }
+
+      //new MenuItem(menu, SWT.SEPARATOR);
+    }
+
+    return menu;
+  }
+
+  protected void addActionToMenu(Menu parent, Action action,
+      ArmListener listener)
+  {
+    ActionContributionItem item = new ActionContributionItem(action);
+    item.fill(parent, -1);
+    MenuItem mi = parent.getItem(parent.getItemCount()-1);
+    mi.addArmListener(listener);
+  }
+
+  @Override
+  public Menu getMenu(Menu parent)
+  {
+    return null;
+  }
+}