Skip to content

Commit a2ce293

Browse files
committed
Add support for custom labels on breakpoints
This commit introduces the ability for users to set custom labels on breakpoints, making it easier to identify and differentiate them. Additionally, breakpoints with custom labels are visually highlighted, improving workflow and debugging efficiency.
1 parent 9e339b2 commit a2ce293

File tree

11 files changed

+242
-7
lines changed

11 files changed

+242
-7
lines changed

debug/org.eclipse.debug.core/META-INF/MANIFEST.MF

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.debug.core; singleton:=true
5-
Bundle-Version: 3.23.0.qualifier
5+
Bundle-Version: 3.23.100.qualifier
66
Bundle-Activator: org.eclipse.debug.core.DebugPlugin
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/Breakpoint.java

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2016 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -45,7 +45,6 @@
4545

4646
public abstract class Breakpoint extends PlatformObject implements IBreakpoint, ITriggerPoint {
4747

48-
4948
/**
5049
* Creates a breakpoint.
5150
*
@@ -384,4 +383,24 @@ public String toString() {
384383
return builder.toString();
385384
}
386385

386+
/**
387+
* Returns associated label associated with the breakpoint.
388+
* @since 3.23
389+
*/
390+
public String getBreakpointLabel() {
391+
String LABEL = "org.eclipse.debug.core.label"; //$NON-NLS-1$
392+
return getMarker().getAttribute(LABEL, ""); //$NON-NLS-1$
393+
}
394+
395+
/**
396+
* Sets a new label for the breakpoint.
397+
*
398+
* @param label provide by the user
399+
* @since 3.23
400+
*/
401+
public void setBreakpointLabel(String label) throws CoreException {
402+
String LABEL = "org.eclipse.debug.core.label"; //$NON-NLS-1$
403+
setAttribute(LABEL, label);
404+
}
405+
387406
}

debug/org.eclipse.debug.core/core/org/eclipse/debug/core/model/IBreakpoint.java

+1
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ public interface IBreakpoint extends IAdaptable {
220220
*/
221221
void setPersisted(boolean registered) throws CoreException;
222222

223+
223224
}
224225

225226

Loading

debug/org.eclipse.debug.ui/plugin.properties

+1
Original file line numberDiff line numberDiff line change
@@ -418,3 +418,4 @@ debug.core.component.label = Platform Debug Core
418418
GroupLaunch.description=Launch several other configurations sequentially
419419

420420
prototype.decorator.label = Prototype Decorator
421+
breakpointLabel.label=Label

debug/org.eclipse.debug.ui/plugin.xml

+9
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,15 @@
15401540
enablesFor="+"
15411541
id="org.eclipse.debug.ui.breakpointsView.toolbar.remove">
15421542
</action>
1543+
<action
1544+
label="%breakpointLabel.label"
1545+
icon="$nl$/icons/full/elcl16/bp_label.png"
1546+
helpContextId="remove_breakpoint_action_context"
1547+
class="org.eclipse.debug.internal.ui.actions.breakpoints.BreakpointLabelAction"
1548+
menubarPath="breakpointGroup"
1549+
enablesFor="1"
1550+
id="org.eclipse.debug.ui.breakpointsView.breakpointLabel">
1551+
</action>
15431552
<action
15441553
label="%DisableAllBreakpointsAction.label"
15451554
icon="$nl$/icons/full/elcl16/disabled_co.png"

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2020 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -252,4 +252,8 @@ public class ActionMessages extends NLS {
252252
public static String EnableAllBreakpointsAction_0;
253253
public static String EnableAllBreakpointsAction_1;
254254
public static String EnableAllBreakpointsAction_3;
255+
public static String BreakpointLabelTitle;
256+
public static String BreakpointLabelDialog;
257+
public static String BreakpointLabelClear;
258+
255259
}

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ActionMessages.properties

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
# Copyright (c) 2000, 2020 IBM Corporation and others.
2+
# Copyright (c) 2000, 2025 IBM Corporation and others.
33
#
44
# This program and the accompanying materials
55
# are made available under the terms of the Eclipse Public License 2.0
@@ -235,4 +235,7 @@ VirtualFindAction_0=Error
235235
VirtualFindAction_1=Unable to locate {0} in viewer
236236

237237
ToggleBreakpointsTargetManager_defaultToggleTarget_name = Default
238-
ToggleBreakpointsTargetManager_defaultToggleTarget_description = Default
238+
ToggleBreakpointsTargetManager_defaultToggleTarget_description = Default
239+
BreakpointLabelTitle=Set Breakpoint Label
240+
BreakpointLabelDialog=Provide a custom label, or blank for the default label
241+
BreakpointLabelClear=Clear
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 IBM Corporation
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.debug.internal.ui.actions.breakpoints;
15+
16+
import org.eclipse.core.runtime.CoreException;
17+
import org.eclipse.debug.core.model.Breakpoint;
18+
import org.eclipse.debug.internal.ui.DebugUIPlugin;
19+
import org.eclipse.debug.internal.ui.actions.ActionMessages;
20+
import org.eclipse.jface.action.IAction;
21+
import org.eclipse.jface.dialogs.Dialog;
22+
import org.eclipse.jface.dialogs.IDialogConstants;
23+
import org.eclipse.jface.viewers.ISelection;
24+
import org.eclipse.jface.viewers.IStructuredSelection;
25+
import org.eclipse.jface.window.Window;
26+
import org.eclipse.swt.SWT;
27+
import org.eclipse.swt.events.SelectionAdapter;
28+
import org.eclipse.swt.events.SelectionEvent;
29+
import org.eclipse.swt.layout.GridData;
30+
import org.eclipse.swt.widgets.Button;
31+
import org.eclipse.swt.widgets.Composite;
32+
import org.eclipse.swt.widgets.Control;
33+
import org.eclipse.swt.widgets.Label;
34+
import org.eclipse.swt.widgets.Shell;
35+
import org.eclipse.swt.widgets.Text;
36+
import org.eclipse.ui.IViewActionDelegate;
37+
import org.eclipse.ui.IViewPart;
38+
39+
public class BreakpointLabelAction implements IViewActionDelegate {
40+
41+
private IViewPart fView;
42+
43+
protected IViewPart getView() {
44+
return fView;
45+
}
46+
47+
protected void setView(IViewPart view) {
48+
fView = view;
49+
}
50+
51+
@Override
52+
public void run(IAction action) {
53+
IStructuredSelection selection = getSelection();
54+
if (selection.getFirstElement() instanceof Breakpoint bp) {
55+
String label = askForLabel(bp);
56+
if (label == null) {
57+
return;
58+
}
59+
if (!label.isEmpty()) {
60+
try {
61+
bp.setBreakpointLabel(label);
62+
} catch (CoreException e) {
63+
DebugUIPlugin.log(e);
64+
}
65+
} else {
66+
try {
67+
bp.setBreakpointLabel(""); //$NON-NLS-1$
68+
} catch (CoreException e) {
69+
DebugUIPlugin.log(e);
70+
}
71+
}
72+
}
73+
}
74+
75+
protected IStructuredSelection getSelection() {
76+
return (IStructuredSelection) getView().getViewSite().getSelectionProvider().getSelection();
77+
}
78+
79+
@Override
80+
public void selectionChanged(IAction action, ISelection selection) {
81+
}
82+
83+
@Override
84+
public void init(IViewPart view) {
85+
setView(view);
86+
}
87+
88+
private String askForLabel(Breakpoint breakpoint) {
89+
String current = breakpoint.getBreakpointLabel();
90+
91+
class BreakpointLabelBox extends Dialog {
92+
private Text textInput;
93+
private String value;
94+
private Button clearButton;
95+
private String initialLabel;
96+
97+
protected BreakpointLabelBox(Shell parentShell, String intialValue) {
98+
super(parentShell);
99+
initialLabel = intialValue;
100+
}
101+
@Override
102+
protected Control createDialogArea(Composite parent) {
103+
Composite composite = (Composite) super.createDialogArea(parent);
104+
Label label = new Label(composite, SWT.WRAP);
105+
label.setText(ActionMessages.BreakpointLabelDialog);
106+
GridData data = new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL
107+
| GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
108+
data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
109+
label.setLayoutData(data);
110+
label.setFont(parent.getFont());
111+
textInput = new Text(composite, SWT.SINGLE | SWT.BORDER);
112+
textInput.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
113+
textInput.setText(initialLabel);
114+
applyDialogFont(composite);
115+
return composite;
116+
}
117+
118+
@Override
119+
protected void configureShell(Shell newShell) {
120+
super.configureShell(newShell);
121+
newShell.setText(ActionMessages.BreakpointLabelTitle);
122+
123+
}
124+
125+
@Override
126+
protected void createButtonsForButtonBar(Composite parent) {
127+
super.createButtonsForButtonBar(parent);
128+
clearButton = createButton(parent, IDialogConstants.BACK_ID, ActionMessages.BreakpointLabelClear,
129+
false);
130+
clearButton.addSelectionListener(new SelectionAdapter() {
131+
@Override
132+
public void widgetSelected(SelectionEvent e) {
133+
textInput.setText(""); //$NON-NLS-1$
134+
135+
}
136+
});
137+
}
138+
139+
@Override
140+
protected void buttonPressed(int buttonId) {
141+
if (buttonId == IDialogConstants.OK_ID) {
142+
value = textInput.getText();
143+
} else {
144+
value = null;
145+
}
146+
super.buttonPressed(buttonId);
147+
}
148+
private String getInput() {
149+
return value;
150+
}
151+
152+
}
153+
BreakpointLabelBox dialog = new BreakpointLabelBox(fView.getSite().getShell(), current);
154+
155+
if (dialog.open() != Window.OK) {
156+
return null;
157+
}
158+
String data = dialog.getInput();
159+
return data.trim();
160+
}
161+
162+
}

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/model/elements/BreakpointLabelProvider.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*****************************************************************
2-
* Copyright (c) 2009, 2010 Texas Instruments and others
2+
* Copyright (c) 2009, 2025 Texas Instruments and others
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,6 +15,7 @@
1515
package org.eclipse.debug.internal.ui.model.elements;
1616

1717
import org.eclipse.core.runtime.CoreException;
18+
import org.eclipse.debug.core.model.Breakpoint;
1819
import org.eclipse.debug.core.model.IBreakpoint;
1920
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
2021
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
@@ -31,6 +32,20 @@ public class BreakpointLabelProvider extends DebugElementLabelProvider {
3132
@Override
3233
protected String getLabel(TreePath elementPath, IPresentationContext presentationContext, String columnId, int columnIndex) throws CoreException {
3334
if (columnIndex == 0) {
35+
if (elementPath.getFirstSegment() instanceof Breakpoint breakpoint) {
36+
String current = super.getLabel(elementPath, presentationContext, columnId, columnIndex);
37+
if (!breakpoint.getBreakpointLabel().isEmpty()) {
38+
String[] currentElements = current.split(" "); //$NON-NLS-1$
39+
if (current.contains("line")) { //$NON-NLS-1$
40+
41+
return currentElements[0] + currentElements[1] + currentElements[2] + " " //$NON-NLS-1$
42+
+ breakpoint.getBreakpointLabel();
43+
}
44+
return currentElements[0] + " " //$NON-NLS-1$
45+
+ breakpoint.getBreakpointLabel();
46+
}
47+
48+
}
3449
return super.getLabel(elementPath, presentationContext, columnId, columnIndex);
3550
} else {
3651
return IInternalDebugCoreConstants.EMPTY_STRING;

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/launch/DebugElementHelper.java

+21
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,21 @@
1616
import java.util.HashMap;
1717
import java.util.Map;
1818

19+
import org.eclipse.debug.core.model.Breakpoint;
1920
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
2021
import org.eclipse.debug.ui.IDebugModelPresentation;
22+
import org.eclipse.debug.ui.IDebugUIConstants;
2123
import org.eclipse.jface.resource.ImageDescriptor;
24+
import org.eclipse.jface.resource.JFaceResources;
2225
import org.eclipse.jface.viewers.IColorProvider;
2326
import org.eclipse.jface.viewers.IFontProvider;
27+
import org.eclipse.swt.SWT;
2428
import org.eclipse.swt.graphics.Color;
2529
import org.eclipse.swt.graphics.Font;
2630
import org.eclipse.swt.graphics.FontData;
2731
import org.eclipse.swt.graphics.Image;
2832
import org.eclipse.swt.graphics.RGB;
33+
import org.eclipse.swt.widgets.Display;
2934

3035
/**
3136
* Translates images, colors, and fonts into image descriptors, RGBs, and font
@@ -144,6 +149,13 @@ public static RGB getForeground(Object element, IDebugModelPresentation presenta
144149
if (color != null) {
145150
return color.getRGB();
146151
}
152+
if (element instanceof Breakpoint breakpoint) {
153+
if (!breakpoint.getBreakpointLabel().isEmpty()) {
154+
Color redColor = new Color(Display.getCurrent(), 255, 0, 0);
155+
return redColor.getRGB();
156+
}
157+
158+
}
147159
return null;
148160
}
149161

@@ -222,7 +234,16 @@ public static FontData getFont(Object element, IDebugModelPresentation presentat
222234
if (font != null) {
223235
return font.getFontData()[0];
224236
}
237+
if (element instanceof Breakpoint breakpoint) {
238+
if (!breakpoint.getBreakpointLabel().isEmpty()) {
239+
var fontNew = JFaceResources.getFontDescriptor(IDebugUIConstants.PREF_VARIABLE_TEXT_FONT)
240+
.getFontData()[0];
241+
return new FontData(fontNew.getName(), fontNew.getHeight(), fontNew.getStyle() ^ SWT.BOLD);
242+
}
243+
244+
}
225245
return null;
246+
226247
}
227248

228249
/**

0 commit comments

Comments
 (0)