Expand description
v0.213 (ADR 0239): textDocument/codeAction extract-variable —
CodeActionKind::REFACTOR_EXTRACT. The smallest expression node whose
span fully contains the requested selection is bound to a fresh let
inserted immediately above its enclosing statement (or block tail), and
the selection’s span is replaced with the new name.
text is whatever snapshot the caller passes in — for code_action that’s
the last committed analysis round’s snapshot (ADR 0235’s
stale-while-revalidate posture), not necessarily the very latest keystroke.
Like crate::structure, this reparses that snapshot fresh each call — no
cached AST is retained in Analysis, and extraction is selection-driven
the same way folding/selection ranges are.
Track #800 settles as: plan_function reuses the exact same
smallest-containing-expression selection algorithm, but lifts the
expression into a new top-level fn (threading its free identifiers as
parameters) rather than a local let. It is capability-free-only — fn
has no given clause to propagate a capability-using body into, unlike
Handler/Provider (that language-change question is deliberately not
taken on here) — so it declines whenever the selection’s site carries any
recorded Requirement, covered or not.
#813 extends plan_function to a contiguous run of one or more full
statements (optionally including the block’s tail), not just one
expression — offered when the selection’s span aligns exactly with
statement boundaries (whitespace-trimmed at either end, so a real
“select these lines” gesture matches); a selection that doesn’t align
falls back to the single-expression algorithm above unchanged. A run that
stops before the tail synthesises a fn … -> () — or -> Effect[()]
when the run itself performs an effect, so ~>/do/<- stay legal in
the lifted body — with no explicit tail, the same implicit-unit-tail
shape the parser already synthesises for any statements-only block
(v0.146, ADR 0170); the call site becomes let _ = …(…) (or do …(…)
in the effectful case) rather than a bare expression, since Bynk has no
expression-statement form. It declines whenever a := (Cell store
write) statement falls inside the run — a lifted top-level fn has no
store fields to write, so this always fails to typecheck, not merely a
conservative guess — or whenever a binding the run introduces is still
referenced later in the same block: lifting it away would strand that
reference.
Structs§
- Function
Plan - #2100 slice 2: a planned extract-function — the new
fn’s name and the two edits (insert thefn, replace the selection with its call). - Function
Refusal - #2100 slice 2: why extract-function is not offered for a selection.
reasonisSomewhen the selection is a real candidate the user should be told about (a client that supports it shows a disabled action with the reason);Nonewhen there is simply nothing to extract there. - Function
Target - #2100 slice 2: what a listed extract-function action’s
datanames.
Functions§
- extract_
variable - Extract-variable actions for the requested range. Only offered for a
genuine selection (
requested.start != requested.end) — a bare cursor offers nothing, the refactor-vs-quickfix posture other editors take. - function_
listed - #2100 slice 2: the listed extract-function action for a selection — no
edit yet (
codeAction/resolvecomputes and re-checks it), or, when the selection is refused for a reason worth telling and the client supports it, a disabled action carrying that reason.Noneotherwise. - plan_
function - #2100 slice 2: the extract-function plan for
requested, or why there is none. Extracted functions stay capability-free (afnhas nogivenclause), and a selection containing?is refused: lifted into a newfn, the?would return from thatfninstead of the one it was written in.