Skip to content

Clarify the meaning of position in textDocument/hover request #2184

@nighca

Description

@nighca

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:

  1. Default behavior: Return hover information for the symbol to the right of the position
  2. 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:

  1. User hovers over a character (e.g., space) after a symbol
  2. Editor sends position at the end of the preceding symbol
  3. Language server applies special case handling
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions