Bug 507546 - Show variable values inline Uses code mining to render extra information at end of line. Lookup for information that's worth being shown relies on a TextPostion->IVariable adapter being available and returning a value. Change-Id: I6cbadd48ff6a2888cef047fac5128cb58e7ade3a Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/190735 Tested-by: Mickael Istria <mistria@redhat.com> Reviewed-by: Mickael Istria <mistria@redhat.com>
diff --git a/org.eclipse.debug.ui/META-INF/MANIFEST.MF b/org.eclipse.debug.ui/META-INF/MANIFEST.MF index ddea511..e7aad2c 100644 --- a/org.eclipse.debug.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.debug.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.debug.ui; singleton:=true -Bundle-Version: 3.15.300.qualifier +Bundle-Version: 3.16.0.qualifier Bundle-Activator: org.eclipse.debug.internal.ui.DebugUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin
diff --git a/org.eclipse.debug.ui/plugin.xml b/org.eclipse.debug.ui/plugin.xml index 2d052d8..fc82676 100644 --- a/org.eclipse.debug.ui/plugin.xml +++ b/org.eclipse.debug.ui/plugin.xml
@@ -3392,4 +3392,11 @@ icon="icons/full/obj16/launchConfiguration.png"> </icon> </extension> + <extension + point="org.eclipse.ui.workbench.texteditor.codeMiningProviders"> + <codeMiningProvider + class="org.eclipse.debug.internal.ui.codemining.DebugValueCodeMiningProvider" + id="org.eclipse.debug.ui.codeMiningProvider1"> + </codeMiningProvider> + </extension> </plugin>
diff --git a/org.eclipse.debug.ui/pom.xml b/org.eclipse.debug.ui/pom.xml index 082dee7..6fe008b 100644 --- a/org.eclipse.debug.ui/pom.xml +++ b/org.eclipse.debug.ui/pom.xml
@@ -19,7 +19,7 @@ </parent> <groupId>org.eclipse.debug</groupId> <artifactId>org.eclipse.debug.ui</artifactId> - <version>3.15.300-SNAPSHOT</version> + <version>3.16.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <properties> <code.ignoredWarnings>-warn:+resource,-deprecation,unavoidableGenericProblems</code.ignoredWarnings>
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/codemining/DebugValueCodeMining.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/codemining/DebugValueCodeMining.java new file mode 100644 index 0000000..b535535 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/codemining/DebugValueCodeMining.java
@@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2022 Red Hat, Inc. and others. + * + * 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 + *******************************************************************************/ +package org.eclipse.debug.internal.ui.codemining; + +import java.util.function.Consumer; + +import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.views.variables.VariablesView; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.codemining.ICodeMiningProvider; +import org.eclipse.jface.text.codemining.LineEndCodeMining; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +public class DebugValueCodeMining extends LineEndCodeMining { + + private IVariable variable; + + protected DebugValueCodeMining(IDocument document, int line, IVariable variable, ICodeMiningProvider provider) + throws BadLocationException { + super(document, line, provider); + this.variable = variable; + setLabel(DebugUIPlugin.getModelPresentation().getText(variable)); + } + + @Override + public Consumer<MouseEvent> getAction() { + return e -> openVariableInVariablesView(variable); + } + + private static void openVariableInVariablesView(IVariable variable) { + + VariablesView view; + try { + view = (VariablesView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .showView(IDebugUIConstants.ID_VARIABLE_VIEW); + view.getViewer().setSelection(new StructuredSelection(variable)); + } catch (PartInitException e) { + DebugUIPlugin.log(e); + } + } + + @Override + public boolean isResolved() { + return true; + } + +}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/codemining/DebugValueCodeMiningProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/codemining/DebugValueCodeMiningProvider.java new file mode 100644 index 0000000..b960305 --- /dev/null +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/codemining/DebugValueCodeMiningProvider.java
@@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2022 Red Hat, Inc. and others. + * + * 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 + *******************************************************************************/ +package org.eclipse.debug.internal.ui.codemining; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.core.runtime.Adapters; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.codemining.AbstractCodeMiningProvider; +import org.eclipse.jface.text.codemining.ICodeMining; +import org.eclipse.jface.text.source.ISourceViewerExtension5; + +public class DebugValueCodeMiningProvider extends AbstractCodeMiningProvider { + + private boolean alreadyListening; + private IDebugEventSetListener listener; + + @Override + public CompletableFuture<List<? extends ICodeMining>> provideCodeMinings(ITextViewer viewer, + IProgressMonitor monitor) { + if (!isEnabled()) { + return CompletableFuture.completedFuture(List.of()); + } + final IDocument document = viewer.getDocument(); + if (viewer instanceof ISourceViewerExtension5 && !alreadyListening) { + alreadyListening = true; + listener = e -> ((ISourceViewerExtension5) viewer).updateCodeMinings(); + DebugPlugin.getDefault().addDebugEventListener(listener); + } + return CompletableFuture.supplyAsync(() -> { + List<DebugValueCodeMining> res = new ArrayList<>(); + for (int line = 0; line < document.getNumberOfLines(); line++) { + LinkedHashMap<String, IVariable> variablesOnLine = new LinkedHashMap<>(); + try { + IRegion lineInfo = document.getLineInformation(line); + for (int offsetInLine = 0; offsetInLine < lineInfo.getLength(); offsetInLine++) { + IVariable variableAtOffset = Adapters.adapt( + new TextSelection(document, lineInfo.getOffset() + offsetInLine, 0), IVariable.class); + if (variableAtOffset != null) { + try { + variablesOnLine.putIfAbsent(variableAtOffset.getName(), variableAtOffset); + offsetInLine += variableAtOffset.getName().length(); + } catch (DebugException ex) { + DebugUIPlugin.log(ex); + } + } + } + for (IVariable variableOnLine : variablesOnLine.values()) { + res.add(new DebugValueCodeMining(document, line, variableOnLine, this)); + } + } catch (BadLocationException e) { + DebugUIPlugin.log(e); + } + } + return res; + }); + } + + private boolean isEnabled() { + return DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_SHOW_VARIABLES_INLINE); + } + + @Override + public void dispose() { + DebugPlugin.getDefault().removeDebugEventListener(listener); + } +}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencePage.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencePage.java index 129c1a3..2f740d0 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencePage.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencePage.java
@@ -50,6 +50,8 @@ @Override protected void createFieldEditors() { addField(new BooleanFieldEditor(IDebugUIConstants.PREF_REUSE_EDITOR, DebugPreferencesMessages.DebugPreferencePage_2, SWT.NONE, getFieldEditorParent())); + addField(new BooleanFieldEditor(IDebugUIConstants.PREF_SHOW_VARIABLES_INLINE, + DebugPreferencesMessages.DebugPreferencePage_showValuesInline, SWT.NONE, getFieldEditorParent())); SWTFactory.createHorizontalSpacer(getFieldEditorParent(), 2);
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java index 72b5771..bc2d6e4 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java
@@ -59,6 +59,7 @@ public static String DebugPreferencePage_25; public static String DebugPreferencePage_26; public static String DebugPreferencePage_27; + public static String DebugPreferencePage_showValuesInline; public static String DefaultLaunchConfigurationsPropertiesPage_0; @@ -215,4 +216,5 @@ public static String RunDebugPropertiesPage_0; + }
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties index a2a56c2..6cb77f4 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties
@@ -52,6 +52,7 @@ DebugPreferencePage_31=&Prompt for confirmation when removing all triggerpoints DebugPreferencePage_32=&Prompt for confirmation when disabling all breakpoints DebugPreferencePage_5=Prompt for confirmation when deleting all e&xpressions +DebugPreferencePage_showValuesInline=Show debug values &inline on text editors LaunchingPreferencePage_1=&Build (if required) before launching LaunchingPreferencePage_2=Save required dirty editors before launching
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/IDebugUIConstants.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/IDebugUIConstants.java index e30a6fc..208e033 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/IDebugUIConstants.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/IDebugUIConstants.java
@@ -1280,6 +1280,13 @@ String PREF_DETAIL_PANE_FONT= "org.eclipse.debug.ui.DetailPaneFont"; //$NON-NLS-1$ /** + * Preference to enable variable view inline on text editors. + * + * @since 3.16 + */ + String PREF_SHOW_VARIABLES_INLINE = "org.eclipse.debug.ui.ShowVariableInline"; //$NON-NLS-1$ + + /** * Instruction pointer image for editor ruler for the currently executing * instruction in the top stack frame. * @@ -1347,4 +1354,5 @@ * @since 3.8 */ String COLUMN_ID_VARIABLE_VALUE_TYPE = COLUMN_PRESENTATION_ID_VARIABLE + ".COL_VALUE_TYPE"; //$NON-NLS-1$ + }