Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _data/specification-3-17-toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@
anchor: textDocument_linkedEditingRange
- title: moniker
anchor: textDocument_moniker
- title: inlay hints
anchor: textDocument_inlayHints
- title: Change Log
anchor: changeLog
children:
Expand Down
127 changes: 127 additions & 0 deletions _specifications/specification-3-17.md
Original file line number Diff line number Diff line change
Expand Up @@ -8217,6 +8217,132 @@ export interface Moniker {

Server implementations of this method should ensure that the moniker calculation matches to those used in the corresponding LSIF implementation to ensure symbols can be associated correctly across IDE sessions and LSIF indexes.

#### <a href="#textDocument_inlayHints" name="textDocument_inlayHints" class="anchor">Inlay hints (:leftwards_arrow_with_hook:)</a>

> *Since version 3.17.0*

Inlay hints are short textual annotations that are attached to points in the source code.
These typically spell out some inferred information, such as the parameter name when passing a value to a function.

```typescript
/**
* Well-known kinds of information conveyed by InlayHints.
* Clients may choose which categories to display according to user preferences.
*/
export enum InlayHintCategory {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are those categories necessary for a 1st iteration? I don't see categories in "Hover" nor "CodeLens" for instance. I think a 1st iteration should take place without them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, good question. These are present in both VSCode's proposed API and rust-analyzer (though Rust's categories have some overlap with classes, too)

I see two main purposes:

  • allow users to selectively turn on/off hints by category. (This could also/instead be done by hintClass, but it seems more complex).
  • style hints differently (e.g. a subtle color tint on the chips). This seems useful but I haven't seen it in the wild, maybe it isn't?

I find the configurability argument quite compelling, as this is a highly invasive/visible feature.
Categories don't add a lot of spec complexity, and are optional for both client & server.
So I'm inclined to include them but not wedded to it, definitely want to hear more opinions.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the configurability argument quite compelling, as this is a highly invasive/visible feature.

The thing is that to properly handle it, it would require tools to dynamically generate some page which lists the available categories in the LS and allow to enable/disable some of them. The LS would require to allow more introspective than usual; categories/kinds are usually hardcoded pre-identified enums of things shared by many languages more than dynamically filled placeholders for LS-specific stuff.
If we need to distinguish different kinds, I think it's better to do it just like Completion and other do: the protocol defines a static list of supported kinds; that clients can then code a behavior for.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that was definitely the intention here: clients could show fixed checkboxes for Params/Types/Other.
(In fact I thought about using classes for configuration, but it seems too complicated for exactly the reason you mention)

The reason to allow other values is just to make protocol versioning/extensions easier:

  • avoid deadlock where neither clients/servers/spec feel they should be the first to support a new category
  • avoid complicated capability negotiation (completionItemKind.valueSet) to ensure back-compatibility
    It's possible different servers use the same non-standard category name to mean different things, I don't think this is a large risk.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I've tweaked some comments and such, trying to make this clearer)

/**
* The range is an expression passed as an argument to a function.
* The label is the name of the parameter.
*/
Parameter = 'parameter',
/**
* The range is an entity whose type is unknown.
* The label is its inferred type.
*/
Type = 'type'
}
```

The `textDocument/inlayHints` request is sent from the client to the server to retrieve inlay hints for a document.

_Client Capabilities_:

* property name (optional): `textDocument.inlayHints`
* property type: `InlayHintsClientCapabilities` defined as follows:

```typescript
interface InlayHintsClientCapabilities {
/**
* Whether implementation supports dynamic registration. If this is set to
* `true` the client supports the new `(TextDocumentRegistrationOptions &
* StaticRegistrationOptions)` return value for the corresponding server
* capability as well.
*/
dynamicRegistration?: boolean;
}
```

_Server Capability_:

* property name (optional): `inlayHintsProvider`
* property type: `boolean | InlayHintsOptions | InlayHintsRegistrationOptions` is defined as follows:

```typescript
export interface InlayHintsOptions extends WorkDoneProgressOptions {
}
```

_Registration Options_: `InlayHintsRegistrationOptions` defined as follows:

```typescript
export interface InlayHintsRegistrationOptions extends
TextDocumentRegistrationOptions, InlayHintsOptions {
}
```

_Request_:

* method: `textDocument/inlayHints`
* params: `InlayHintsParams` defined as follows:

```typescript
export interface InlayHintsParams extends WorkDoneProgressParams, PartialResultParams {
/**
* The text document.
*/
textDocument: TextDocumentIdentifier;

/**
* The range the inlay hints are requested for.
* If unset, returns all hints for the document.
*/
range?: Range;

/**
* The categories of inlay hints that are interesting to the client.
* The client should filter out hints of other categories, so the server may
* skip computing them.
*/
only?: string[];
}
```

_Response_:

* result: `InlayHint[]`
* partial result: `InlayHint[]`
* error: code and message set in case an exception happens during the 'textDocument/inlayHint' request

`InlayHint` is defined as follows:

```typescript
/**
* An inlay hint is a short textual annotation for a range of source code.
*/
export interface InlayHint {
/**
* The text to be shown.
*/
label: string;

/**
* The position within the code this hint is attached to.
*/
position: Position;

/**
* The kind of information this hint conveys.
* May be an InlayHintCategory or any other value, clients should treat
* unrecognized values as if missing.
*/
category?: string;
}
```

**TODO**: Do we need a `/refresh` server->client call, like with SemanticTokens and Code Lens?

**TODO**: Likely future evolution: add a `/resolve` call enabling interactions with hints. Should we foreshadow this?

### <a href="#implementationConsiderations" name="implementationConsiderations" class="anchor">Implementation Considerations</a>

Language servers usually run in a separate process and client communicate with them in an asynchronous fashion. Additionally clients usually allow users to interact with the source code even if request results are pending. We recommend the following implementation pattern to avoid that clients apply outdated response results:
Expand All @@ -8240,6 +8366,7 @@ Servers usually support different communication channels (e.g. stdio, pipes, ...
#### <a href="#version_3_17_0" name="version_3_17_0" class="anchor">3.17.0 (xx/xx/xxxx)</a>

* Add support for a completion item label details.
* Add support for inlay hints.

#### <a href="#version_3_16_0" name="version_3_16_0" class="anchor">3.16.0 (12/14/2020)</a>

Expand Down