Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

inspect action

  • Loading branch information...
commit aadf7351f3cb2c761e19380eb9b00769c7495ea5 1 parent 2c2c5a6
@JPMoresmau authored
View
2  docs/releasenotes/net.sf.eclipsefp.haskell_2.3.2.txt
@@ -25,6 +25,8 @@ Features:
- Install all dependencies for one project from right click on project (performs a clean of the project afterwards).
- BuildWrapper and scion-browser should build with GHC 7.6
- If you run a GHCi session in debug mode and launch a function with :trace, :hist output will show as a stack trace in the Debug perspective
+ - Watch action on editor adds the selected text as a debug expression
+ - Inspect action on editor evaluates the expression in current GHCi session (only visible if stopped at a breakpoint in debug GHCi session)
Internal:
- Hopefully performance of some UI operations has been enhanced and the UI should be more responsive in places
View
41 ...debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/debug/HaskellDebugTarget.java
@@ -1,3 +1,8 @@
+/**
+ * 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.debug;
import java.io.BufferedReader;
@@ -44,6 +49,19 @@
*
*/
public class HaskellDebugTarget extends HaskellDebugElement implements IDebugTarget,IStreamListener {
+ /**
+ * lock
+ */
+ private static Object instanceLock=new Object();
+ /**
+ * number of target currently suspended at a breakpoint
+ */
+ private static int instances=0;
+ /**
+ * system property to write globally if we can handle inspect
+ */
+ private static final String SYSTEM_PROPERTY="haskell.debug"; //$NON-NLS-1$
+
// associated system process (VM)
private final IProcess fProcess;
@@ -64,6 +82,22 @@
private final HaskellThread thread=new HaskellThread( this );
+ /**
+ * manages the number of instances
+ * @param delta the number to move the count by
+ */
+ private static void instances(final int delta){
+ synchronized( instanceLock ) {
+ instances+=delta;
+ if(instances>0){
+ System.setProperty( SYSTEM_PROPERTY, "true" ); //$NON-NLS-1$
+ } else {
+ instances=0;
+ System.clearProperty( SYSTEM_PROPERTY );
+ }
+ }
+ }
+
public HaskellDebugTarget(final ILaunch launch, final IProcess process){
setTarget( this );
this.fLaunch=launch;
@@ -71,6 +105,7 @@ public HaskellDebugTarget(final ILaunch launch, final IProcess process){
this.fProcess.getStreamsProxy().getOutputStreamMonitor().addListener( this );
DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);
+ instances(1);
}
@Override
@@ -191,6 +226,7 @@ private synchronized void waitForPrompt(){
@Override
public void terminate() throws DebugException {
if (isSuspended()){
+ instances(-1);
thread.setBreakpoint( null );
thread.setStopLocation( null );
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( thread, DebugEvent.RESUME )});
@@ -224,7 +260,7 @@ public void resume() throws DebugException {
thread.setStopLocation( null );
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( thread, DebugEvent.RESUME )});
sendRequest( GHCiSyntax.CONTINUE_COMMAND, false );
-
+ instances(-1);
}
@Override
@@ -327,6 +363,7 @@ public void dispose(){
connected=false;
disposed=true;
DebugPlugin.getDefault().getBreakpointManager().removeBreakpointListener( this );
+
}
@Override
@@ -422,7 +459,7 @@ public void run() {
}
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[]{new DebugEvent( thread, DebugEvent.SUSPEND,hb!=null?DebugEvent.BREAKPOINT:DebugEvent.UNSPECIFIED )});
-
+ instances(1);
} else {
m=GHCiSyntax.BREAKPOINT_NOT.matcher( response.toString() );
View
45 ....debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/debug/HaskellExpression.java
@@ -0,0 +1,45 @@
+/**
+ * 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.debug;
+
+import org.eclipse.debug.core.model.IExpression;
+import org.eclipse.debug.core.model.IValue;
+
+
+/**
+ * Wrapping a value and an expression text
+ * @author JP Moresmau
+ *
+ */
+public class HaskellExpression extends HaskellDebugElement implements IExpression{
+ private final String expression;
+ private final HaskellValue value;
+
+ public HaskellExpression( final HaskellDebugTarget target,final String expression,final HaskellValue value ) {
+ super( target );
+ this.expression=expression;
+ this.value=value;
+ }
+
+ @Override
+ public String getExpressionText() {
+ return expression;
+ }
+
+ @Override
+ public IValue getValue() {
+ return value;
+ }
+
+ @Override
+ public void dispose() {
+ // NOOP
+
+ }
+
+
+
+}
View
BIN  net.sf.eclipsefp.haskell.ui/icons/etool16/insp_exp.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.ui/plugin.properties
@@ -122,6 +122,8 @@ openDefinitionCommand_desc = Opens an editor on the declaration of the selected
watchExpressionCommand_name=Watch
watchExpressionCommand_desc=Add the selected code to the watched expressions
+inspectExpressionCommand_name=Inspect
+inspectExpressionCommand_desc=See the current value of the expression
searchHoogleAction_label = Search in &Hoogle
searchHoogleAction_tooltip = Search for the select element in Hoogle
View
41 net.sf.eclipsefp.haskell.ui/plugin.xml
@@ -481,6 +481,11 @@
name="%watchExpressionCommand_name"
id="net.sf.eclipsefp.ui.commands.run.watchExpression"/>
<command
+ description="%inspectExpressionCommand_desc"
+ categoryId="org.eclipse.debug.ui.category.run"
+ name="%inspectExpressionCommand_name"
+ id="net.sf.eclipsefp.ui.commands.run.inspectExpression"/>
+ <command
description="%HaddockDocumentFollowing.description"
categoryId="net.sf.eclipsefp.haskell.ui.category.source"
name="%HaddockDocumentFollowing.name"
@@ -523,6 +528,14 @@
<visibleWhen checkEnabled="true"/>
</command>
</menuContribution>
+ <menuContribution
+ locationURI="menu:org.eclipse.ui.run?after=emptyBreakpointGroup">
+ <command
+ commandId="net.sf.eclipsefp.ui.commands.run.inspectExpression"
+ icon="icons/etool16/insp_exp.gif">
+ <visibleWhen checkEnabled="true"/>
+ </command>
+ </menuContribution>
<menuContribution
locationURI="menu:navigate?after=open.ext">
<command
@@ -546,6 +559,14 @@
</command>
</menuContribution>
<menuContribution
+ locationURI="popup:#HaskellEditorContext?after=additions">
+ <command
+ commandId="net.sf.eclipsefp.ui.commands.run.inspectExpression"
+ icon="icons/etool16/insp_exp.gif">
+ <visibleWhen checkEnabled="true"/>
+ </command>
+ </menuContribution>
+ <menuContribution
locationURI="popup:#HaskellEditorContext?after=group.open">
<command
commandId="net.sf.eclipsefp.ui.commands.navigate.searchHoogle">
@@ -688,7 +709,7 @@
</reference>
</activeWhen>
</handler>
- <!-- handler for the Watch expression action when invoked from the HaskellEditor -->
+ <!-- handler for the Watch expression action when invoked from the HaskellEditor -->
<handler
class="net.sf.eclipsefp.haskell.ui.handlers.WatchExpressionHandler"
commandId="net.sf.eclipsefp.ui.commands.run.watchExpression">
@@ -705,6 +726,24 @@
</and>
</activeWhen>
</handler>
+ <!-- handler for the Inspect expression action when invoked from the HaskellEditor -->
+ <handler
+ class="net.sf.eclipsefp.haskell.ui.handlers.InspectExpressionHandler"
+ commandId="net.sf.eclipsefp.ui.commands.run.inspectExpression">
+ <activeWhen>
+ <and>
+ <reference
+ definitionId="net.sf.eclipsefp.haskell.ui.internal.editors.haskell.HaskellEditor.active">
+ </reference>
+ <with variable="selection">
+ <iterate operator="or">
+ <instanceof value="org.eclipse.jface.text.ITextSelection"/>
+ </iterate>
+ </with>
+ <systemTest property="haskell.debug" value="true"/>
+ </and>
+ </activeWhen>
+ </handler>
</extension>
<extension
point="org.eclipse.core.expressions.definitions">
View
80 ...lipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/handlers/InspectExpressionHandler.java
@@ -0,0 +1,80 @@
+/**
+ * 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.ui.handlers;
+
+import net.sf.eclipsefp.haskell.debug.core.internal.debug.HaskellDebugElement;
+import net.sf.eclipsefp.haskell.debug.core.internal.debug.HaskellExpression;
+import net.sf.eclipsefp.haskell.debug.core.internal.debug.HaskellValue;
+import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin;
+import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.HaskellEditor;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.ISuspendResume;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.InspectPopupDialog;
+import org.eclipse.swt.graphics.Point;
+
+
+/**
+ * Inspect the current value of the selected expression
+ * @author JP Moresmau
+ *
+ */
+public class InspectExpressionHandler extends WatchExpressionHandler {
+
+ /* (non-Javadoc)
+ * @see net.sf.eclipsefp.haskell.ui.handlers.WatchExpressionHandler#addExpression(java.lang.String)
+ */
+ @Override
+ protected void addExpression(final HaskellEditor hEditor, final String s ) {
+ IAdaptable context = DebugUITools.getDebugContext();
+ if (context instanceof HaskellDebugElement){
+ final HaskellDebugElement hde=(HaskellDebugElement)context;
+ if ((hde instanceof ISuspendResume && ((ISuspendResume)hde).isSuspended()) || hde.getDebugTarget().isSuspended()){
+ try {
+ final HaskellValue val=hde.getDebugTarget().evaluate( s );
+ hEditor.getEditorSite().getShell().getDisplay().asyncExec( new Runnable(){
+ @Override
+ public void run() {
+ Point p=hEditor.getSelectedPoint();
+ //new InspectDialog(hEditor,s,res).open();
+ new InspectPopupDialog( hEditor.getEditorSite().getShell(), new Point( p.x, p.y+20 ), null, new HaskellExpression( hde.getDebugTarget(), s, val ) ).open();
+ }
+ });
+
+ } catch (DebugException de){
+ HaskellUIPlugin.log( de );
+ }
+
+ }
+ }
+
+ }
+
+// private static class InspectDialog extends PopupDialog{
+// private final String val;
+// /**
+// *
+// */
+// public InspectDialog(final HaskellEditor hEditor,final String exp,final String val) {
+// super(hEditor.getEditorSite().getShell(),PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE,false,false,false,false,false,exp,"");
+// this.val=val;
+// }
+//
+// /* (non-Javadoc)
+// * @see org.eclipse.jface.dialogs.PopupDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+// */
+// @Override
+// protected Control createDialogArea( final Composite parent ) {
+// Composite composite=(Composite)super.createDialogArea( parent );
+// Label l=new Label(composite,SWT.NONE);
+// l.setLayoutData( new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL) );
+// l.setText( val );
+// composite.layout( true );
+// return composite;
+// }
+// }
+}
View
10 ...eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/handlers/WatchExpressionHandler.java
@@ -39,8 +39,10 @@ public Object execute( final ExecutionEvent event ) {
return null;
}
final HaskellEditor hEditor=(HaskellEditor)editor;
+
// cast is safe because we have a guard in plugin.xml
final ITextSelection sel=(ITextSelection)HandlerUtil.getActiveMenuSelection( event );
+
String s=sel.getText();
// find word at location
if (s.length()==0){
@@ -50,23 +52,23 @@ public Object execute( final ExecutionEvent event ) {
public void handle( final EditorThing thing ) {
if (thing!=null && thing.getThing()!=null){
String name = thing.getThing().getName();
- addExpression( name );
+ addExpression(hEditor, name );
} else {
String s=WordFinder.findWord( hEditor.getDocument(), sel.getOffset() );
if (s.length()>0){
- addExpression( s );
+ addExpression(hEditor, s );
}
}
}
});
} else {
- addExpression( s );
+ addExpression(hEditor, s );
}
return null;
}
- protected void addExpression(final String s){
+ protected void addExpression(final HaskellEditor hEditor,final String s){
if (s.length()>0){
IWatchExpression expression= DebugPlugin.getDefault().getExpressionManager().newWatchExpression(s);
DebugPlugin.getDefault().getExpressionManager().addExpression(expression);
View
13 ...fp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/editors/haskell/HaskellEditor.java
@@ -71,6 +71,7 @@
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
@@ -203,7 +204,10 @@ public HaskellEditor() {
// getSourceViewer().revealRange( offset, length );
// }
+
+
public IDocument getDocument() {
+
IDocumentProvider docProvider = getDocumentProvider();
if (docProvider!=null){
return docProvider.getDocument( getEditorInput() );
@@ -288,6 +292,15 @@ public void editorContextMenuAboutToShow( final IMenuManager menu ) {
}
}
+ /**
+ * get the location in display coordinates of the current selection
+ * @return
+ */
+ public Point getSelectedPoint(){
+ Point p2=getSourceViewer().getTextWidget().getLocationAtOffset( getSourceViewer().getTextWidget().getSelectionRange().x );
+ return getSourceViewer().getTextWidget().toDisplay(p2 );
+ }
+
@Override
protected void createActions() {
super.createActions();

0 comments on commit aadf735

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