microsoft / microsoft/language-server-protocol

Allow signature help to explicitly specify "no parameters highlighted"

Open
#1,271 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature-request help wanted signature help
Dominant language
TypeScript
Stars
13k
Forks
1k
Avg merge
6d 1h
Merged PRs (30d)
10

Description

Given code like this:

def foo(a, b): ...

foo(1, 2, |)

If the cursor is on the last parameter to the call, we want to specify that nothing should be highlighted. Additionally, the function may be overloaded, in which case we specify per-signature active parameters (https://github.com/microsoft/vscode/issues/94637). Some of those overloads may not match what the user has written, and so none of the parameters should be highlighted.

The spec says:

	/**
	 * The active parameter of the active signature. If omitted or the value
	 * lies outside the range of `signatures[activeSignature].parameters`
	 * defaults to 0 if the active signature has parameters. If
	 * the active signature has no parameters it is ignored.
	 * In future version of the protocol this property might become
	 * mandatory to better express the active parameter if the
	 * active signature does have any.
	 */
	activeParameter?: uinteger;

And for the the signature itself:

	/**
	 * The index of the active parameter.
	 *
	 * If provided, this is used in place of `SignatureHelp.activeParameter`.
	 *
	 * @since 3.16.0
	 */
	activeParameter?: uinteger;

This means there is no spec-compliant way to say "don't highlight any parameters"; omitting the active parameter on the signature defers to the old-style active parameter field, which will be zero (the first parameter) if not provided or specified with an out of bounds value.

We can work around this in pyright/pylance by making use of the fact that the VS Code LSP client doesn't verify the values its given when they are numbers:

https://github.com/microsoft/vscode-languageserver-node/blob/2645fb54ea1e764aff71dee0ecc8aceff3aabf56/client/src/common/protocolConverter.ts#L587-L598

VS Code doesn't implement the "if out of bounds, assume zero" part of the spec, instead not highlighting a parameter, which is what we want, so it works. We've been using -1 as the out of bounds value: https://github.com/microsoft/pyright/blob/48a5f1284055e61f9887a6e0fbfb6176bae730bf/packages/pyright-internal/src/languageServerBase.ts#L702

However, the specs were retroactively changed to specify uinteger for many values, and some clients strictly check that the value is non-negative (https://github.com/microsoft/pyright/pull/1783), so we will likely need to move to some other out of bounds value to maintain this hack. Looking at other languages, I can see that gopls is also relying on this behavior, providing indexes past the end of the parameter list to avoid highlighting, so we can do that too.

But, swapping one hack for another doesn't really address the original need of being able to explicitly specify that no parameter is selected (for the single signature or for all).

Can the spec be modified in some way to explicitly allow something like this? E.g.:

  • Treat "index past end of parameter list" as "no highlight"; this may match the behavior of existing language servers.
  • Allow explicitly setting null or something to say "no highlight" behind a capability.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Review the SignatureHelp and SignatureInformation definitions quoted in the issue, along with the referenced VS Code protocol-converter behavior and pyright workaround. Determine a backward-compatible way to represent no active parameter for individual signatures and all signatures. Done means the specification clearly defines the representation, bounds behavior, and any required capability or versioning changes.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, developer-experience
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.