@marimo-team/islands 0.23.14-dev38 → 0.23.14-dev39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36198,7 +36198,7 @@ ${d}`,
36198
36198
  return Logger.warn("Failed to get version from mount config"), null;
36199
36199
  }
36200
36200
  }
36201
- marimoVersionAtom = atom(getVersionFromMountConfig() || "0.23.14-dev38");
36201
+ marimoVersionAtom = atom(getVersionFromMountConfig() || "0.23.14-dev39");
36202
36202
  showCodeInRunModeAtom = atom(true);
36203
36203
  atom(null);
36204
36204
  var import_compiler_runtime = require_compiler_runtime();
package/dist/main.js CHANGED
@@ -26,7 +26,7 @@ import { $ as reducer, $t as requestClientAtom, A as ChevronDownIcon, At as Path
26
26
  import { __tla as __tla_1 } from "./chunk-5FQGJX7Z-BbqSm5gU.js";
27
27
  import { o as useSize, s as Root$1, u as createLucideIcon } from "./dist--2Bqjvs0.js";
28
28
  import { A as SquareFunction, C as DEFAULT_COLOR_SCHEME, D as SCALE_TYPE_DESCRIPTIONS, E as EMPTY_VALUE$1, O as TIME_UNIT_DESCRIPTIONS, S as DEFAULT_AGGREGATION, T as DEFAULT_TIME_UNIT, _ as AGGREGATION_TYPE_DESCRIPTIONS, a as AGGREGATION_FNS$1, b as COLOR_SCHEMES, c as COLOR_BY_FIELDS, d as NONE_VALUE, f as SELECTABLE_DATA_TYPES, g as TIME_UNITS, h as STRING_AGGREGATION_FNS, i as convertDataTypeToSelectable, j as ChartColumn, k as escapeFieldName, l as COMBINED_TIME_UNITS, m as SORT_TYPES, n as createSpecWithoutData, o as BIN_AGGREGATION, p as SINGLE_TIME_UNITS, r as isFieldSet, s as CHART_TYPES, t as augmentSpecWithData, u as ChartType, v as AGGREGATION_TYPE_ICON, w as DEFAULT_MAX_BINS_FACET, x as COUNT_FIELD, y as CHART_TYPE_ICON } from "./spec-CnTgI25l.js";
29
- import { $ as PANEL_TYPES, $t as HtmlOutput, A as prettifyRowCount, At as INDEX_COLUMN_NAME, B as CompactChipRow, Bt as dateToLocalISODateTime, C as downloadSizeLimitAtom, Ct as ColumnChartSpecModel, D as ErrorState, Dt as getPageIndexForRow, E as EmptyState, Et as usePrevious$1, F as ContextMenuItem, Ft as hasFunctionProperty, G as Command, Gt as TabsTrigger, H as DateRangePicker, Ht as Tabs, I as ContextMenuSeparator, It as isRecord, J as CommandItem, Jt as ChartLoadingState, K as CommandEmpty, Kt as ChartErrorState, L as ContextMenuTrigger, Lt as isNullishFilter, M as getUserColumnVisibilityCounts, Mt as TOO_MANY_ROWS, N as ContextMenu, Nt as toFieldTypes, O as LoadingState, Ot as loadTableAndRawData, P as ContextMenuContent, Pt as getMimeValues, Q as ContextAwarePanelItem, Qt as Kbd, R as useInternalStateWithSync, Rt as Maps, S as Filenames, St as ColumnChartContext, T as ColumnPreviewContainer, Tt as useIntersectionObserver, U as Combobox, Ut as TabsContent, V as DatePicker, Vt as dateToLocalISOTime, W as ComboboxItem, Wt as TabsList, X as CommandSeparator, Xt as useOverflowDetection, Y as CommandList, Yt as LazyVegaEmbed, Z as smartMatch, Zt as RenderTextWithLinks, _ as ADD_PRINTING_CLASS, _t as TableRow, an as Funnel, at as slotsController, b as downloadHTMLAsImage, bt as inferFieldTypes, c as Slide, cn as Ellipsis, d as RadioGroupItem, dn as ChevronsUpDown, dt as Provider$1, en as EmotionCacheProvider, et as contextAwarePanelOpen, f as JsonOutput, fn as ChevronsRight, ft as Table, g as InstallPackageButton, gn as ArrowDownWideNarrow, gt as TableHeader, h as DataTable, hn as ChevronLeft, ht as TableHead, in as GripHorizontal, it as SlotNames, j as getColumnCountForDisplay, jt as SELECT_COLUMN_ID, k as prettifyRowColumnCount, kt as loadTableData, l as Switch, ln as Download, m as OutputRenderer, mn as ChevronsDownUp, mt as TableCell, n as marimoVersionAtom, nn as $fae977aafc393c5c$export$6b862160d295c8e, nt as contextAwarePanelType, o as SLIDE_TYPE_OPTIONS_BY_VALUE, on as EyeOff, ot as Toggle, p as OutputArea, pn as ChevronsLeft, pt as TableBody, q as CommandInput, qt as ChartInfoState, r as showCodeInRunModeAtom, rn as TextWrap, rt as isCellAwareAtom, t as useNotebookCodeAvailable, tn as $fae977aafc393c5c$export$588937bcd60ade55, tt as contextAwarePanelOwner, u as RadioGroup, un as Code, ut as Fill, v as downloadBlob, vt as NAMELESS_COLUMN_PREFIX, w as ColumnName, wt as DelayMount, x as Progress, xt as renderCellValue, y as downloadByURL, yt as generateColumns, z as useSelectList, zt as dateToLocalISODate, __tla as __tla_2 } from "./code-visibility-mXuKNkTw.js";
29
+ import { $ as PANEL_TYPES, $t as HtmlOutput, A as prettifyRowCount, At as INDEX_COLUMN_NAME, B as CompactChipRow, Bt as dateToLocalISODateTime, C as downloadSizeLimitAtom, Ct as ColumnChartSpecModel, D as ErrorState, Dt as getPageIndexForRow, E as EmptyState, Et as usePrevious$1, F as ContextMenuItem, Ft as hasFunctionProperty, G as Command, Gt as TabsTrigger, H as DateRangePicker, Ht as Tabs, I as ContextMenuSeparator, It as isRecord, J as CommandItem, Jt as ChartLoadingState, K as CommandEmpty, Kt as ChartErrorState, L as ContextMenuTrigger, Lt as isNullishFilter, M as getUserColumnVisibilityCounts, Mt as TOO_MANY_ROWS, N as ContextMenu, Nt as toFieldTypes, O as LoadingState, Ot as loadTableAndRawData, P as ContextMenuContent, Pt as getMimeValues, Q as ContextAwarePanelItem, Qt as Kbd, R as useInternalStateWithSync, Rt as Maps, S as Filenames, St as ColumnChartContext, T as ColumnPreviewContainer, Tt as useIntersectionObserver, U as Combobox, Ut as TabsContent, V as DatePicker, Vt as dateToLocalISOTime, W as ComboboxItem, Wt as TabsList, X as CommandSeparator, Xt as useOverflowDetection, Y as CommandList, Yt as LazyVegaEmbed, Z as smartMatch, Zt as RenderTextWithLinks, _ as ADD_PRINTING_CLASS, _t as TableRow, an as Funnel, at as slotsController, b as downloadHTMLAsImage, bt as inferFieldTypes, c as Slide, cn as Ellipsis, d as RadioGroupItem, dn as ChevronsUpDown, dt as Provider$1, en as EmotionCacheProvider, et as contextAwarePanelOpen, f as JsonOutput, fn as ChevronsRight, ft as Table, g as InstallPackageButton, gn as ArrowDownWideNarrow, gt as TableHeader, h as DataTable, hn as ChevronLeft, ht as TableHead, in as GripHorizontal, it as SlotNames, j as getColumnCountForDisplay, jt as SELECT_COLUMN_ID, k as prettifyRowColumnCount, kt as loadTableData, l as Switch, ln as Download, m as OutputRenderer, mn as ChevronsDownUp, mt as TableCell, n as marimoVersionAtom, nn as $fae977aafc393c5c$export$6b862160d295c8e, nt as contextAwarePanelType, o as SLIDE_TYPE_OPTIONS_BY_VALUE, on as EyeOff, ot as Toggle, p as OutputArea, pn as ChevronsLeft, pt as TableBody, q as CommandInput, qt as ChartInfoState, r as showCodeInRunModeAtom, rn as TextWrap, rt as isCellAwareAtom, t as useNotebookCodeAvailable, tn as $fae977aafc393c5c$export$588937bcd60ade55, tt as contextAwarePanelOwner, u as RadioGroup, un as Code, ut as Fill, v as downloadBlob, vt as NAMELESS_COLUMN_PREFIX, w as ColumnName, wt as DelayMount, x as Progress, xt as renderCellValue, y as downloadByURL, yt as generateColumns, z as useSelectList, zt as dateToLocalISODate, __tla as __tla_2 } from "./code-visibility-CqDnWUEQ.js";
30
30
  import { c as Calendar, i as createReducerAndAtoms, n as useOnUnmount, o as ToggleLeft, t as useOnMount } from "./useLifecycle-CxffarYV.js";
31
31
  import { t as Check } from "./check-C9OoNtR4.js";
32
32
  import { A as Icon, C as logNever, D as $18f2051aff69b9bf$export$a54013f0d02a8f82, E as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7, F as createCollection, I as X, M as clamp$2, N as usePrevious$2, P as useDirection, R as ChevronDown, S as assertNever, a as SelectGroup, c as SelectSeparator, d as NativeSelect, i as SelectContent, j as Trigger$1, l as SelectTrigger, n as capitalize, o as SelectItem, r as Select, s as SelectLabel, t as Strings, u as SelectValue, w as $a916eb452884faea$export$b7a616150fdb9f44 } from "./strings-Dq_j3Rxw.js";
@@ -37725,7 +37725,7 @@ ${c}
37725
37725
  function _temp2$2(e) {
37726
37726
  e.target === e.currentTarget && e.key === "Enter" && (e.preventDefault(), e.stopPropagation(), e.currentTarget.click());
37727
37727
  }
37728
- var LazySlidesComponent = import_react.lazy(() => import("./reveal-component-DW8FGG4C.js"));
37728
+ var LazySlidesComponent = import_react.lazy(() => import("./reveal-component-BtwLhHQU.js"));
37729
37729
  const SlidesLayoutRenderer = ({ layout: e, setLayout: r, cells: c, mode: l }) => {
37730
37730
  var _a3;
37731
37731
  let u = useAtomValue(kioskModeAtom), d = l === "read" || u, f = useAtomValue(numColumnsAtom) > 1, [p, m] = (0, import_react.useState)(null), { slideCells: h, skippedIds: g, noOutputIds: _, slideTypes: v, startCellIndex: y } = (0, import_react.useMemo)(() => computeSlideCellsInfo(c, e), [
@@ -9,7 +9,7 @@ import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
9
9
  import { lt as kioskModeAtom, pt as outputIsStale } from "./html-to-image-DLSOS-bE.js";
10
10
  import "./chunk-5FQGJX7Z-BbqSm5gU.js";
11
11
  import { u as createLucideIcon } from "./dist--2Bqjvs0.js";
12
- import { a as DEFAULT_SLIDE_TYPE, c as Slide, ct as PanelGroup, i as DEFAULT_DECK_TRANSITION, lt as PanelResizeHandle, on as EyeOff, s as SlideSidebar, sn as Expand, st as Panel, t as useNotebookCodeAvailable, un as Code } from "./code-visibility-mXuKNkTw.js";
12
+ import { a as DEFAULT_SLIDE_TYPE, c as Slide, ct as PanelGroup, i as DEFAULT_DECK_TRANSITION, lt as PanelResizeHandle, on as EyeOff, s as SlideSidebar, sn as Expand, st as Panel, t as useNotebookCodeAvailable, un as Code } from "./code-visibility-CqDnWUEQ.js";
13
13
  import { X as useDebouncedCallback } from "./input-BSdZp5Ng.js";
14
14
  import "./toDate-D1Z7ZXWh.js";
15
15
  import "./react-dom-BTJzcVJ9.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.23.14-dev38",
3
+ "version": "0.23.14-dev39",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -23,7 +23,7 @@ import { toast } from "@/components/ui/use-toast";
23
23
  import { useCellData, useCellRuntime } from "@/core/cells/cells";
24
24
  import { CellOutputId } from "@/core/cells/ids";
25
25
  import { isOutputEmpty } from "@/core/cells/outputs";
26
- import { goToDefinitionAtCursorPosition } from "@/core/codemirror/go-to-definition/utils";
26
+ import { goToDefinitionWithLspFallback } from "@/core/codemirror/go-to-definition/utils";
27
27
  import { sendToPanelManager } from "@/core/vscode/vscode-bindings";
28
28
  import { copyImageToClipboard, copyToClipboard } from "@/utils/copy";
29
29
  import { getImageExtension } from "@/utils/filenames";
@@ -170,7 +170,7 @@ export const CellActionsContextMenu = ({
170
170
  // Only suppress focus restoration when we actually navigated;
171
171
  // otherwise let Radix return focus to the trigger cell.
172
172
  suppressCloseAutoFocus.current =
173
- goToDefinitionAtCursorPosition(editorView);
173
+ goToDefinitionWithLspFallback(editorView);
174
174
  }
175
175
  },
176
176
  },
@@ -2,13 +2,17 @@
2
2
 
3
3
  import { python } from "@codemirror/lang-python";
4
4
  import { EditorState } from "@codemirror/state";
5
- import { EditorView } from "@codemirror/view";
6
- import { afterEach, describe, expect, test } from "vitest";
5
+ import { EditorView, keymap } from "@codemirror/view";
6
+ import { afterEach, describe, expect, test, vi } from "vitest";
7
7
  import { cellId, variableName } from "@/__tests__/branded";
8
8
  import { initialNotebookState, notebookAtom } from "@/core/cells/cells";
9
9
  import { store } from "@/core/state/jotai";
10
10
  import { variablesAtom } from "@/core/variables/state";
11
- import { goToDefinitionAtCursorPosition } from "../utils";
11
+ import {
12
+ goToDefinitionAtCursorPosition,
13
+ goToDefinitionWithLspFallback,
14
+ requestLspGoToDefinition,
15
+ } from "../utils";
12
16
 
13
17
  async function tick(): Promise<void> {
14
18
  await new Promise((resolve) => requestAnimationFrame(resolve));
@@ -181,3 +185,71 @@ print(mymodule)`;
181
185
  );
182
186
  });
183
187
  });
188
+
189
+ describe("goToDefinitionWithLspFallback", () => {
190
+ test("falls through to LSP when marimo cannot resolve the symbol", () => {
191
+ const lspGoToDefinition = vi.fn(() => true);
192
+ const view = new EditorView({
193
+ state: EditorState.create({
194
+ doc: "parser.add_argument('--foo')",
195
+ selection: { anchor: "parser.add_argument".indexOf("add_argument") },
196
+ extensions: [
197
+ python(),
198
+ keymap.of([{ key: "F12", run: lspGoToDefinition }]),
199
+ ],
200
+ }),
201
+ parent: document.body,
202
+ });
203
+ views.push(view);
204
+
205
+ const result = goToDefinitionWithLspFallback(view);
206
+
207
+ expect(result).toBe(true);
208
+ expect(lspGoToDefinition).toHaveBeenCalledOnce();
209
+ });
210
+
211
+ test("does not invoke LSP when marimo resolves the symbol", async () => {
212
+ const lspGoToDefinition = vi.fn(() => true);
213
+ const code = "a = 10\nprint(a)";
214
+ const view = new EditorView({
215
+ state: EditorState.create({
216
+ doc: code,
217
+ selection: { anchor: code.indexOf("a", 3) },
218
+ extensions: [
219
+ python(),
220
+ keymap.of([{ key: "F12", run: lspGoToDefinition }]),
221
+ ],
222
+ }),
223
+ parent: document.body,
224
+ });
225
+ views.push(view);
226
+
227
+ const result = goToDefinitionWithLspFallback(view);
228
+
229
+ expect(result).toBe(true);
230
+ expect(lspGoToDefinition).not.toHaveBeenCalled();
231
+ await tick();
232
+ expect(view.state.selection.main.head).toBe(0);
233
+ });
234
+
235
+ test("falls through with a modified shortcut like Ctrl-F12", () => {
236
+ const lspGoToDefinition = vi.fn(() => true);
237
+ const view = new EditorView({
238
+ state: EditorState.create({
239
+ doc: "parser.add_argument('--foo')",
240
+ selection: { anchor: "parser.add_argument".indexOf("add_argument") },
241
+ extensions: [
242
+ python(),
243
+ keymap.of([{ key: "Ctrl-F12", run: lspGoToDefinition }]),
244
+ ],
245
+ }),
246
+ parent: document.body,
247
+ });
248
+ views.push(view);
249
+
250
+ const result = requestLspGoToDefinition(view, "Ctrl-F12");
251
+
252
+ expect(result).toBe(true);
253
+ expect(lspGoToDefinition).toHaveBeenCalledOnce();
254
+ });
255
+ });
@@ -1,7 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { EditorView } from "@codemirror/view";
3
3
  import { createUnderlinePlugin, underlineField } from "./underline";
4
- import { goToDefinition } from "./utils";
4
+ import { goToDefinitionWithLspFallback } from "./utils";
5
5
 
6
6
  /**
7
7
  * Create a go-to-definition extension.
@@ -9,8 +9,8 @@ import { goToDefinition } from "./utils";
9
9
  export function goToDefinitionBundle() {
10
10
  return [
11
11
  underlineField,
12
- createUnderlinePlugin((view, variableName) => {
13
- goToDefinition(view, variableName);
12
+ createUnderlinePlugin((view) => {
13
+ goToDefinitionWithLspFallback(view);
14
14
  }),
15
15
  EditorView.baseTheme({
16
16
  ".underline": {
@@ -55,12 +55,9 @@ class MetaUnderlineVariablePlugin {
55
55
  private view: EditorView;
56
56
  private commandClickMode: boolean;
57
57
  private hoveredRange: { from: number; to: number; position: number } | null;
58
- private onClick: (view: EditorView, variableName: string) => void;
58
+ private onClick: (view: EditorView) => void;
59
59
 
60
- constructor(
61
- view: EditorView,
62
- onClick: (view: EditorView, variableName: string) => void,
63
- ) {
60
+ constructor(view: EditorView, onClick: (view: EditorView) => void) {
64
61
  this.view = view;
65
62
  this.commandClickMode = false;
66
63
  this.hoveredRange = null;
@@ -191,20 +188,16 @@ class MetaUnderlineVariablePlugin {
191
188
  // If we have a hovered range, go to it
192
189
  private click = (event: MouseEvent) => {
193
190
  if (this.hoveredRange) {
194
- const variableName = this.view.state.doc.sliceString(
195
- this.hoveredRange.from,
196
- this.hoveredRange.to,
197
- );
198
191
  event.preventDefault();
199
192
  event.stopPropagation();
200
- this.onClick(this.view, variableName);
201
- // Move the cursor to the clicked position
193
+ // Move the cursor before resolving so LSP uses the clicked position.
202
194
  this.view.dispatch({
203
195
  selection: {
204
196
  head: this.hoveredRange.position,
205
197
  anchor: this.hoveredRange.position,
206
198
  },
207
199
  });
200
+ this.onClick(this.view);
208
201
  }
209
202
  };
210
203
 
@@ -217,7 +210,5 @@ class MetaUnderlineVariablePlugin {
217
210
  }
218
211
  }
219
212
 
220
- export const createUnderlinePlugin = (
221
- onClick: (view: EditorView, variableName: string) => void,
222
- ) =>
213
+ export const createUnderlinePlugin = (onClick: (view: EditorView) => void) =>
223
214
  ViewPlugin.define((view) => new MetaUnderlineVariablePlugin(view, onClick));
@@ -2,8 +2,14 @@
2
2
 
3
3
  import { closeCompletion } from "@codemirror/autocomplete";
4
4
  import type { EditorState } from "@codemirror/state";
5
- import { closeHoverTooltips, type EditorView } from "@codemirror/view";
5
+ import {
6
+ closeHoverTooltips,
7
+ type EditorView,
8
+ type KeyBinding,
9
+ keymap,
10
+ } from "@codemirror/view";
6
11
  import type { CellId } from "@/core/cells/ids";
12
+ import { hotkeysAtom, platformAtom } from "../../config/config";
7
13
  import { notebookAtom } from "../../cells/cells";
8
14
  import { store } from "../../state/jotai";
9
15
  import { variablesAtom } from "../../variables/state";
@@ -11,6 +17,20 @@ import type { VariableName, Variables } from "../../variables/types";
11
17
  import { getPositionAtWordBounds } from "../completion/hints";
12
18
  import { goToLine, goToVariableDefinition } from "./commands";
13
19
 
20
+ function keymapBindingMatchesHotkey(
21
+ binding: KeyBinding,
22
+ hotkey: string,
23
+ ): boolean {
24
+ const platform = store.get(platformAtom);
25
+ const bindingKey =
26
+ platform === "mac"
27
+ ? (binding.mac ?? binding.key)
28
+ : platform === "windows"
29
+ ? (binding.win ?? binding.key)
30
+ : (binding.linux ?? binding.key);
31
+ return bindingKey === hotkey;
32
+ }
33
+
14
34
  /**
15
35
  * Get the word under the cursor.
16
36
  */
@@ -68,6 +88,34 @@ export function goToDefinitionAtCursorPosition(view: EditorView): boolean {
68
88
  return goToDefinition(view, word, position);
69
89
  }
70
90
 
91
+ /**
92
+ * Invoke the editor's go-to-definition keymap handlers for the configured
93
+ * hotkey. Matches CodeMirror key strings directly (including customized
94
+ * shortcuts like `Ctrl-F12`) instead of synthesizing keyboard events.
95
+ */
96
+ export function requestLspGoToDefinition(
97
+ view: EditorView,
98
+ hotkey = store.get(hotkeysAtom).getHotkey("cell.goToDefinition").key,
99
+ ): boolean {
100
+ for (const binding of view.state.facet(keymap).flat()) {
101
+ if (keymapBindingMatchesHotkey(binding, hotkey) && binding.run?.(view)) {
102
+ return true;
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+
108
+ /**
109
+ * Go to the definition under the cursor, falling back to the language server
110
+ * when marimo cannot resolve the symbol (e.g. external library code).
111
+ */
112
+ export function goToDefinitionWithLspFallback(view: EditorView): boolean {
113
+ if (goToDefinitionAtCursorPosition(view)) {
114
+ return true;
115
+ }
116
+ return requestLspGoToDefinition(view);
117
+ }
118
+
71
119
  /**
72
120
  * Go to the definition of the variable under the cursor.
73
121
  * @param view The editor view at which the command was invoked.