Open mjbvz opened 5 years ago
This api sketch proposes making diagnostic messages a list of parts. Parts would be joined together to form the message rendered in the editor:
interface TextDiagnosticPart {
readonly type: 'text';
/**
* Text rendered in the editor
*/
readonly text: string;
}
interface ExpansionDiagnosticPart {
readonly type: 'expansion';
/**
* Contents rendered for the expansion, such as the text `...`
*/
readonly contents: ReaonlyArray<DiagnosticPart>;
/**
* Lazily resolves the diagnostics.
*
* The could also be implemented using a provider or commands.
*/
expand(): Thenable<ReaonlyArray<DiagnosticPart>>;
}
type DiagnosticPart = TextDiagnosticPart | ExpansionDiagnosticPart;
The diagnostic type would then become:
export class Diagnostic {
...
message: string | ReadonlyArray<DiagnosticPart>;
...
}
Extensions
interface ClickableDiagnosticPart {
readonly type: 'clickable';
/**
* Contents rendered in the diagnostics
*/
readonly contents: ReaonlyArray<DiagnosticPart>;
/**
* Command executed on click
*/
readonly command: Command
}
interface CodeDiagnosticPart {
readonly type: 'code';
/**
* Language to use for syntax highlighting
*/
readonly language: string
/**
* Code rendered in the editor
*/
readonly contents: ReaonlyArray<DiagnosticPart>;
}
MessagePart
(needs better name) so that parts could also be used in hovers and other UI locations/cc @sandy081, @jrieken, @dbaeumer, @DanielRosenwasser, @weswigham, @amcasey
FYI @minestarks
Probably worth noting that for the syntax highlighting extension bit, it's very possible that syntax highlighted and linked/expanded ranges overlap; so them being mutually exclusive parts would seem to prevent that.
@weswigham Good point. I've updated CodeDiagnosticPart
to potentially handle nesting better. One difficult thing about colorization is that the snippets may not actually be valid code. T<...>
for example would colorize T
as a variable.other.constant
instead of as a type if we reused the js/ts grammar.
In the TS / editor sync today, we also discussed a proposal that would allow specific spans to marked as code or as expandable, something like:
interface DiagnosticMessage {
/**
* Text rendered in the editor
*/
readonly text: string;
/**
* Ranges within the text that can be expanded.
*/
readonly expandableRanges?: Range[];
/**
* Ranges within the text that should be rendered as code
*/
readonly codeRanges?: { range: Range, language: string } [];
}
Keeping the range correct after expansion happens could get tricky
Is this inventing our own markup language? How about using markdown as proposed by @mjbvz here: https://github.com/Microsoft/vscode/issues/54272
Rendered markdown could be used to implement hyperlinks (though you'd need to ensure file urls with locations work fine in markdown link tags) and if you're lucky syntax highlighting (although what's keeping the editor highlighting and the markdown highlighting consistent?) but I don't think it covers the expandable lazy ranges (the original request) - unless that markdown support goes all the way to full blown html/js support.
It's might also worth noting that for the syntax highlighting part, we'd likely be trying to colorize things in specific contexts, so in addition to the standard markdown language selector, you'd also need to be able to somehow specify a specific tmLanguage rule to start in (instead of the root rule - this way our types get syntax highlighted as types and not statements). So in that regard, getting pre-classified spans (a la quickinfo) back from the language service might be easier than messing with picking apart tmLanguage rulesets; but I'm not the most familiar with them, so I'm not sure.
unless that markdown support goes all the way to full blown html/js support.
Yeah, good point... We could experiment with commands. We already support command-links and we could have a special command that replaces the link text...
you'd also need to be able to somehow specify a specific tmLanguage rule to start in (instead of the root rule - this way our types get syntax highlighted
The markdown rendering picks up any language that's registered (by extensions). So it would require some special code-chunk-language so that MD will use the grammar that came with that language.
Stepping back a bit: The idea is to keep of all this in the editor hover, right? So make that smarter and a bit more interactive? I am asking because the hover is easy to dismiss and maybe not the best place for a UX in which the user invests time configuring its state.
My 2 cents, I would not have asynchronosity in error message which might not have good UX especially in Hovers. Why does this needs to be async first of all Is it expensive to compute complete message?
Also not a big fan of having UI semantics. My first step would be to use MD string. BTW, Is not the related information can be used to show more information? I think we do not restrict this to be used only for multi-diagnostics but also for adding more information.
Why does this needs to be async first of all Is it expensive to compute complete message?
It can be, yes. Our typesystem has the ability to generate new types by mapping old ones, so you can get very complex or large (anonymous) types with a very short sequence of type operators. And when those appear in errors, well... Things can get difficult to grok very quickly since there's simply too much to print - today we're forced to truncate the output, but making it explorable just like how dotting off the object can reveal more info would go a long way toward making it easier to work with.
My 2 cents, I would not have asynchronosity in error message which might not have good UX especially in Hovers.
Ignoring hover over red squiggles for a moment, errors still appear in the problems window and the f8 error bar as well, both of which are much more persistent. I'd think persisting the hover text as it is updated is an extension of those two.
BTW, Is not the related information can be used to show more information?
Nope - in this case the lazy querying is key to making it work. It allows us to gradually expose/generate the shape of complex types as requested, and only the parts requested. We actually have the ability to construct infinitely deep anonymous types - today we cut these off after printing one level of the type with a ...
, but being able to expand these to an arbitrary depth as needed would be very nice. We do use related info where we can - it just doesn't help in complex type display/type truncation cases. (And secondarily would be a gratuitious way to "linkify" all the references in the types in an error, TBH - very nonlocal)
Stepping back a bit: The idea is to keep of all this in the editor hover, right? So make that smarter and a bit more interactive? I am asking because the hover is easy to dismiss and maybe not the best place for a UX in which the user invests time configuring its state.
What I was hoping was that diagnostic state was synchronized between the problems window/the f8 error bars/hover strings between full refreshes. That way you can expand within the hover if you want (then go back to it and still see it expanded), but also explore in the other places errors are displayed. In our meeting, someone mentioned that eclipse has the ability to copy things like individual diagnostics (plus stack traces and more) into a project context pane to allow them to persist and be inspected, which could work, too, but is maybe less continuous an experience than just being able to interact with a diagnostic anywhere you see it.
adding @misolori - call for diagnostics UX ideas
Here's the most minimal API for this we could have on the vscode side:
Make Diagnostic::message
a markdown string
In the diagnostic messages, allow hyperlinks of the form:
some text [...](command:editor.expandDiagnostic?_typescript.resolveDiagnostic,123) and more text
The editor.expandDiagnostic
command is a special VS Code command that delegates out to another command to handle the actual expansion. In this case, it would invoke the _typescript.resolveDiagnostic
command with the diagnostic object and the expansion id 123
_typescript.resolveDiagnostic
would return a promise to a MarkdownString
. VS Code would then replace the original editor.expandDiagnostic
link with the rendered string
A few things with this approach:
_typescript.resolveDiagnostic would return a promise to a MarkdownString. VS Code would then replace the original editor.expandDiagnostic link with the rendered string
In case TypeScript already knows the omitted text behind [...]
it could just add it as argument, [...](command:md.expand?FOO
). That would prevent extra commands and round trips.
This would let you use other markdown features like bolds and italics.
Yes. My POV is that it's just like Hover
and editor decorations and I believe people can build cool things with it, see GitLens. Sure, there is a risk of folks turning us into a Christmas tree but then I don't use such an extension. We can also consider disabling certain markdown features, e.g. tables or images, in certain places.
This is pretty VS Code specific. TypeScript would still likely want a diagnostic structure api closer to the one I originally proposed.
Haha - better VS Code specific extension API than TypeScript specific extension API. Honestly, the proposal smells very TypeScript-tailored and we should first circle in other languages with complex error messages, maybe rust-lang or lean.
I think there should be a way to automatically expand all of the three dots when selecting the text, I use this shortcut:
Ctrl+K Ctrl+I
Hover, Ctrl + A
select all Ctrl+C
copy
And when I select all I want the whole type, not the abbreviated form. In past I could use that to get the whole type of any JSON object pasted to VSCode, but this is not possible anymore.
Please allow these to be expanded somehow. It has become VERY frustrating working with types now in typescript. I'm wasting so much time trying to get everything to work with the different intellisense features, and not being able to copy and paste complete types, or even read them properly has become VERY frustrating and time consuming. PLEASE PLEASE PLEASE add SOME way (even just a command) to show the full type without any abbreviations.
One problem is that I don't even know which type is being repeated or if more than one is being repeated. A type variable layout would be more clear.
I'm used to hacking other peoples code, so I am perfectly capable of building an extension or changing the source code, I just don't want to have to do that with everything I use. Why can't the tools just do what they're supposed to do and get out of the way?
See https://github.com/microsoft/vscode/issues/64566#issuecomment-590140308
I see at the top that this can be staticly chosen, but I have no idea how to do that. Is it a setting?
This is a really annoying issue; honestly there is never a time when I don't want to see the whole thing. Optimize for readability? How is it readable to only see a small part of the relevant information?
Would really really like to see this become a setting that was easy to tweak :-( it would save me a lot of time right now with what I'm working on
noErrorTruncation: true
At some point someone pointed out the TypeScript tsconfig.json setting compilerOptions.noErrorTruncation
. This in fact seems to solve the problem.
@Arlen22 It doesn't work.
The bug to track is this: https://github.com/microsoft/TypeScript/issues/26238
I am also looking for a way to access "computed types" I've posted on StackOverflow about it here. It would be nice to have better tooling / understanding about what a type is, and I'd personally like a CLI tool that could give me a glimpse, rather then trying to get VSCode to show everything in a tooltip on hover.
same issue + 1
Somewhat related is my recently-closed-as-out-of-scope suggestion of being able to cmd-click on types in the tooltip to dig into those types (like you can in Eclipse). That request is also about having "links" within the tooltip.
I found https://github.com/intellij-rust/intellij-rust/pull/4217 through https://github.com/microsoft/vscode/issues/16221#issuecomment-518658249 and it seems to be doing almost the same thing (it expands all the way with just 1 click). I would imagine it being similar to that except having the option to advance 1 step at a time?
What I'm doing meanwhile is to use simplify from type fest to wrap big types
It successfully expands the type on VSCode and I can freely scroll it.
am also look a way to get something like on hover
instead of this
i tried ctrl, alt on hover but not work, any tips to extends full alias definition on hover ?.
can we prioritize this, we eagerly need this feature to expand all the complex types in our codebase.
i'm currently doing https://github.com/Microsoft/TypeScript/issues/26238#issuecomment-672086446, but that's undesired because sometimes i don't want to expand the full type.
@weswigham @jrieken any news on this issue?
We have been waiting for any solution for 5 years now, let us know are you considering it? This problem is really annoying and limiting us
Related: #94679 and microsoft/TypeScript#35601.
Related on Stack Overflow:
Right now it's like dangling a steak in front of a canine; as a dev seeing the inferred type in the tooltip and knowing VS Code can expose the complete type yet not being able to copy or extract it in any way... This would be the most effective feature to help us avoid having to manually setup up types from a JSON payload or code-gen'ing our types, especially for those that are combinations of other types.
It would be nice if we can click on the ellipses or more
then we can see some more.
This is actually not a VSCode problem but a TypeScript problem.
Proof:
1) Create a very long type that displays ... 15 more ...
when you hover it
2) Deliberately mis-assign it, for example const foo: VeryLongType = {}
missing required properties or something like that
3) Run npx tsc
You'll see even in your terminal TypeScript collapses the type and outputs ... 15 more ...
.
But I would also like to see this fixed, because I often need to copy some complex computed types from one project to another, and this would save me a lot of chore work.
To fix this you can patch the TypeScript node module in your project (to at least get terminal output), or patch the TypeScript node module that VSCode uses.
More information here:
https://github.com/microsoft/TypeScript/issues/35601#issuecomment-921752554
Long term solution by @extremegf
in vscode
node_modules/typescript/lib/tsserver.js
var defaultMaximumTruncationLength = 160
1000
or value of your choosing.PS.
noErrorTruncation
in tsconfig didn't work for me.Before: with ...
After: You can also drag the bottom border
Have written a quick patcher that runs automatically after installing new dependencies or updates using a post script.
Add the following to scripts
in package.json
:
"postinstall": "./scripts/patch-ts.sh",
Add the following to scripts/patch-ts.sh
(and remember to run chmod +x ./scripts/patch-ts.sh
#!/bin/bash
FROM="var defaultMaximumTruncationLength = 160;" TO="var defaultMaximumTruncationLength = 1e6;"
sed -i -e "s/$FROM/$TO/g" "node_modules/typescript/lib/typescript.js"
echo "Annotation Truncation Length patched successfully"
3. Run `yarn install` or `npm install`
4. Reload Window
5. ???
6. Profit
Long term solution by @extremegf
in vscode
1. Using Ctrl+P, Go to `node_modules/typescript/lib/tsserver.js` 2. Find line `var defaultMaximumTruncationLength = 160` 3. Change it to `1000` or value of your choosing. 4. Open Ctrl+Shift+P menu, select TypeScript: Select TypeScript Version... 5. Ensure it's set to Use Workspace Version 6. Full restart VSCode - reloading workspace is not enough. 7. Verify that ... abbreviations are gone from type hints.
Since TypeScript 5.6 this is now located in node_modules/typescript/lib/typescript.js
.
There also seems to be a noTruncation
variable, not sure if that was there prior to 5.6 (related to noErrorTruncation
tsconfig option) but I'm going to explore it a bit further
Edit: yeah it was just the noErrorTruncation
stuff. Just set your defaultMaximumTruncationLength
to 5k and you'll be good 👍🏼
Problem
JS and TS diagnostic messages can get quite large, especially when dealing with frameworks like Vue or react. The TS team has worked to significantly improve and shorten diagnostic messages, including replacing complex type information with
...
, however there are still cases where you need to see the full type information. Right now, we have to staticly choose to expand the additional information or not. They would like the user to be able to interactively expand types within a diagnosticIn addition, the overall diagnostic experience could be improved. Two areas identified talking with the TS team:
Refs
11847
Desired User Experience
Consider a diagnostic message
T<...>
. We would like the...
to be something like a link. Clicking it would expand the diagnostic message toT<Array<...>>
, which itself contains another expandable linkRequirements
The main focus is on being able dynamically to expand sections of a diagnostic. We need new VS Code API support for this and then will need languages to adopt this API. However, I think the other two features should be considered while designing the new diagnostics API as they are likely something we would like to support and will influence overall api design
For expansion, we want to be able to:
Many of these features also make sense for quick info hovers