-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Investigate debug visualization extension points #197287
Comments
@thegecko and I had some discussion on the linked issue, continuing here #197458 (comment) |
I'd love to have better support for visualizations! I think a fundamental question is if these visualizations should be a modal one-time experience (as in VS https://youtu.be/1Nq4E4aN1WA?t=85, maybe you can see it as copilots "inline chat") or a more interactive non-modal experience (as in my debug visualizer extension, which would correspond to copilots ghost text once you setup the visualization). The modal experience is much easier to implement, but much more inconvenient to use when you want to inspect how value visualizations change as you step through your code, as the visualization disappears when you step. I would really like to see the non-modal experience, as it is a much more useful feature.
This basically replaces the "generic" tree in the hover with a specialized, extension-contributed one, right? I think extensions might want to be able to return Maybe the non-modal approach could work like this (similar to how SuggestProviders work): namespace debug {
/**
* Registers a custom data visualization for variables when debugging.
*
* @param selector Identifies data this visualizer applies to. It will only
* be shown for DAP variables whose properties are a superset of the
* `variable` property, and whose session type is `debugType`.
*
* @param provideView Invoked for a variable when a user picks the visualizer.
* It may return a {@link TreeView} that's shown in the Debug Console or
* inline in a hover.
*/
export function registerDebugVisualizationProvider<T extends IDebugVisualization>(
selector: { debugType?: string; variable?: Dap.Variable },
// Serves as dynamic discoverability mechanism (selector applies first though).
provide: (context: IDebugVisualizationContext) => ProviderResult<T[] | undefined>,
// Allows to delay computing `treeView`
resolve: (visualization: T) => Promise<void>;
): Disposable;
export interface IDebugVisualization {
name: string; // A human readable (localized) name of this visualization
id: string; // The id to remember which visualization was picked the last time
treeView?: TreeView; // If this visualization is selected, this tree view replaces the "generic" tree view of the value
visualizeCommand?: ICommand; // This command is shown next to the value when an inline visualization cannot be done.
}
export interface IDebugVisualizationContext {
/** The variable the user wants to visualize */
variable: Dap.Variable;
/** The container the variable was set in. */
// authors note: this and the name is required for use of `setVariable` / `setExpression`
container: Dap.Variable;
/** The name of the variable in its container. */
name: string;
/** The debug session the variable belongs to. */
session: DebugSession;
/** The currently selected debug visualization for this value. This gives extensions a chance to use a single DAP request for discovery and visualization computation. In that case, a resolve call wouldn't have to send a second DAP request to actually compute the visualization */
preferredDebugVisualizationId?: string;
}
}
I think the super power from visualizations really comes from custom UI. But I understand its a hassle to implement (also, because some visualization libraries are large and take time to load, you want to reuse the webview). |
It may be useful to outline some real-world use cases which this proposal may (or may not!) be designed to support.
Some further thoughts:
|
Persistence: it would be possible for an extension who opens its own webview to also have a DebugAdapterTracker to update a webview as the state changes. Provider/resolver: I agree, that is a good idea. Updated the API in the main issue. "This basically replaces the "generic" tree in the hover with a specialized, extension-contributed one, right?" -- yes Webviews: yes, webviews are more of a nightmare when it comes to showing them inside tree views. This is a path trod by notebooks in years past. For performance, showing many individual webviews is a poor experience, so notebooks ended up with the editor layer and webview layer. But getting this right has taken years and is still presenting challenges, so I have no appetite at all to do that here. But, as mentioned, inline 'popouts' might be a way to make this happen, and could be added in the future by adding some extra I'll update the main issue with scenarios to support. Searching/filter: I don't think this is in scope for this work.
Other thought. I realized the "variable" selector as I have defined it is not very good, since e.g. the common case thegecko is looking would want any defined If we continue to go with an object selector, I would type it as
I don't want to have a more tailored selector with properties like |
We currently use It just so happens there exists a |
I would find it particularly nice, if the "visualization extension points" could also be reused not only for the hex editor, but also for "Go to source location" proposed in microsoft/debug-adapter-protocol#372. Afaict, the current proposal would already support adding such a "Go to source location" button, or am I missing something? |
also, CC @vadimcn since the proposed extension points here might also be very useful for https://github.com/vadimcn/codelldb and its data visualizations |
I think this should align with the Rather it should return the command that does this.
That would be nice! |
Good point, we should do this for extension activation anyway.
Maybe, we do have precedent for |
I've done some initial work on this, as well as initial refinement in the API, which is in the main branch of VS Code. It currently supports command-generating visualizers. You can see an example of a basic 'base64 visualizer' in https://github.com/microsoft/vscode-extension-samples/tree/connor4312/debug-viz-demo/proposed-api-sample, and try it in VS Code Insiders.
|
@connor4312 nice work! I think this is an excellent addition and looks very flexible.
Are there any specific things you want feedback or testing around? |
Any feedback you want to provide on the initial version is great -- though the current exposure is fairly simple and "works for me" is also good feedback 🙂 The more gnarly part will be letting it support subtrees, which I'll look at this coming iteration. |
This sounds interesting. I wonder how it'll affect or help with C++ things (Natvis and GDB pretty printers, which I think the MS C/C++ extension currently supports). |
Well, it "works for me"! As long as the hex edit recommendation is removed when this is merged :) Playing some more, I notice multiple visualizations are put into a menu: Would it be worth supporting group names (including inline) to control this and group accordingly if multiple appear?
Is this supporting branches further down the graph? |
Hi @connor4312 , since this is a big work item, I suppose this will not be finalized this milestone, hence I am changing the milestone to |
Just tried out the API again. What Also, it seems like it only works in the variable view, not in the watch view or with hovers. Would be very nice if this would be supported there as well. |
@connor4312 can we have an update on this being merged, please? We are keen to promote our new memory inspector in the VS Code UI: https://marketplace.visualstudio.com/items?itemName=eclipse-cdt.memory-inspector |
Any updates in getting this merged @connor4312 ? |
I just noticed this issue. One suggestion I would like to make is that it would be good if there was special casing in the registration mechanism for text, since it is a common data type to visualize, and it exists in all languages. To test if a variable is text, check if VariablePresentationHint.attributes has |
I'm new to this party because I seem especially bad at finding existing issues that already address things I want... I don't think a new API is needed, and I'd amend the initial bullet list to:
Adding menus/items to existing views from extensions works well for editors and various tree views. Isn't that really all that's needed? I get that custom webviews are a pain, but in my experience there's not much you can do without them, and I think that's a problem that should be addressed generally. I quite like the tree-inside-a-tree thing as an alternative to VS's natvis or lldb scripted variable formatting, but don't those respective debuggers already return pre-formatted structures over DAP? The modal aspect of VS's visualization makes it all but useless (to me, at least); don't even think about the possibility of entertaining the thought! Edit: just wanted to add that I have nothing against your API proposal, but it's been over a year, and perhaps just bringing the variables/watch panes to parity with similar views would be less... contentious? |
VS proper has some data visualization like this:
...and personally I've never been a fan of how we represent things like XML elements or binary data in debug hovers and the REPL. In large part this is because we have to have a 'generic' view that gives all possible information, so we can't be more concise when showing things like DOM tree.
So it would be nice to have a way for visualizations to be contributed, with similar affordances to what VS provides.
My initial thought at an API is something like this. Note that we don't bring in DAP types in vscode.d.ts, so they would be typed as
unknown
and cast by the extension author.cc @hediet @roblourens @joj
The text was updated successfully, but these errors were encountered: