Skip to content
Browse files

initial commit: first go at command history in ghci console

  • Loading branch information...
1 parent 405eded commit fc7051ff0dd230811530038f926c88f490bac5c8 @JPMoresmau committed Jun 27, 2012
Showing with 525 additions and 100 deletions.
  1. +4 −4 net.sf.eclipsefp.haskell-feature/feature.xml
  2. +1 −1 net.sf.eclipsefp.haskell.debug.core/META-INF/MANIFEST.MF
  3. +7 −0 net.sf.eclipsefp.haskell.debug.core/plugin.xml
  4. +64 −60 ...lipsefp.haskell.debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/HaskellDebugCore.java
  5. +22 −13 ...g.core/src/net/sf/eclipsefp/haskell/debug/core/internal/launch/AbstractHaskellLaunchDelegate.java
  6. +5 −3 ...ell.debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/launch/HaskellLaunchDelegate.java
  7. +1 −0 .../src/net/sf/eclipsefp/haskell/debug/core/internal/launch/IInteractiveLaunchOperationDelegate.java
  8. +57 −0 ...askell.debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/launch/REPLProcessFactory.java
  9. +2 −2 net.sf.eclipsefp.haskell.debug.ui/META-INF/MANIFEST.MF
  10. BIN net.sf.eclipsefp.haskell.debug.ui/icons/etool16/history16.gif
  11. +1 −1 net.sf.eclipsefp.haskell.debug.ui/plugin.properties
  12. +12 −12 net.sf.eclipsefp.haskell.debug.ui/plugin.xml
  13. +2 −0 ...ll.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/internal/launch/InteractiveLaunchOperation.java
  14. +2 −0 ...ug.ui/src/net/sf/eclipsefp/haskell/debug/ui/internal/launch/ghci/GhciLaunchOperationDelegate.java
  15. +1 −0 ...rc/net/sf/eclipsefp/haskell/debug/ui/internal/launch/yesod/YesodDevelLaunchOperationDelegate.java
  16. +2 −0 net.sf.eclipsefp.haskell.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/internal/util/UITexts.java
  17. +2 −0 ...eclipsefp.haskell.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/internal/util/uitexts.properties
  18. +179 −0 net.sf.eclipsefp.haskell.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/repl/HistoryAction.java
  19. +82 −0 net.sf.eclipsefp.haskell.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/repl/HistoryParticipant.java
  20. +1 −1 net.sf.eclipsefp.haskell.hlint/META-INF/MANIFEST.MF
  21. +1 −1 net.sf.eclipsefp.haskell.hugs/META-INF/MANIFEST.MF
  22. +6 −2 net.sf.eclipsefp.haskell.ui/plugin.xml
  23. +71 −0 net.sf.eclipsefp.haskell.util/src/net/sf/eclipsefp/haskell/util/BinaryStreamRedirect.java
View
8 net.sf.eclipsefp.haskell-feature/feature.xml
@@ -100,7 +100,7 @@ available at http://www.eclipse.org/legal/epl-v10.html.
id="net.sf.eclipsefp.haskell.hugs"
download-size="0"
install-size="0"
- version="2.3.0"
+ version="2.3.1"
unpack="false"/>
<plugin
@@ -114,14 +114,14 @@ available at http://www.eclipse.org/legal/epl-v10.html.
id="net.sf.eclipsefp.haskell.debug.ui"
download-size="0"
install-size="0"
- version="2.3.0"
+ version="2.3.1"
unpack="false"/>
<plugin
id="net.sf.eclipsefp.haskell.debug.core"
download-size="0"
install-size="0"
- version="2.3.0"
+ version="2.3.1"
unpack="false"/>
<plugin
@@ -149,7 +149,7 @@ available at http://www.eclipse.org/legal/epl-v10.html.
id="net.sf.eclipsefp.haskell.hlint"
download-size="0"
install-size="0"
- version="2.3.0"
+ version="2.3.1"
unpack="false"/>
<plugin
View
2 net.sf.eclipsefp.haskell.debug.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: net.sf.eclipsefp.haskell.debug.core;singleton:=true
-Bundle-Version: 2.3.0
+Bundle-Version: 2.3.1
Bundle-Activator: net.sf.eclipsefp.haskell.debug.core.internal.HaskellDebugCore
Bundle-Vendor: %bundleVendor
Require-Bundle: org.eclipse.core.runtime,
View
7 net.sf.eclipsefp.haskell.debug.core/plugin.xml
@@ -87,6 +87,13 @@
id="net.sf.eclipsefp.haskell.debug.core.sourcePathComputer">
</sourcePathComputer>
</extension>
+ <extension point="org.eclipse.debug.core.processFactories">
+ <processFactory
+ id="net.sf.eclipsefp.haskell.debug.core.launch.REPLProcessFactory"
+ class="net.sf.eclipsefp.haskell.debug.core.internal.launch.REPLProcessFactory">
+ </processFactory>
+ </extension>
+
<!-- <extension
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
View
124 ...haskell.debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/HaskellDebugCore.java
@@ -1,60 +1,64 @@
-// Copyright (c) 2008 by Leif Frenzel. All rights reserved.
-// This code is made available under the terms of the Eclipse Public License,
-// version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
-package net.sf.eclipsefp.haskell.debug.core.internal;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtensionRegistry;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.Plugin;
-import org.eclipse.core.runtime.Status;
-import org.osgi.framework.BundleContext;
-
-/** <p>The main plugin class for the Haskell Debug Core.</p>
- *
- * @author Leif Frenzel
- */
-public class HaskellDebugCore extends Plugin {
-
- public static final String ID_HASKELL_DEBUG_MODEL = "net.sf.eclipsefp.haskell.debug"; //$NON-NLS-1$
-
- public static final String ID_EXT_POINT_INTERACTIVE_DELEGATES = "interactiveDelegates"; //$NON-NLS-1$
-
- // The shared instance
- private static HaskellDebugCore plugin;
-
- public static HaskellDebugCore getDefault() {
- return plugin;
- }
-
- public static String getPluginId() {
- return getDefault().getBundle().getSymbolicName();
- }
-
- public IConfigurationElement[] getExtensions(final String key) {
- IExtensionRegistry registry = Platform.getExtensionRegistry();
- return registry.getConfigurationElementsFor(getPluginId(), key);
- }
-
- // interface methods of Activator
- /////////////////////////////////
-
- @Override
- public void start( final BundleContext context ) throws Exception {
- super.start( context );
- plugin = this;
- }
-
- @Override
- public void stop( final BundleContext context ) throws Exception {
- plugin = null;
- super.stop( context );
- }
-
- public static void log( final String message, final Throwable thr ) {
- String id = getPluginId();
- Status status = new Status( IStatus.ERROR, id, IStatus.OK, message, thr );
- getDefault().getLog().log( status );
- }
-}
+// Copyright (c) 2008 by Leif Frenzel. All rights reserved.
+// This code is made available under the terms of the Eclipse Public License,
+// version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+package net.sf.eclipsefp.haskell.debug.core.internal;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.BundleContext;
+
+/** <p>The main plugin class for the Haskell Debug Core.</p>
+ *
+ * @author Leif Frenzel
+ */
+public class HaskellDebugCore extends Plugin {
+
+ public static final String ID_HASKELL_DEBUG_MODEL = "net.sf.eclipsefp.haskell.debug"; //$NON-NLS-1$
+
+ public static final String ID_EXT_POINT_INTERACTIVE_DELEGATES = "interactiveDelegates"; //$NON-NLS-1$
+
+ /**
+ * constant for command history enablement on process
+ */
+ public static final String PROCESS_COMMAND_HISTORY ="net.sf.eclipse.haskell.debug.commandHistory" ; //$NON-NLS-1$
+ // The shared instance
+ private static HaskellDebugCore plugin;
+
+ public static HaskellDebugCore getDefault() {
+ return plugin;
+ }
+
+ public static String getPluginId() {
+ return getDefault().getBundle().getSymbolicName();
+ }
+
+ public IConfigurationElement[] getExtensions(final String key) {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ return registry.getConfigurationElementsFor(getPluginId(), key);
+ }
+
+ // interface methods of Activator
+ /////////////////////////////////
+
+ @Override
+ public void start( final BundleContext context ) throws Exception {
+ super.start( context );
+ plugin = this;
+ }
+
+ @Override
+ public void stop( final BundleContext context ) throws Exception {
+ plugin = null;
+ super.stop( context );
+ }
+
+ public static void log( final String message, final Throwable thr ) {
+ String id = getPluginId();
+ Status status = new Status( IStatus.ERROR, id, IStatus.OK, message, thr );
+ getDefault().getLog().log( status );
+ }
+}
View
35 ...rc/net/sf/eclipsefp/haskell/debug/core/internal/launch/AbstractHaskellLaunchDelegate.java
@@ -11,6 +11,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import net.sf.eclipsefp.haskell.core.HaskellCorePlugin;
import net.sf.eclipsefp.haskell.core.util.ResourceUtil;
import net.sf.eclipsefp.haskell.debug.core.internal.HaskellDebugCore;
import net.sf.eclipsefp.haskell.debug.core.internal.util.CoreTexts;
@@ -116,20 +117,27 @@ public void launch( final ILaunchConfiguration configuration,
@Override
protected IStatus run( final IProgressMonitor mon ) {
- while( !theProcess.isTerminated() ) {
- try {
- if( mon.isCanceled()) {
- theProcess.terminate();
- return Status.CANCEL_STATUS;
+ try {
+ while( !theProcess.isTerminated() ) {
+ try {
+ if( mon.isCanceled()) {
+ theProcess.terminate();
+ return Status.CANCEL_STATUS;
+ }
+ Thread.sleep( 50 );
+ } catch( InterruptedException iex ) {
+ // ignored
+ } catch ( DebugException ex ) {
+ // ignored
}
- Thread.sleep( 50 );
- } catch( InterruptedException iex ) {
- // ignored
- } catch ( DebugException ex ) {
- // ignored
+ }
+ } finally {
+ try {
+ postProcessFinished(configuration);
+ } catch(CoreException ce){
+ HaskellCorePlugin.log( ce );
}
}
- postProcessFinished(configuration);
return Status.OK_STATUS;
}
};
@@ -161,7 +169,7 @@ protected abstract void preProcessCreation(final ILaunchConfiguration configurat
final String mode,final ILaunch launch,Map<String, String> processAttribs) throws CoreException;
protected abstract void preProcessDefinitionCreation(final ILaunchConfiguration configuration,
final String mode,final ILaunch launch) throws CoreException;
- protected abstract void postProcessFinished(final ILaunchConfiguration configuration);
+ protected abstract void postProcessFinished(final ILaunchConfiguration configuration) throws CoreException;
private IProcess createProcess( final ILaunchConfiguration configuration,
final String mode, final ILaunch launch, final IPath location,
@@ -177,12 +185,13 @@ private IProcess createProcess( final ILaunchConfiguration configuration,
}
try {
preProcessDefinitionCreation( configuration, mode, launch );
- Process proc = pb.start();
+
Map<String, String> processAttrs = new HashMap<String, String>();
String programName = determineProgramName( location );
processAttrs.put( IProcess.ATTR_PROCESS_TYPE, programName );
preProcessCreation( configuration, mode, launch, processAttrs );
IProcess process = null;
+ Process proc = pb.start();
if( proc != null ) {
//String loc = location.toOSString();
process = DebugPlugin.newProcess( launch, proc, configuration.getName(), processAttrs );
View
8 ...g.core/src/net/sf/eclipsefp/haskell/debug/core/internal/launch/HaskellLaunchDelegate.java
@@ -30,19 +30,21 @@
*/
public class HaskellLaunchDelegate extends AbstractHaskellLaunchDelegate {
+
// static final String DEBUG_PROCESS_TYPE = "net.sf.eclipsefp.haskell.debug.ui.internal.launch.ghci.GhciProcessType"; //$NON-NLS-1$
@Override
protected void preProcessCreation( final ILaunchConfiguration configuration,
final String mode, final ILaunch launch, final Map<String, String> processAttribs ) {
- /*if (mode.equals( ILaunchManager.DEBUG_MODE )){
- processAttribs.put( IProcess.ATTR_PROCESS_TYPE, DEBUG_PROCESS_TYPE );
- }*/
+ // NOOP
}
@Override
protected void postProcessCreation( final ILaunchConfiguration configuration,
final String mode, final ILaunch launch, final IProcess process ) throws CoreException{
+
+ process.setAttribute( HaskellDebugCore.PROCESS_COMMAND_HISTORY, Boolean.TRUE.toString() );
+
if (mode.equals( ILaunchManager.DEBUG_MODE )){
HaskellDebugTarget hdt=new HaskellDebugTarget( launch, process );
launch.addDebugTarget(hdt);
View
1 .../sf/eclipsefp/haskell/debug/core/internal/launch/IInteractiveLaunchOperationDelegate.java
@@ -32,4 +32,5 @@
* @return the reload command, or null
*/
String getReloadCommand();
+
}
View
57 ...ebug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/launch/REPLProcessFactory.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.debug.core.internal.launch;
+
+import java.util.Map;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.IProcessFactory;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IStreamsProxy;
+import org.eclipse.debug.core.model.RuntimeProcess;
+
+
+/**
+ * @author JP Moresmau
+ *
+ */
+public class REPLProcessFactory implements IProcessFactory {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.IProcessFactory#newProcess(org.eclipse.debug.core.ILaunch, java.lang.Process, java.lang.String, java.util.Map)
+ */
+ @Override
+ public IProcess newProcess( final ILaunch launch, final Process process,
+ final String name, final Map attributes ) {
+ return new REPLProcess( launch, process, name, attributes );
+ }
+
+
+ public class REPLProcess extends RuntimeProcess {
+
+
+
+ public REPLProcess( final ILaunch launch, final Process process, final String name,
+ final Map attributes ) {
+ super( launch, process, name, attributes );
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.RuntimeProcess#getSystemProcess()
+ */
+ @Override
+ public Process getSystemProcess() {
+ return super.getSystemProcess();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.RuntimeProcess#createStreamsProxy()
+ */
+ @Override
+ protected IStreamsProxy createStreamsProxy() {
+ return null;
+ }
+ }
+}
View
4 net.sf.eclipsefp.haskell.debug.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: net.sf.eclipsefp.haskell.debug.ui;singleton:=true
-Bundle-Version: 2.3.0
+Bundle-Version: 2.3.1
Bundle-Activator: net.sf.eclipsefp.haskell.debug.ui.internal.HaskellDebugUI
Bundle-Vendor: %bundleVendor
Require-Bundle: net.sf.eclipsefp.haskell.ghccompiler,
@@ -18,7 +18,7 @@ Require-Bundle: net.sf.eclipsefp.haskell.ghccompiler,
org.eclipse.ui.editors;bundle-version="3.5.0",
net.sf.eclipsefp.haskell.util,
net.sf.eclipsefp.haskell.compat,
- org.eclipse.ui.console;bundle-version="3.2.0",
+ org.eclipse.ui.console,
org.eclipse.ui.navigator
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Localization: plugin
View
BIN net.sf.eclipsefp.haskell.debug.ui/icons/etool16/history16.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
2 net.sf.eclipsefp.haskell.debug.ui/plugin.properties
@@ -41,4 +41,4 @@ runHaskellProfilingShortcut_desc = Executes the built executable from this proje
toggle_breakpoint=Toggle Breakpoint
-haskellInteractiveLaunchType_name = Haskell interactive session
+haskellInteractiveLaunchType_name = Haskell interactive session
View
24 net.sf.eclipsefp.haskell.debug.ui/plugin.xml
@@ -73,6 +73,7 @@
menubarPath="debug">
</action>
</viewerContribution>
+
</extension>
<extension
point="org.eclipse.ui.editorActions">
@@ -425,17 +426,16 @@
</enablement>
</actionProvider>
</extension>
- <!--
- <extension
- point="org.eclipse.debug.core.launchConfigurationTypes">
- <launchConfigurationType
- delegate="net.sf.eclipsefp.haskell.debug.ui.internal.launch.young.GhciInteractiveLaunchDelegate"
- id="net.sf.eclipsefp.haskell.debug.ui.internal.launch.young.GhciInteractiveLaunchDelegate"
- modes="run,debug"
- name="%haskellInteractiveLaunchType_name"
- sourceLocatorId="net.sf.eclipsefp.haskell.debug.core.sourceLookupDirector"
- sourcePathComputerId="net.sf.eclipsefp.haskell.debug.core.sourcePathComputer">
- </launchConfigurationType>
- </extension>-->
+
+ <extension
+ point="org.eclipse.ui.console.consolePageParticipants">
+ <consolePageParticipant
+ class="net.sf.eclipsefp.haskell.debug.ui.repl.HistoryParticipant"
+ id="net.sf.eclipsefp.haskell.debug.ui.repl.HistoryParticipant">
+ <enablement>
+ <instanceof value="org.eclipse.debug.internal.ui.views.console.ProcessConsole"/>
+ </enablement>
+ </consolePageParticipant>
+ </extension>
</plugin>
View
2 ....ui/src/net/sf/eclipsefp/haskell/debug/ui/internal/launch/InteractiveLaunchOperation.java
@@ -143,6 +143,8 @@ private ILaunchConfiguration createConfiguration( final IResource[] resources,
String projectName = ILaunchAttributes.PROJECT_NAME;
wc.setAttribute( projectName, project.getName() );
wc.setAttribute( FIRST_SELECTED_RESOURCE, resources[ 0 ].getName() );
+ //wc.setAttribute( DebugPlugin.ATTR_PROCESS_FACTORY_ID,"net.sf.eclipsefp.haskell.debug.core.launch.REPLProcessFactory");
+
//wc.setAttribute( ILaunchAttributes.RELOAD_COMMAND, delegate.getReloadCommand() );
// by default, reload when saving, that's why interactive sessions are good
wc.setAttribute( ILaunchAttributes.RELOAD,true);
View
2 ...c/net/sf/eclipsefp/haskell/debug/ui/internal/launch/ghci/GhciLaunchOperationDelegate.java
@@ -176,4 +176,6 @@ private void addAll( final List<String> cmdLine, final IFile[] selectedFiles ) {
public String getReloadCommand() {
return ":r"; //$NON-NLS-1$
}
+
+
}
View
1 ...f/eclipsefp/haskell/debug/ui/internal/launch/yesod/YesodDevelLaunchOperationDelegate.java
@@ -44,4 +44,5 @@ public String getReloadCommand() {
return null;
}
+
}
View
2 ...lipsefp.haskell.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/internal/util/UITexts.java
@@ -57,6 +57,8 @@
public static String runTestSuite;
public static String yesod_devel_error;
+ public static String command_history;
+
private static final String BUNDLE_NAME
= UITexts.class.getPackage().getName() + ".uitexts"; //$NON-NLS-1$
View
2 ...p.haskell.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/internal/util/uitexts.properties
@@ -47,3 +47,5 @@ runProfiling = Run with profiling
runTestSuite = Run
yesod_devel_error=Could not launch Yesod
+
+command_history=Command History
View
179 ....eclipsefp.haskell.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/repl/HistoryAction.java
@@ -0,0 +1,179 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.debug.ui.repl;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import net.sf.eclipsefp.haskell.debug.ui.internal.HaskellDebugUI;
+import net.sf.eclipsefp.haskell.debug.ui.internal.util.UITexts;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.ui.console.TextConsolePage;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * the action writing the history command
+ * @author JP Moresmau
+ *
+ */
+public class HistoryAction extends Action {
+ private final StringBuilder current=new StringBuilder();
+ private final LinkedList<String> commands=new LinkedList<String>();
+
+ private final int maxHistory=20;
+
+ private int insertOffset=0;
+ private int insertIndex=-1;
+
+ public HistoryAction(final TextConsolePage p){
+ super(UITexts.command_history,AbstractUIPlugin.imageDescriptorFromPlugin( HaskellDebugUI.getDefault().getBundle().getSymbolicName(), "icons/etool16/history16.gif" )); //$NON-NLS-1$
+ final StyledText text=p.getViewer().getTextWidget();
+
+ text.addKeyListener( new KeyAdapter() {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent)
+ */
+ @Override
+ public void keyReleased( final KeyEvent e ) {
+ if ((e.keyCode==SWT.ARROW_UP || e.keyCode==SWT.ARROW_DOWN) && (e.stateMask & SWT.CONTROL) == SWT.CONTROL && commands.size()>0){
+ if (current.length()==0){
+ insertOffset=text.getCharCount();
+ } else {
+ text.replaceTextRange( insertOffset, current.length(), "" );
+ current.setLength( 0);
+ }
+ if (e.keyCode==SWT.ARROW_DOWN ){
+ insertIndex--;
+ if (insertIndex<0){
+ insertIndex=commands.size()-1;
+ }
+ } else if (e.keyCode==SWT.ARROW_UP ){
+ insertIndex++;
+ if (insertIndex>=commands.size()){
+ insertIndex=0;
+ }
+ }
+ Iterator<String> it=commands.iterator();
+ String toInsert=it.next();
+ for (int a=0;a<insertIndex;a++){
+ toInsert=it.next();
+ }
+
+ current.append( toInsert);
+ text.append(toInsert);
+ text.setCaretOffset( text.getCharCount() );
+ }
+ }
+
+ @Override
+ public void keyPressed(final org.eclipse.swt.events.KeyEvent e) {
+ char c=e.character;
+ synchronized(current){
+ if (c=='\r'){
+ String s=current.toString().trim();
+ if (s.length()>0){
+ commands.remove(s);
+ commands.addFirst(s);
+ if (commands.size()>maxHistory){
+ commands.removeLast();
+ }
+ }
+ insertIndex=-1;
+ current.setLength( 0 );
+ } else if (!Character.isISOControl( c )){
+ if (current.length()==0){
+ insertOffset=text.getCharCount();
+ }
+ current.append(c);
+ } else if (c=='\b' && current.length()>0){
+ current.setLength( current.length()-1 );
+ }
+ }
+ }
+
+ } );
+
+
+
+ setMenuCreator( new IMenuCreator() {
+
+ @Override
+ public Menu getMenu( final Menu arg0 ) {
+ Menu m=new Menu(arg0);
+ for (final String s:commands){
+ MenuItem mi=new MenuItem( m, SWT.NONE );
+ mi.setText( s );
+ mi.addSelectionListener( new HistoryMenuSelectionListener( text, s ) );
+ }
+ return m;
+ }
+
+ @Override
+ public Menu getMenu( final Control arg0 ) {
+ Menu m=new Menu(arg0);
+ for (final String s:commands){
+ MenuItem mi=new MenuItem( m, SWT.NONE );
+ mi.setText( s );
+ mi.addSelectionListener( new HistoryMenuSelectionListener( text, s ) );
+ }
+ return m;
+ }
+
+ @Override
+ public void dispose() {
+ // NOOP
+
+ }
+ } );
+ }
+
+ private class HistoryMenuSelectionListener extends SelectionAdapter {
+ private final StyledText text;
+ private final String command;
+
+ public HistoryMenuSelectionListener( final StyledText text, final String command ) {
+ super();
+ this.text = text;
+ this.command = command;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected( final SelectionEvent e ) {
+ text.append( command);
+ text.setCaretOffset( text.getCharCount() );
+
+ Event event = new Event();
+ event.widget = text;
+ event.stateMask = 0;
+ event.keyCode = 13;
+ event.character = '\r';
+ text.notifyListeners( SWT.KeyDown, event );
+
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ // NOOP
+ }
+}
View
82 ...psefp.haskell.debug.ui/src/net/sf/eclipsefp/haskell/debug/ui/repl/HistoryParticipant.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.debug.ui.repl;
+
+import net.sf.eclipsefp.haskell.debug.core.internal.HaskellDebugCore;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsolePageParticipant;
+import org.eclipse.ui.console.TextConsolePage;
+import org.eclipse.ui.part.IPageBookViewPage;
+
+
+/**
+ * This console page participant allows us to implement command history
+ * @author JP Moresmau
+ *
+ */
+public class HistoryParticipant implements IConsolePageParticipant {
+
+ private HistoryAction action;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter( final Class arg0 ) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.console.IConsolePageParticipant#init(org.eclipse.ui.part.IPageBookViewPage, org.eclipse.ui.console.IConsole)
+ */
+ @Override
+ public void init( final IPageBookViewPage paramIPageBookViewPage,
+ final IConsole paramIConsole ) {
+ TextConsolePage p=(TextConsolePage)paramIPageBookViewPage;
+
+ if (paramIConsole instanceof ProcessConsole){
+ IProcess pr=((ProcessConsole)paramIConsole).getProcess();
+ if (pr!=null && Boolean.TRUE.toString().equals( pr.getAttribute( HaskellDebugCore.PROCESS_COMMAND_HISTORY ) )){
+ action=new HistoryAction(p);
+
+ IActionBars actionBars = paramIPageBookViewPage.getSite().getActionBars();
+ actionBars.getToolBarManager().add( action );
+ }
+ }
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.console.IConsolePageParticipant#dispose()
+ */
+ @Override
+ public void dispose() {
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.console.IConsolePageParticipant#activated()
+ */
+ @Override
+ public void activated() {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.console.IConsolePageParticipant#deactivated()
+ */
+ @Override
+ public void deactivated() {
+ // TODO Auto-generated method stub
+
+ }
+
+}
View
2 net.sf.eclipsefp.haskell.hlint/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: net.sf.eclipsefp.haskell.hlint;singleton:=true
-Bundle-Version: 2.3.0
+Bundle-Version: 2.3.1
Bundle-Activator: net.sf.eclipsefp.haskell.hlint.HLintPlugin
Require-Bundle: org.eclipse.ui;bundle-version="[3.2.0,4.0.0)",
org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)",
View
2 net.sf.eclipsefp.haskell.hugs/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-Name: %bundleName
Bundle-SymbolicName: net.sf.eclipsefp.haskell.hugs;singleton:=true
-Bundle-Version: 2.3.0
+Bundle-Version: 2.3.1
Bundle-Activator: net.sf.eclipsefp.haskell.hugs.HugsPlugin
Bundle-Vendor: %bundleVendor
Bundle-Localization: plugin
View
8 net.sf.eclipsefp.haskell.ui/plugin.xml
@@ -1105,6 +1105,10 @@
id="net.sf.eclipsefp.haskell.browser"
name="%haskellBrowserPerspective_category">
</category>
+ <category
+ id="net.sf.eclipsefp.haskell"
+ name="%viewCategory_name">
+ </category>
<view
category="net.sf.eclipsefp.haskell.browser"
class="net.sf.eclipsefp.haskell.browser.views.packages.PackagesView"
@@ -1136,15 +1140,15 @@
restorable="true">
</view>
<view
- category="net.sf.eclipsefp.haskell.browser"
+ category="net.sf.eclipsefp.haskell"
class="net.sf.eclipsefp.haskell.browser.views.hoogle.HoogleView"
icon="icons/obj16/lambda.gif"
id="net.sf.eclipsefp.haskell.browser.views.hoogle.HoogleView"
name="%haskellBrowser_hoogleView"
restorable="true">
</view>
<view
- category="net.sf.eclipsefp.haskell.browser"
+ category="net.sf.eclipsefp.haskell"
class="net.sf.eclipsefp.haskell.ui.views.CabalPackagesView"
icon="icons/eview16/cabal.gif"
id="net.sf.eclipsefp.haskell.ui.views.CabalPackagesView"
View
71 net.sf.eclipsefp.haskell.util/src/net/sf/eclipsefp/haskell/util/BinaryStreamRedirect.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @author JP Moresmau
+ *
+ */
+public class BinaryStreamRedirect extends Thread {
+
+ private static final int BUFFER_SIZE = 2048;
+
+ private final InputStream fInput;
+
+ private OutputStream output;
+
+ public BinaryStreamRedirect( final String name, final InputStream in,
+ final OutputStream out ) {
+ super( name );
+ fInput = in;
+ output = out;
+ setPriority( Thread.MAX_PRIORITY - 1 );
+ }
+
+ public BinaryStreamRedirect( final InputStream in, final OutputStream out ) {
+ this( "Stream redirect thread", in, out ); //$NON-NLS-1$
+ }
+
+ // interface methods of java.lang.Thread
+ // //////////////////////////////////////
+
+ @Override
+ public void run() {
+ byte[] cbuf = new byte[ BUFFER_SIZE ];
+ int count;
+ try {
+ while( ( count = fInput.read( cbuf, 0, BUFFER_SIZE ) ) >= 0 ) {
+ output.write( cbuf, 0, count );
+ output.flush(); // flush straight away
+ }
+
+ output.close();
+ } catch( IOException ex ) {
+ // reading error, abort multiplexing
+ }
+ }
+
+ public OutputStream getOutput() {
+ return output;
+ }
+
+ public void setOutput(OutputStream output) {
+ if (this.output!=null){
+ try {
+ this.output.flush();
+ this.output.close();
+ } catch( IOException ignore ) {
+ // noop
+ }
+ }
+ this.output = output;
+ }
+
+}

0 comments on commit fc7051f

Please sign in to comment.
Something went wrong with that request. Please try again.