[codex] Fix reactive go-to-definition lookup#9747
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
recheck |
|
@kirangadhave this might be right, can you confirm? |
There was a problem hiding this comment.
Pull request overview
This PR fixes go-to-definition behavior in the frontend CodeMirror integration so that reactive variable references in one cell can correctly jump to the variable’s defining cell, instead of incorrectly “resolving” to a same-cell name match.
Changes:
- Adds a
fallbackToFirstMatchtoggle togoToVariableDefinitionto prevent same-cell lookups from incorrectly short-circuiting reactive resolution. - Updates
goToDefinitionto disable first-match fallback when a usage position is available, allowing cross-cell reactive lookup to proceed. - Adds a test covering go-to-definition from a reactive variable usage in one cell to its defining cell.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| frontend/src/core/codemirror/go-to-definition/utils.ts | Adjusts local vs reactive resolution flow to avoid false-positive local matches. |
| frontend/src/core/codemirror/go-to-definition/commands.ts | Extends variable-definition navigation API with an opt-out for first-match fallback. |
| frontend/src/core/codemirror/go-to-definition/tests/utils.test.ts | Adds regression coverage for cross-cell reactive go-to-definition. |
Comments suppressed due to low confidence (1)
frontend/src/core/codemirror/go-to-definition/utils.ts:90
- When
goToDefinitionis invoked on a private variable and no same-cell definition is found, the current logic proceeds togetEditorForVariable()which returns the current editor for private vars, then callsgoToVariableDefinition(editorWithVariable, variableName)without ausagePosition. BecausegoToVariableDefinitioncan fall back to the firstVariableNamematch, this can end up "navigating" to the usage token itself even though no definition exists. Since private variables are intended to be same-cell only, it’s better to return false once the scoped lookup fails.
if (usagePosition !== undefined) {
const foundLocally = goToVariableDefinition(
view,
variableName,
usagePosition,
false,
);
if (foundLocally) {
return true;
}
}
| export function goToVariableDefinition( | ||
| view: EditorView, | ||
| variableName: string, | ||
| usagePosition?: number, | ||
| fallbackToFirstMatch = true, |
|
@kirangadhave I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 3 files
Architecture diagram
sequenceDiagram
participant User as "User (Cursor)"
participant View as "EditorView (CodeMirror)"
participant Store as "Jotai Store"
participant Defs as "goToDefinition()"
participant VarDef as "goToVariableDefinition()"
participant Scoped as "findScopedDefinitionPosition()"
participant First as "findFirstMatchingVariable()"
participant Cells as "cellHandles (Notebook)"
Note over User,Cells: Reactive Variable Go-To-Definition Flow
User->>View: Cursor at variable "a" in usage cell
View->>Defs: goToDefinition(usageView, variableName, usagePosition)
alt Same-cell variable (existing)
Note over Defs: fallbackToFirstMatch = false
Defs->>VarDef: goToVariableDefinition(view, variableName, usagePosition, false)
VarDef->>Scoped: findScopedDefinitionPosition(state, variableName, usagePosition)
alt Scoped definition found
Scoped-->>VarDef: Position {from, to} (same cell)
VarDef->>View: Set cursor to definition
VarDef-->>Defs: true (foundLocally)
Defs-->>User: Jumped to same-cell definition
else No scoped definition
Scoped-->>VarDef: null
VarDef->>First: fallbackToFirstMatch = false (skip call)
Note over VarDef: NEW: fallbackToFirstMatch flag prevents fallback
VarDef-->>Defs: false (not found locally)
Defs->>Cells: Lookup reactive variable in notebook.variablesAtom
Cells-->>Defs: Variable data (declaredBy / usedBy)
Defs->>Cells: Navigate to defining cell for "a"
Cells-->>User: Jumped to defining cell
end
else Same-cell variable (old behavior before PR)
Note over Defs: Old: always fallbackToFirstMatch = true
Defs->>VarDef: goToVariableDefinition(view, variableName, usagePosition, true)
VarDef->>Scoped: findScopedDefinitionPosition(state, variableName, usagePosition)
alt Scoped definition found
Scoped-->>VarDef: Position (same cell)
VarDef-->>Defs: true
else No scoped definition
Scoped-->>VarDef: null
VarDef->>First: findFirstMatchingVariable(state, variableName)
Note over First: NEW: This fallback is now skipped for cross-cell lookups
First-->>VarDef: First same-cell match (incorrectly treats reactive var as local)
VarDef-->>Defs: true (incorrect local match)
Defs-->>User: Jumps to wrong first variable in same cell
end
end
Note over User,Cells: Key architectural boundary: local scope vs notebook reactive variables
Note over Defs,VarDef: CHANGED: fallbackToFirstMatch parameter controls boundary
| view: EditorView, | ||
| variableName: string, | ||
| usagePosition?: number, | ||
| fallbackToFirstMatch = true, |
There was a problem hiding this comment.
jsdoc doesn't reflect the new param, default value and what it does
| : null) ?? | ||
| (fallbackToFirstMatch | ||
| ? findFirstMatchingVariable(state, variableName) | ||
| : null); |
There was a problem hiding this comment.
ternaries with null coalescing operator is difficult to parse visually. let's simplify:
let from: number | null = null;
if (usagePosition !== undefined) {
from = findScopedDefinitionPosition(state, variableName, usagePosition);
}
if (from === null && fallbackToFirstMatch) {
from = findFirstMatchingVariable(state, variableName);
}|
Addressed the remaining JSDoc feedback in |
This pull request was authored by a coding agent.
Summary
Root cause
goToDefinitionchecked same-cell definitions first, butgoToVariableDefinitionalways fell back to the first same-cell name match. For a reactive variable used in another cell, that fallback treated the usage token as a local match and stopped before the notebook variable lookup could jump to the defining cell.Validation
pnpm --filter @marimo-team/frontend test src/core/codemirror/go-to-definition/__tests__/utils.test.ts --run