Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion debug/org.eclipse.debug.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.debug.core; singleton:=true
Bundle-Version: 3.23.200.qualifier
Bundle-Version: 3.24.0.qualifier
Bundle-Activator: org.eclipse.debug.core.DebugPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* Copyright (c) 2000, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -94,4 +94,31 @@ public interface IWatchExpression extends IErrorReportingExpression {
*/
void setEnabled(boolean enabled);

/**
* Sets a user preferred context for expression evaluation
*
* @param context
* @since 3.24
*/
public default void setPinnedContext(IDebugElement context) {
}

/**
* Returns the pinned context for the given expression
*
* @return returns pinned <code>IDebugElement</code>
* @since 3.24
*/
public default IDebugElement getPinnedContext() {
return null;
}

/**
* Removes attached custom context
*
* @since 3.24
*/
public default void removePinnedContext() {
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
* Copyright (c) 2000, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -21,6 +21,7 @@
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IWatchExpression;
import org.eclipse.debug.core.model.IWatchExpressionDelegate;
Expand All @@ -39,6 +40,7 @@ public class WatchExpression implements IWatchExpression {
protected IDebugElement fCurrentContext;
private boolean fEnabled= true;
private boolean fPending= false;
private IDebugElement fPinnedContext;

/**
* Creates a new watch expression with the given expression
Expand Down Expand Up @@ -301,4 +303,31 @@ public String[] getErrorMessages() {
return fResult.getErrorMessages();
}

/**
* @see org.eclipse.debug.core.model.IWatchExpression#setPinnedContext(IDebugElement)
*/
@Override
public void setPinnedContext(IDebugElement context) {
fPinnedContext = context;
}

/**
* @see org.eclipse.debug.core.model.IWatchExpression#getPinnedContext()
*/
@Override
public IDebugElement getPinnedContext() {
if (fPinnedContext instanceof IStackFrame) {
return fPinnedContext;
}
return null;
}

/**
* @see org.eclipse.debug.core.model.IWatchExpression#removePinnedContext()
*/
@Override
public void removePinnedContext() {
fPinnedContext = null;
}

}
6 changes: 5 additions & 1 deletion debug/org.eclipse.debug.ui/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -421,4 +421,8 @@ prototype.decorator.label = Prototype Decorator
breakpointLabel.label= Label
breakpointLabel.tooltip= Provide a custom label to quickly identify breakpoint
breakpointLabelCommand = EditBreakpointLabel
breakpointLabelCommand.description = Opens inline editor to change breakpoint label
breakpointLabelCommand.description = Opens inline editor to change breakpoint label


PinExpressionWithCurrentAction.label=Pin Evaluation Context
PinExpressionWithCurrentAction.tooltip=Pin current evaluation stackframe for this expression
13 changes: 13 additions & 0 deletions debug/org.eclipse.debug.ui/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,19 @@
enablesFor="1"
id="org.eclipse.debug.ui.watchExpressionActions.EditWatchExpression">
</action>
</viewerContribution>
<viewerContribution
targetID="org.eclipse.debug.ui.ExpressionView"
id="org.eclipse.debug.ui.WatchExpressionActions22">
<action
label="%PinExpressionWithCurrentAction.label"
helpContextId="pin_current_evaluation_context"
class="org.eclipse.debug.internal.ui.actions.expressions.PinWatchContextAction"
tooltip="%PinExpressionWithCurrentAction.tooltip"
menubarPath="additions"
enablesFor="1"
id="org.eclipse.debug.ui.watchExpressionActions.PinCurrentContext">
</action>
</viewerContribution>
<viewerContribution
targetID="org.eclipse.debug.ui.ExpressionView"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,5 +254,7 @@ public class ActionMessages extends NLS {
public static String EnableAllBreakpointsAction_3;
public static String BreakpointLabelDialog;
public static String RemoveFromFavoritesAction;
public static String ExpressionsPinContext;
public static String ExpressionsRemovePin;

}
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,7 @@ VirtualFindAction_1=Unable to locate {0} in viewer

ToggleBreakpointsTargetManager_defaultToggleTarget_name = Default
ToggleBreakpointsTargetManager_defaultToggleTarget_description = Default
BreakpointLabelDialog=Provide a custom label, or blank for the default label
BreakpointLabelDialog=Provide a custom label, or blank for the default label

ExpressionsRemovePin=Remove Pinned Context
ExpressionsPinContext=Pin Evaluation Context
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*******************************************************************************
* Copyright (c) 2025 IBM Corporation.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.debug.internal.ui.actions.expressions;

import java.util.Iterator;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IWatchExpression;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.actions.ActionMessages;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.IActionDelegate2;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;

/*
* Associates the current stack frame with this expression, allowing its evaluation
* result to remain accessible across different debug contexts.
*/
public class PinWatchContextAction implements IViewActionDelegate, IDebugEventSetListener, IActionDelegate2 {

/**
* Finds the currently selected context in the UI.
*
* @return the current debug context
*/
protected IDebugElement getContext() {
IAdaptable object = DebugUITools.getDebugContext();
IDebugElement context = null;
if (object instanceof IDebugElement iDebugElement) {
context = iDebugElement;
} else if (object instanceof ILaunch iLaunch) {
context = iLaunch.getDebugTarget();
}
return context;
}

protected IStructuredSelection getCurrentSelection() {
IWorkbenchPage page = DebugUIPlugin.getActiveWorkbenchWindow().getActivePage();
if (page != null) {
ISelection selection = page.getSelection();
if (selection instanceof IStructuredSelection sel) {
return sel;
}
}
return null;
}

/**
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
*/
@Override
public void run(IAction action) {
IDebugElement context = getContext();
for (Iterator<?> iter = getCurrentSelection().iterator(); iter.hasNext();) {
if (iter.next() instanceof IWatchExpression expression) {
if (expression.getPinnedContext() != null) {
expression.removePinnedContext();
expression.setExpressionContext(context);
action.setText(ActionMessages.ExpressionsPinContext);
} else {
expression.setPinnedContext(context);
action.setText(ActionMessages.ExpressionsRemovePin);
}
if (expression.isEnabled()) {
expression.evaluate();
}
}
}
}

@Override
public void selectionChanged(IAction action, ISelection selection) {

IDebugElement debugElement = getContext();
if (debugElement == null) {
action.setEnabled(false);
return;
} else {
action.setEnabled(true);
}
if (getCurrentSelection() == null) {
return;
}
for (Object select : getCurrentSelection()) {
if (select instanceof IWatchExpression expression) {
if (expression.getPinnedContext() != null) {
action.setText(ActionMessages.ExpressionsRemovePin);
} else {
action.setText(ActionMessages.ExpressionsPinContext);
}
} else {
action.setEnabled(false);
}

}

}

@Override
public void handleDebugEvents(DebugEvent[] events) {
for (DebugEvent event : events) {
if (event.getSource() instanceof IThread thread && thread.isTerminated()) {
for (IExpression exp : DebugPlugin.getDefault().getExpressionManager().getExpressions()) {
if (exp instanceof IWatchExpression expression && expression.getPinnedContext() != null) {
if (expression.getPinnedContext() instanceof IStackFrame frame && frame.isTerminated()) {
expression.removePinnedContext();
expression.setExpressionContext(getContext());
}
}
}

}
}

}

@Override
public void init(IViewPart view) {
DebugPlugin.getDefault().addDebugEventListener(this);

}

@Override
public void init(IAction action) {
}

@Override
public void dispose() {
DebugPlugin.getDefault().removeDebugEventListener(this);
}

@Override
public void runWithEvent(IAction action, Event event) {
run(action);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2014 IBM Corporation and others.
* Copyright (c) 2006, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -23,7 +23,10 @@
import org.eclipse.debug.internal.ui.DebugUIMessages;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;

/**
Expand Down Expand Up @@ -163,4 +166,19 @@ protected String getExpressionValueText(IExpression expression, IValue value, IP
return null;
}

@Override
protected FontData getFontData(TreePath elementPath, IPresentationContext presentationContext, String columnId)
throws CoreException {
Object element = elementPath.getLastSegment();
if (element instanceof IWatchExpression watchExp) {
if (watchExp.getPinnedContext() != null) {
var fontNew = JFaceResources.getFontDescriptor(IDebugUIConstants.PREF_VARIABLE_TEXT_FONT)
.getFontData()[0];
return new FontData(fontNew.getName(), fontNew.getHeight(),
fontNew.getStyle() ^ (SWT.BOLD | SWT.ITALIC));
}
}
return JFaceResources.getFontDescriptor(IDebugUIConstants.PREF_VARIABLE_TEXT_FONT).getFontData()[0];
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
* Copyright (c) 2005, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -113,8 +113,13 @@ protected void contextActivated(ISelection selection) {
}
}
IWatchExpression expression = (IWatchExpression)getExpression();
if (expression != null){
expression.setExpressionContext(context);
if (expression != null) {
IDebugElement pinnedContext = expression.getPinnedContext();
if (pinnedContext != null) {
expression.setExpressionContext(pinnedContext);
} else {
expression.setExpressionContext(context);
}
}
}
}
Expand Down
Loading