-
Notifications
You must be signed in to change notification settings - Fork 893
Description
Context
- This issue is not a bug report. (please use a different template for reporting a bug)
- This issue is not a duplicate of an existing issue. (please use the search to find existing issues)
Description
Problem Statement
The textDocument/hover
request uses a position: Position
parameter, which according to the LSP specification refers to:
A position is between two characters like an 'insert' cursor in an editor.
However, hover interactions typically occur on characters rather than between them. This creates ambiguity: when a position refers to a gap between characters, which symbol should the language server return hover information for?
An old issue discusses this, but the situation has not improved.
Current Implementation Inconsistencies
Most language server implementations handle this ambiguity inconsistently:
- Default behavior: Return hover information for the symbol to the right of the position
- Special case: When the position is at the end of a symbol, return hover information for the symbol to the left
This behavior is observed in TypeScript language server, gopls, and other major implementations.
Editor Implementation Mismatch
Code editors like VS Code exacerbate this issue. When a user hovers over a character, the editor typically sends the position before that character to the language server. This creates a chain reaction:
- User hovers over a character (e.g., space) after a symbol
- Editor sends position at the end of the preceding symbol
- Language server applies special case handling
- Hover information displays for the preceding symbol
Result: Hovering over whitespace unexpectedly shows information for adjacent symbols, creating unintuitive user experience.
Concrete Example
This ambiguity becomes critical when adjacent symbols have different hover information:
a+1
Scenario: Position (0,1)
(between a
and +
)
- User expectation: Hover information for
+
operator (if available) - Actual result: Hover information for variable
a
This inconsistency makes hover behavior unpredictable and potentially misleading for developers.
Proposed Solutions
To resolve this ambiguity, I propose two complementary approaches:
1. Clarify Position Semantics in Specification
The LSP specification should explicitly define the expected behavior for textDocument/hover
positions:
- Primary rule: Standardize which symbol (left or right of position) takes precedence
- Edge cases: Define consistent handling of whitespace, punctuation, and symbol boundaries
- Implementation guidelines: Ensure uniform behavior across all language server implementations
2. Support Range Parameter
Introduce an optional range: Range
parameter in the textDocument/hover
request:
interface HoverParams {
textDocument: TextDocumentIdentifier;
position: Position;
range?: Range; // NEW: Specify exact character(s) being hovered
}
Advantages:
- Eliminates ambiguity: Precisely identifies which character(s) the user is hovering over
- Maintains compatibility: Existing implementations continue working with
position
parameter - Enhances flexibility: Enables editors to send exact hover targets
- Enables future features: Supports multi-character hover scenarios (e.g., hovering selected text)
This solution eliminates guesswork for language servers and ensures predictable, intuitive hover behavior for developers. And it may be related to #2027.