Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2aa7825
fix: error: Argument 1 to add_common_config has incompatible type Lay…
Shamik-07 Apr 24, 2026
4ad8b3d
feat: adding command matches to the outer and inner function scope de…
Shamik-07 Apr 24, 2026
0a1c771
feat: get word under cursor returns both word and position
Shamik-07 Apr 24, 2026
8a170b1
test: checks nearest local parameters and checks across cells.
Shamik-07 Apr 24, 2026
bee4c91
test: local definitions are preferred over reactive gloabls and priva…
Shamik-07 Apr 24, 2026
0fa0c14
Merge branch 'main' into fix/def_declaration
Shamik-07 Apr 27, 2026
af8a66e
Merge branch 'main' into fix/def_declaration
Shamik-07 Apr 28, 2026
6612d01
Merge branch 'main' into fix/def_declaration
Shamik-07 Apr 29, 2026
2767c77
Merge branch 'main' into fix/def_declaration
Shamik-07 Apr 30, 2026
264c7e8
Merge branch 'main' into fix/def_declaration
Shamik-07 May 1, 2026
d3875e6
Merge branch 'main' into fix/def_declaration
Shamik-07 May 4, 2026
3475ee0
Merge branch 'main' into fix/def_declaration
Shamik-07 May 5, 2026
5f9c696
Merge branch 'main' into fix/def_declaration
Shamik-07 May 6, 2026
b8b9669
Merge branch 'main' into fix/def_declaration
Shamik-07 May 7, 2026
4a8eb4b
Merge branch 'main' into fix/def_declaration
Shamik-07 May 8, 2026
02fc173
Add failing tests for go-to-definition scope bugs
manzt May 11, 2026
bf12fd1
Merge pull request #1 from marimo-team/fix/def_declaration-tests
Shamik-07 May 11, 2026
7c634fa
fix: renaming SetComprehension to SetComprehensionExpression as Lezer…
Shamik-07 May 11, 2026
345e6e4
fix: skipping class scopes after a function boundary in getscopechain…
Shamik-07 May 11, 2026
2853f19
test: fixing the code comments in commands test.
Shamik-07 May 11, 2026
b2551f5
Merge branch 'main' into fix/def_declaration
Shamik-07 May 11, 2026
9638f27
docs: renaming pnpm build watch column name as production esque.
Shamik-07 May 11, 2026
1a458cd
Merge branch 'main' into fix/def_declaration
Shamik-07 May 12, 2026
7aa5372
Merge branch 'main' into fix/def_declaration
Shamik-07 May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,52 @@ print(x)`);
`);
});

test("selects the nearest in-scope local definition", async () => {
const code = `\
a = 10

def my_func():
a = 20
print(a)`;
view = createEditor(code);
const result = goToVariableDefinition(view, "a", code.lastIndexOf("a"));

expect(result).toBe(true);
await tick();
expect(renderEditorView(view)).toMatchInlineSnapshot(`
"
a = 10

def my_func():
a = 20
^
print(a)
"
`);
});

test("selects the nearest in-scope parameter definition", async () => {
const code = `\
a = 10

def my_func(a):
print(a)`;
view = createEditor(code);
const result = goToVariableDefinition(view, "a", code.lastIndexOf("a"));

expect(result).toBe(true);
await tick();
expect(renderEditorView(view)).toMatchInlineSnapshot(`
"
a = 10

def my_func(a):
^
print(a)
"
`);
});

test("selects outer-scope function declaration", async () => {
view = createEditor(`\
def x():
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/* Copyright 2026 Marimo. All rights reserved. */

import { python } from "@codemirror/lang-python";
import { EditorState } from "@codemirror/state";
import { EditorView } from "@codemirror/view";
import { afterEach, describe, expect, test } from "vitest";
import { cellId, variableName } from "@/__tests__/branded";
import { initialNotebookState, notebookAtom } from "@/core/cells/cells";
import { store } from "@/core/state/jotai";
import { variablesAtom } from "@/core/variables/state";
import { goToDefinitionAtCursorPosition } from "../utils";

async function tick(): Promise<void> {
await new Promise((resolve) => requestAnimationFrame(resolve));
}

function createEditor(content: string, selection: number) {
const state = EditorState.create({
doc: content,
selection: { anchor: selection },
extensions: [python()],
});

return new EditorView({
state,
parent: document.body,
});
}

const views: EditorView[] = [];

afterEach(() => {
for (const view of views.splice(0)) {
view.destroy();
}

store.set(notebookAtom, initialNotebookState());
store.set(variablesAtom, {});
});

describe("goToDefinitionAtCursorPosition", () => {
test("prefers the current-cell local definition over a reactive global", async () => {
const globalCell = cellId("global-cell");
const localCell = cellId("local-cell");
const globalCode = `\
a = 10
print(a)`;
const localCode = `\
def test():
a = 20
print(a)`;

const globalView = createEditor(globalCode, globalCode.length);
const localView = createEditor(localCode, localCode.lastIndexOf("a"));
views.push(globalView, localView);

const notebook = initialNotebookState();
notebook.cellHandles[globalCell] = {
current: { editorView: globalView },
} as never;
notebook.cellHandles[localCell] = {
current: { editorView: localView },
} as never;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not need to type cast here:

Suggested change
notebook.cellHandles[globalCell] = {
current: { editorView: globalView },
} as never;
notebook.cellHandles[localCell] = {
current: { editorView: localView },
} as never;
notebook.cellHandles[globalCell] = {
current: { editorView: globalView, editorViewOrNull: globalView },
} as never;
notebook.cellHandles[localCell] = {
current: { editorView: localView, editorViewOrNull: localView },
};

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


store.set(notebookAtom, notebook);
store.set(variablesAtom, {
[variableName("a")]: {
dataType: "int",
declaredBy: [globalCell],
name: variableName("a"),
usedBy: [localCell],
value: "10",
},
});

const result = goToDefinitionAtCursorPosition(localView);

expect(result).toBe(true);
await tick();
expect(localView.state.selection.main.head).toBe(
localCode.indexOf("a = 20"),
);
expect(globalView.state.selection.main.head).toBe(globalCode.length);
});

test("keeps private variables within the current cell", async () => {
const code = `\
_x = 10
output = _x + 10`;
const view = createEditor(code, code.lastIndexOf("_x"));
views.push(view);

const result = goToDefinitionAtCursorPosition(view);

expect(result).toBe(true);
await tick();
expect(view.state.selection.main.head).toBe(code.indexOf("_x = 10"));
});
});
Loading
Loading