Skip to content

API for showing additional info in a hover #195394

Description

@mjbvz

Problem

For TS, one of our most popular feature requests is showing expanded type information in hovers. For example, with the code:

type FooType = string | number

const foo: FooType = 1

Hovering over foo today shows FooType. While this is sometimes what you want, other times you'd like to see the type expanded to string | number instead

While we could add a global setting for expanding types in hovers, this isn't a great solution as sometimes the expanded type is very confusing. Really we want to provide both the simplified and expanded hover info and make it easy to switch between them

Feature Request

Add new UI and apis that users to request a more detailed version of a hover. The user action for this could be:

  • A keyboard shortcut that expands the currently showing hover hover when pressed
  • A button in the hover the lets you toggle between different levels of detail

We believe that other languages besides typescript could use this functionality as well. Jake Bailey (@jakebailey) brought up Python for example but C++, c#, and any other languages with complex types could likely benefit

Activity

  1. added
    feature-requestRequest for new features or functionality
    editor-apiIssues about the API of vscode in the area of editors
    and removed on Dec 4, 2023
  2. added this to the Backlog milestone on Dec 4, 2023
  3. aiday-mar commented on Feb 19, 2024

    @aiday-mar
    Contributor

    Hi Jake Bailey (@jakebailey) Matt Bierner (@mjbvz), we have discussed this issue in the team and I see three possible ways to implement this:

    (1) We can propose a new API provideExtendedHover which would have the same signature as the existing provideHover, and would be called when the user requests more detailed hover information. The extended hover information will entirely replace the previous hover information. The downside of this method, is that we have no way to enforce that the new hover information will in fact be an extension of the initial hover information, as one could return any random markdown string through this method. A variant of this method could be to instead add a boolean in the signature of provideHover to signal that one wants extended hover information.

    (2) Instead we could change the class Hover which is returned by provideHover, so that it has one more field additionalContents: MarkdownString. The additionalContents markdown string would be displayed below the current hover when the user requests more information. The disadvantage of this approach is that one can not replace the whole current hover information with something new, since the new information is instead appended at the end on request. The other potential disadvantage of this method is that all the extended hover information will be shown at once, so the user can not target what extended information to show exactly. The advantage however is that this approach is simple.

    (3. a) Another idea that was discussed by our team is the following. We could allow extension authors to return hover markdown information with custom URI links. On click of this custom link, we would do a request to the hover provider through a proposed API resolveLink that would return a markdown string that would either replace the original link or be appended at the end of the hover (to be discussed still). In other words, the flow would be as follows:

    1. In a hover markdown string that contains FooBar as an expandable type, the TS team could enclose FooBar in a link
    2. On click or hover of this link (to be discussed), we would send the following request:
    const link = CustomUri('FooBar', opts);
    const res : MarkdownString = hoverProvider.resolveLink(link);
    
    1. The result res will either replace the custom uri in the hover, or be appended to the bottom of the current hover.

    This idea would require us to introduce a new proposed API resolveLink. The advantage of this idea is that the user can decide what information exactly to expand (perhaps the user does not want all the expanded information). This puts however more work on the extension authors.

    (3.b) We have also discussed another variant of 3.a. The flow is as follows:

    1. In a hover markdown string that contains FooBar as an expandable type, the TS team could enclose FooBar in a custom link as follows:
    const x : [FooBar](file://c/:/myworkspace/FooBar.ts#L250C33)
    
    1. On click or hover of this link (to be discussed), the controller would use the associated link to fire a hover request for the file file://c/:/myworkspace/Hello.ts at line 250, column 33.
    2. The result will be displayed at the bottom of the current hover.

    In the case of TypeScript, the link will point to the definition of FooBar. This idea is simpler in that it does not require to manually process links through the implementation of an resolveLink API. The disadvantage of this method however is that the extension author needs to define the appropriate link in the custom URI, and can not add more information then what is otherwise requested.

    Please let us know what approach you think is more appropriate and what would suit better the needs of the TypeScript team. Thank you.

    cc Johannes Rieken (@jrieken) Henning Dieterichs (@hediet) Martin Aeschlimann (@aeschli) Ulugbek Abdullaev (@ulugbekna)

  4. mjbvz commented on Feb 22, 2024

    @mjbvz
    ContributorAuthor

    Thanks Aiday Marlen Kyzy (@aiday-mar)! Either 1 or 2 sound fairly easy and I think would address the original request

    I personally prefer approach 1 where we pass a boolean or enum to provideHover as I think this will be the easiest to adopt and fully replacing the hover gives us a lot of flexibility

    However if we go with approach 1, we'd also likely want a way to figure out a way for providers to tell us if they can provide extended info or not. That way we can show an expand button in normal hovers. Maybe we could add a new isExpandable field on vscode.Hover?

    Ryan Cavanaugh (@RyanCavanaugh) Daniel Rosenwasser (@DanielRosenwasser) What do you think about these proposals?


    Approach 3 is interesting and something that we've talked about before for improving our diagnostics UX. I especially like that it could let us support go to definition and other language features in hovers. However it will also be much more complicated to implement in VS Code and for extensions, so I'm sure if we're ready to start down that road right now

    One nice feature of approach 1 or 2 is that we could implement 3 on top of them later too

  5. RedCMD commented on Mar 4, 2024

    @RedCMD
    Contributor

    With (2). couldn't additionalContents: MarkdownString be optional?
    with the expanded info button based off, if additionalContents is present or not

  6. alexdima commented on Mar 4, 2024

    @alexdima
    Member

    To discuss (raw notes):

    proposal 4: the hover provider returns an URI which is then interpreted as a text document and rendered in the hover. This allows us to invoke the DocumentLinkProvider on that document.

    proposal 5: the hover provider returns another field (annotations) which references offsets into the markdown content. Via annotations we could link to locations (similar to proposal 3b). It could be another field in the Hover or it could be MarkdownStringWithAnnotations.

  7. aiday-mar commented on Mar 4, 2024

    @aiday-mar
    Contributor

    I have discussed the proposals in #195394 (comment) with Alexandru Dima (@alexdima). Conclusions from the discussion are as follows:

    • Solution 1 allows users to return any markdown string in the method provideExtendedHover which would break the contract of returning only extended information.
    • Solution 3.a and 3.b imply we would use custom links (like command links) in Markdown code blocks which are currently not supported. To implement these proposals, we would need therefore to do some pre-processing or post-processing of the content to turn it into a proper Markdown string. This implies deviating from standard Markdown in the content hover which is not ideal.

    2 more proposals have been made in the comment #195394 (comment) above. I have scheduled a meeting to discuss this work further.

  8. jakebailey commented on Mar 4, 2024

    @jakebailey
    Member
    • Solution 1 allows users to return any markdown string in the method provideExtendedHover which would break the contract of returning only extended information.

    Why is this a concern? Why would anyone put completely different info into a hover tooltip? That seems like it would not be productive for any API consumer (and one could totally "misuse" any other feature for other uses already?).

  9. aiday-mar commented on Mar 4, 2024

    @aiday-mar
    Contributor

    Indeed that would not be productive for any API consumer. The idea is to limit this possibility of this happening.

    I will bring up this thread in our meeting and let you know of the discussion later.

  10. aiday-mar commented on Mar 5, 2024

    @aiday-mar
    Contributor

    Hey all. We have discussed all of the proposals in a meeting, and decided to move forward with proposal 1, since it seems to be what best suits the needs of the TypeScript team. We will put proposal 5 on the backlog, and potentially implement it in the future too, since proposal 1 can co-exist with proposal 5.

    To give more detail about the implementation, extensions will be able to return a hover with additional fields currentZoomLevel, canZoomOut, canZoomIn (names are yet to be refined). On request of a zoom in, or zoom out, requests will be made through the provideHover method (which will have an additional parameter zoomLevel) for hover results. Extensions will thus be able to provide gradually more and more information on zoom in.

  11. starball5 commented on Mar 6, 2024

    @starball5
  12. maxpaj commented on Mar 27, 2024

    @maxpaj

    Any progress, or projection when we can expect to have it released?

  13. aiday-mar commented on Mar 28, 2024

    @aiday-mar
    Contributor

    Hi maxpaj yes so the PR is almost finished. We are planning on pushing it at the beginning of the next iteration. You can track the PR here #204721.

  14. clcoco commented on Apr 8, 2024

    @clcoco

    Hi maxpaj yes so the PR is almost finished. We are planning on pushing it at the beginning of the next iteration. You can track the PR here #204721.

    Does this mean we will be able to get it with the next update?

  15. aiday-mar commented on Apr 8, 2024

    @aiday-mar
    Contributor

    Hi clcoco so this PR will likely be part of VS Code 1.89, but not 1.88

  16. aiday-mar commented on Apr 22, 2024

    @aiday-mar
    Contributor

    Fixed with #210472

  17. locked and limited conversation to collaborators on Jun 11, 2024
  18. aiday-mar commented on Sep 11, 2024

    @aiday-mar
    Contributor

    In the last UX sync, Gabriela Araujo Britto (@gabritto) who is currently working on adopting the expandable hover for TypeScript, mentioned the TypeScript team would like to add links in the hover which when clicked would expand the specific type. There are several reasons for this:

    • There could be many types in a hover, and it would be nice if the user could expand a specific type not the whole text all at once
    • The hover would be smaller

    The hover is a nice way to display the types because it is easily discoverable and can be used to easily expand and contract type information. In the UX sync certain other ideas have been proposed for how to display the type information:

    • Add an action to the status bar called for example Inspect Types which would open up a view where the types could be shown.
      • We could show the peek view with the type definitions
      • Or the explorer view with the type information
    • Another idea was to allow 1 to 2 levels of expansion only with the current UI then move to the explorer view

    We should discuss this other language extensions authors and collect more feedback to see if/how much they would find it useful to have expandable links in the hover.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

editor-apiIssues about the API of vscode in the area of editorseditor-hoverEditor mouse hoverfeature-requestRequest for new features or functionalityon-testplan

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions