Selection ranges

textDocument/selectionRange expands from an ident or smallest AST node to the enclosing statement and block.

This page

Abstract

textDocument/selectionRange grows the editor selection from the identifier (or smallest AST node) under the cursor to the enclosing statement, then enclosing if / for / while / switch / once blocks and FunctionDef / TypeDef / EnumDef. Empty or unparsed documents, or a position with no node, return [].

Conceptual model

Diagram

Rendering…

Control blocks are expressions (If, ForTo, ForIn, While, Switch, Once) and often sit under Expr. Duplicate spans (the Expr wrapper and the inner block) are collapsed. Nested blocks are linked inner-to-outer so Expand Selection walks ident → statement → inner block → outer block.

Interface surface

  • Method: textDocument/selectionRange
  • Capability: selection_range_provider=True
  • Handler: features/selection_range.py → handle_selection_range (receives version-matched tree=doc.valid_ast)

Each result is a SelectionRange whose range contains the requested position and whose optional parent is a strictly larger containing range (LSP exclusive-end ranges from AST lineno / end_lineno / col_offset / end_col_offset).

LayerSelected
InnermostIdentifier segment under the cursor, else the smallest AST node
StatementEnclosing stmt (Assign, Expr, FunctionDef, …)
BlockIf / ForTo / ForIn / While / Switch / Once / FunctionDef / TypeDef / EnumDef

Returns [] for empty source, parse failure, tree=None, or no node at the position.

Internals

PathRole
src/pynescript/langserver/features/selection_range.pyIdent + AST walk → nested SelectionRange
src/pynescript/langserver/config.pyselection_range_provider=True
src/pynescript/langserver/server.pyTEXT_DOCUMENT_SELECTION_RANGE handler

Tests: tests/test_lsp_features.py.

See also