@marimo-team/frontend 0.21.2-dev5 → 0.21.2-dev52
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.
- package/dist/assets/{CellStatus-CDSBsjjF.js → CellStatus-DX8MnBMk.js} +1 -1
- package/dist/assets/{ConnectedDataExplorerComponent-Buaffg3u.js → ConnectedDataExplorerComponent-7yXYooWG.js} +1 -1
- package/dist/assets/{DeferredRequestRegistry-O6RDJKs0.js → DeferredRequestRegistry-B8jPCuU1.js} +1 -1
- package/dist/assets/{ImperativeModal-qEtcJ95s.js → ImperativeModal-C3CD5-Aq.js} +1 -1
- package/dist/assets/JsonOutput-DqjAyzM8.js +46 -0
- package/dist/assets/{LazyAnyLanguageCodeMirror-m8w66E4s.js → LazyAnyLanguageCodeMirror-CcCHIX38.js} +2 -2
- package/dist/assets/{MarimoErrorOutput-az74f3Mp.js → MarimoErrorOutput-Dat_S09q.js} +5 -5
- package/dist/assets/RenderHTML-C7XM39M2.js +1 -0
- package/dist/assets/{add-cell-with-ai-DUn4LN4W.js → add-cell-with-ai-y2xroEGf.js} +9 -9
- package/dist/assets/{add-connection-dialog-CBz0AUVX.js → add-connection-dialog-QDBOmil3.js} +23 -23
- package/dist/assets/{agent-panel-u83dsDsM.js → agent-panel-DziFrEjJ.js} +6 -6
- package/dist/assets/ai-model-dropdown-CiJpv5wN.js +5 -0
- package/dist/assets/{alert-dialog-9WfvUF7e.js → alert-dialog-ebk_-wsU.js} +1 -1
- package/dist/assets/{any-language-editor-DwQMnAM3.js → any-language-editor-DZYnKlJB.js} +1 -1
- package/dist/assets/{app-config-button-rDu-lCIB.js → app-config-button-CpAv9Tiu.js} +1 -1
- package/dist/assets/{architectureDiagram-VXUJARFQ-DfMHHFZ3.js → architectureDiagram-VXUJARFQ-DKmk99ac.js} +1 -1
- package/dist/assets/{azure-BTXHztTw.js → azure-Dw5gKmUz.js} +1 -1
- package/dist/assets/{blockDiagram-VD42YOAC-CuEDwbg7.js → blockDiagram-VD42YOAC-TpAhP5OQ.js} +1 -1
- package/dist/assets/{c4Diagram-YG6GDRKO-CD9uz7WG.js → c4Diagram-YG6GDRKO-Dg8hCyKf.js} +1 -1
- package/dist/assets/{cache-panel-qIxnndwr.js → cache-panel-D0OsHk_D.js} +1 -1
- package/dist/assets/cell-editor-RbAVpSFb.js +22 -0
- package/dist/assets/{cell-link-Q_UEP94Z.js → cell-link-CNgO3c-T.js} +1 -1
- package/dist/assets/{cells-fq1RMGX_.js → cells-39RE4UzS.js} +77 -76
- package/dist/assets/channel-D1wPYhc9.js +1 -0
- package/dist/assets/{chat-display-D_Fuuy6r.js → chat-display-BPUVrlA6.js} +1 -1
- package/dist/assets/{chat-panel-BO-JoQSp.js → chat-panel-esz5TfF-.js} +2 -2
- package/dist/assets/{chunk-5FQGJX7Z-CM1a_K7I.js → chunk-5FQGJX7Z-sGWxL7Ey.js} +3 -3
- package/dist/assets/{chunk-ABZYJK2D-D_Wumzom.js → chunk-ABZYJK2D-DXJ7hnjx.js} +1 -1
- package/dist/assets/{chunk-ATLVNIR6-BZ0lTgIn.js → chunk-ATLVNIR6-CTEqcLEc.js} +1 -1
- package/dist/assets/{chunk-B4BG7PRW-Dw1S6osV.js → chunk-B4BG7PRW-CkAIqtPf.js} +1 -1
- package/dist/assets/{chunk-DI55MBZ5-Q63FTCPP.js → chunk-DI55MBZ5-C4F9vu8o.js} +1 -1
- package/dist/assets/{chunk-EXTU4WIE-CfkJ_R7W.js → chunk-EXTU4WIE-BT0Py-4P.js} +1 -1
- package/dist/assets/{chunk-JA3XYJ7Z-B41fGeoj.js → chunk-JA3XYJ7Z-CGd7jja_.js} +1 -1
- package/dist/assets/{chunk-JZLCHNYA-D43EJxQw.js → chunk-JZLCHNYA-CqY-RYTj.js} +1 -1
- package/dist/assets/{chunk-N4CR4FBY-DCtw0-ni.js → chunk-N4CR4FBY-aUDjVzN7.js} +2 -2
- package/dist/assets/{chunk-QN33PNHL-CLA2rsaS.js → chunk-QN33PNHL-DHnCb5-U.js} +1 -1
- package/dist/assets/{chunk-QXUST7PY-De1DpbnL.js → chunk-QXUST7PY-CRO5kYCE.js} +1 -1
- package/dist/assets/{chunk-S3R3BYOJ-qrwvlUdq.js → chunk-S3R3BYOJ-CSHQgcuP.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-C4KcThb0.js → chunk-TZMSLE5B-CE7o9asH.js} +1 -1
- package/dist/assets/classDiagram-2ON5EDUG-BDIQSKYv.js +1 -0
- package/dist/assets/classDiagram-v2-WZHVMYZB-Cdh4cVOB.js +1 -0
- package/dist/assets/{code-block-37QAKDTI-D4FF4cnN.js → code-block-37QAKDTI-DMpe1jNG.js} +1 -1
- package/dist/assets/{column-preview-WsubyItX.js → column-preview-BUKHsglA.js} +1 -1
- package/dist/assets/{command-rfxSsiHU.js → command-DmzEbs6L.js} +1 -1
- package/dist/assets/{command-palette-Bez4BqJF.js → command-palette-BX5gNpUr.js} +1 -1
- package/dist/assets/{common-BYwO983A.js → common-B4yshY-H.js} +1 -1
- package/dist/assets/{components-Ozq0825a.js → components-DCqJqyys.js} +1 -1
- package/dist/assets/{components-Bpgzv_5_.js → components-oKCjx6cN.js} +1 -1
- package/dist/assets/{config-3Aq84phF.js → config-DqxNMQDN.js} +1 -1
- package/dist/assets/{context-CIAP2NOh.js → context-CRmPPhx9.js} +1 -1
- package/dist/assets/{context-aware-panel-CfsfBlhO.js → context-aware-panel-DC0Te9Hj.js} +2 -2
- package/dist/assets/copy-KjcPgPw9.js +1 -0
- package/dist/assets/{copy-icon-BgmMM9Zg.js → copy-icon-P0kzz1Pr.js} +1 -1
- package/dist/assets/{dagre-6UL2VRFP-BhMnPhuU.js → dagre-6UL2VRFP-XqoNLMQ3.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-kbv73SQ7.js → data-grid-overlay-editor-Cus1-BFN.js} +1 -1
- package/dist/assets/{datasource-F9sJtuof.js → datasource-DKHG39NV.js} +2 -2
- package/dist/assets/{dates-CHaNfieI.js → dates-CTqMeMGY.js} +1 -1
- package/dist/assets/{dependency-graph-panel-AOBcX2tP.js → dependency-graph-panel-7GKT3dyD.js} +4 -4
- package/dist/assets/{diagram-PSM6KHXK-Cr2t4zul.js → diagram-PSM6KHXK-BuzKNNcN.js} +1 -1
- package/dist/assets/{diagram-QEK2KX5R-DLU_hSO4.js → diagram-QEK2KX5R-A5LBQS11.js} +1 -1
- package/dist/assets/{diagram-S2PKOQOG-C7EkNAO3.js → diagram-S2PKOQOG-dkJE8SA0.js} +1 -1
- package/dist/assets/{dialog-CVN1lcMF.js → dialog-1_jIyAb_.js} +1 -1
- package/dist/assets/{dist-DJBpXGro.js → dist-6P6vjf93.js} +1 -1
- package/dist/assets/dist-BWGxTsTP.js +1 -0
- package/dist/assets/{dist-CblX3KGI.js → dist-B_buFm3B.js} +1 -1
- package/dist/assets/{dist-CXLJUPFl.js → dist-BatEf-0f.js} +1 -1
- package/dist/assets/dist-C3AnARPE.js +1 -0
- package/dist/assets/{dist-BNC_tnlW.js → dist-C6ohaMKU.js} +1 -1
- package/dist/assets/{dist-BoDHthoc.js → dist-CO9Pg2Rc.js} +1 -1
- package/dist/assets/{dist-By6zhkxZ.js → dist-CSV6H5w_.js} +1 -1
- package/dist/assets/{dist-6FIAeDIu.js → dist-CYs1oP7g.js} +1 -1
- package/dist/assets/{dist-DbK_4_qo.js → dist-DD9ZJMK5.js} +1 -1
- package/dist/assets/{dist-DlTbNRBn.js → dist-DReDpc2z.js} +1 -1
- package/dist/assets/dist-DSlq5ZeQ.js +1 -0
- package/dist/assets/{dist-DrceDAhM.js → dist-DXyIIB32.js} +1 -1
- package/dist/assets/{dist-CcGcwrUD.js → dist-DkaderFA.js} +1 -1
- package/dist/assets/{dist-BiZQlfhr.js → dist-Dq3BlK4R.js} +1 -1
- package/dist/assets/{dist-ClzRAVN-.js → dist-Dxov2ltb.js} +1 -1
- package/dist/assets/{dist-BXXPfIam.js → dist-EtGG9C1A.js} +1 -1
- package/dist/assets/{dist-C3MmXcLA.js → dist-NjId5Gdz.js} +1 -1
- package/dist/assets/dist-ZM59OWYL.js +1 -0
- package/dist/assets/dist-_TwZ4tIe.js +1 -0
- package/dist/assets/dist-f9b2H4q_.js +1 -0
- package/dist/assets/{dist-mxGLXOFm.js → dist-feWVQ4dq.js} +1 -1
- package/dist/assets/{documentation-panel-D28MpqbI.js → documentation-panel-D5d_BbHV.js} +1 -1
- package/dist/assets/{download-B9_ToVd4.js → download-B1vXaivj.js} +4 -4
- package/dist/assets/{dropdown-menu-DdPu5Kfu.js → dropdown-menu-BehqiLFL.js} +1 -1
- package/dist/assets/{edit-page-otS-QvnC.js → edit-page-B5cAZdO7.js} +7 -7
- package/dist/assets/{en-US-BO8E69bZ.js → en-US-f8tajDx1.js} +1 -1
- package/dist/assets/{erDiagram-Q2GNP2WA-DqlEo_Us.js → erDiagram-Q2GNP2WA-CgH6udOW.js} +1 -1
- package/dist/assets/{error-banner-BRG6IPhC.js → error-banner-J5F3weEj.js} +1 -1
- package/dist/assets/{error-panel-RRoj_iOR.js → error-panel-DnhKJ5Ou.js} +1 -1
- package/dist/assets/{es-CzkousWe.js → es-DYI7U61K.js} +1 -1
- package/dist/assets/{esm-CBkHtTOV.js → esm-BC1J92im.js} +1 -1
- package/dist/assets/{esm-DhTsVMLM.js → esm-DKLLCu3N.js} +1 -1
- package/dist/assets/{field-B1jGbQlH.js → field-B08lvxnl.js} +1 -1
- package/dist/assets/file-explorer-panel-BUk69TND.js +26 -0
- package/dist/assets/{file-icons-CWLHDa1J.js → file-icons-3DTS8ZM7.js} +1 -1
- package/dist/assets/{floating-outline-BvQKiC0F.js → floating-outline-DmugATcB.js} +1 -1
- package/dist/assets/{flowDiagram-NV44I4VS-CQlIJ12H.js → flowDiagram-NV44I4VS-D85BL4rA.js} +1 -1
- package/dist/assets/{focus-DYwTiH9-.js → focus-DlJH7sfh.js} +1 -1
- package/dist/assets/{form-CrQYrsUC.js → form-760_EqmF.js} +2 -2
- package/dist/assets/{formats-rhOJovGE.js → formats-wYuh1bqp.js} +1 -1
- package/dist/assets/{formatting-B4ZCH3ol.js → formatting-CraOPe94.js} +1 -1
- package/dist/assets/{gallery-page-eRea0yic.js → gallery-page--paiPvYX.js} +1 -1
- package/dist/assets/{ganttDiagram-JELNMOA3-B3EGIuZL.js → ganttDiagram-JELNMOA3-DzCOXWlF.js} +1 -1
- package/dist/assets/{gitGraphDiagram-V2S2FVAM-h5SlguJK.js → gitGraphDiagram-V2S2FVAM-BUHURX6t.js} +1 -1
- package/dist/assets/{glide-data-editor-xt5xNZeV.js → glide-data-editor-DYdoQTO5.js} +4 -4
- package/dist/assets/{globals-BsV5fVR-.js → globals-7M5DRsIb.js} +1 -1
- package/dist/assets/home-page-CxQ1e98h.js +4 -0
- package/dist/assets/{hooks-CHx5dUUq.js → hooks-C3jEff2O.js} +1 -1
- package/dist/assets/html-to-image-DTFXm6_Z.js +2 -0
- package/dist/assets/{index-GjXovVsl.css → index-BmoocKR0.css} +1 -1
- package/dist/assets/index-DNchElHl.js +38 -0
- package/dist/assets/{infoDiagram-HS3SLOUP-pzpClObZ.js → infoDiagram-HS3SLOUP-GG5r0Y5G.js} +1 -1
- package/dist/assets/{input-CUwqpKjd.js → input-CN1ZeRYm.js} +1 -1
- package/dist/assets/{isValid-BGe7pJXT.js → isValid-DY4Mgbr7.js} +1 -1
- package/dist/assets/{journeyDiagram-XKPGCS4Q-BrdRi92v.js → journeyDiagram-XKPGCS4Q-B1dvnV4D.js} +1 -1
- package/dist/assets/{kanban-definition-3W4ZIXB7-B6WqgFqh.js → kanban-definition-3W4ZIXB7-CefbrXQv.js} +1 -1
- package/dist/assets/{kiosk-mode-DNjEnIWb.js → kiosk-mode-CyTnrzwK.js} +1 -1
- package/dist/assets/{layout-CwFtCyW8.js → layout-3b3tzmbb.js} +3 -3
- package/dist/assets/{linear-BP9rwmWK.js → linear-BDnrHGYO.js} +1 -1
- package/dist/assets/{links-CIQwYQ48.js → links-CptYD1FP.js} +1 -1
- package/dist/assets/{logs-panel-BU1tNEVc.js → logs-panel-C4k_2IHW.js} +1 -1
- package/dist/assets/{markdown-renderer-MR9df58W.js → markdown-renderer-DSy5IuAx.js} +1 -1
- package/dist/assets/{menu-items-UxKrm8hS.js → menu-items-BpHXKv51.js} +1 -1
- package/dist/assets/mermaid-4DMBBIKO-g7AL4SLJ.js +1 -0
- package/dist/assets/{mermaid-Djr3jUAB.js → mermaid-C43VbdrM.js} +3 -3
- package/dist/assets/{mermaid-parser.core-DR82IMb2.js → mermaid-parser.core-CdM8D_p_.js} +1 -1
- package/dist/assets/{mindmap-definition-VGOIOE7T-DAmJpbPM.js → mindmap-definition-VGOIOE7T-CcV7D-wF.js} +1 -1
- package/dist/assets/{mode-AcL8c6qH.js → mode-D-iRbN9x.js} +1 -1
- package/dist/assets/{multi-map-Pp1P2DOX.js → multi-map-C8RbwBrw.js} +1 -1
- package/dist/assets/{name-cell-input-DVFEv_aO.js → name-cell-input-Dyb0ZO4X.js} +1 -1
- package/dist/assets/{number-overlay-editor-D__AflXQ.js → number-overlay-editor-BBJO1mf8.js} +1 -1
- package/dist/assets/{outline-panel-CP0oIuiU.js → outline-panel-D7CJwO8u.js} +1 -1
- package/dist/assets/{packages-panel-CzRELimG.js → packages-panel-Bp1SYjgc.js} +1 -1
- package/dist/assets/{panels-wTweRyIv.js → panels-D0aw6jdc.js} +1 -1
- package/dist/assets/{pieDiagram-ADFJNKIX-DbGIFRoq.js → pieDiagram-ADFJNKIX-C1fBf15W.js} +1 -1
- package/dist/assets/{popover-BPGG2gPG.js → popover-Bvoif-Mg.js} +1 -1
- package/dist/assets/{precisionRound-BOmLQIKI.js → precisionRound-CCOoIlcP.js} +1 -1
- package/dist/assets/{process-output-CTVsT--B.js → process-output-BxPWHcIi.js} +1 -1
- package/dist/assets/{quadrantDiagram-AYHSOK5B-CLAtyple.js → quadrantDiagram-AYHSOK5B-RVooN-fX.js} +1 -1
- package/dist/assets/{react-vega-BZav_-2n.js → react-vega-BKRQSy0g.js} +1 -1
- package/dist/assets/react-vega-DXESF7qN.js +1 -0
- package/dist/assets/{readonly-python-code-DH-1xZGq.js → readonly-python-code-D95oshJa.js} +1 -1
- package/dist/assets/{renderShortcut-CnD1Dah5.js → renderShortcut-BYvKm38e.js} +1 -1
- package/dist/assets/{request-registry-B-7cIM_I.js → request-registry-XB2EzJHm.js} +1 -1
- package/dist/assets/{requirementDiagram-UZGBJVZJ-DDDTB1LD.js → requirementDiagram-UZGBJVZJ-DtqOYJpH.js} +1 -1
- package/dist/assets/{run-page-FCvGnICa.js → run-page-B7CASued.js} +1 -1
- package/dist/assets/{sankeyDiagram-TZEHDZUN-DAWPOfBw.js → sankeyDiagram-TZEHDZUN-DmcooLA8.js} +1 -1
- package/dist/assets/{scratchpad-panel-k9lrm-rC.js → scratchpad-panel-BIVRgYOU.js} +1 -1
- package/dist/assets/{secrets-panel-B1Z-6dmz.js → secrets-panel-C24hZEiO.js} +1 -1
- package/dist/assets/{select-CxT2Geqr.js → select-Cnd3vm9n.js} +1 -1
- package/dist/assets/{sequenceDiagram-WL72ISMW-D_qAidD2.js → sequenceDiagram-WL72ISMW-S2qeLb7J.js} +1 -1
- package/dist/assets/{session-panel-WhN0qilM.js → session-panel-CNabBHQm.js} +1 -1
- package/dist/assets/{share-BdH_5I58.js → share-NjpZ54PJ.js} +1 -1
- package/dist/assets/{snippets-panel-BCDHUuku.js → snippets-panel-D1JAeJj1.js} +1 -1
- package/dist/assets/{spec-DbmSqx09.js → spec-DnVBmJUh.js} +1 -1
- package/dist/assets/{state-Ce7CVShi.js → state-BagvlaEz.js} +1 -1
- package/dist/assets/{state-3V5UxC3B.js → state-Cz_wrzCz.js} +1 -1
- package/dist/assets/{state-CBmCYWFH.js → state-DMQXxemS.js} +1 -1
- package/dist/assets/{stateDiagram-FKZM4ZOC-C7qgDrGA.js → stateDiagram-FKZM4ZOC-uuQ60pIl.js} +1 -1
- package/dist/assets/stateDiagram-v2-4FDKWEC3-D-GWhQTG.js +1 -0
- package/dist/assets/stex-CruVQx-P.js +1 -0
- package/dist/assets/{switch-CVKxYu_0.js → switch-Bwpd2AFq.js} +1 -1
- package/dist/assets/{terminal-Cr7wbEjz.js → terminal-Gl8Fi44y.js} +1 -1
- package/dist/assets/{time-D2GKc0U6.js → time-Bw8f15NM.js} +1 -1
- package/dist/assets/{timeline-definition-IT6M3QCI-hd6uJKGs.js → timeline-definition-IT6M3QCI-TKWeDnSQ.js} +1 -1
- package/dist/assets/{toggle-RCwU-rnE.js → toggle-C_gNjXg8.js} +1 -1
- package/dist/assets/{tooltip-D9723Brr.js → tooltip-CR_izE8Q.js} +1 -1
- package/dist/assets/tracing-DwAC7DWN.js +1 -0
- package/dist/assets/tracing-panel-D1iNgclL.js +2 -0
- package/dist/assets/{tree-Ch2-GuhG.js → tree-WVrWjdwv.js} +3 -3
- package/dist/assets/{useAddCell-YC7rpcmD.js → useAddCell-D6Q7JziZ.js} +1 -1
- package/dist/assets/{useBoolean-m1e6E3Ao.js → useBoolean-CrltYVhE.js} +1 -1
- package/dist/assets/{useCellActionButton-GUb2fXU8.js → useCellActionButton-B2G9OaX9.js} +1 -1
- package/dist/assets/{useDateFormatter-CpE7XQLs.js → useDateFormatter-DOoVZUts.js} +1 -1
- package/dist/assets/{useDeleteCell-DRUDRiy0.js → useDeleteCell-d8veThW7.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-nFVMlEx0.js → useDependencyPanelTab-B3iIj3MO.js} +1 -1
- package/dist/assets/{useInstallPackage-C9V-on2J.js → useInstallPackage-CQEr5429.js} +1 -1
- package/dist/assets/{useNotebookActions-ChLHy-0O.js → useNotebookActions-SAEOWcBo.js} +1 -1
- package/dist/assets/{useNumberFormatter-DbDKSvEd.js → useNumberFormatter-BXZcbTzH.js} +1 -1
- package/dist/assets/{usePress-BHGkpw8X.js → usePress-alQ5Crny.js} +1 -1
- package/dist/assets/{useRunCells-5m6jCnyo.js → useRunCells-Dhl8ZTGh.js} +1 -1
- package/dist/assets/{useSplitCell-DGD9smMq.js → useSplitCell-BSnFazbH.js} +1 -1
- package/dist/assets/{utils-CdjCA1J8.js → utils-C24l2A1T.js} +1 -1
- package/dist/assets/{vega-component-CRbeDmeM.js → vega-component-9Pf4pVZL.js} +1 -1
- package/dist/assets/{vega-loader.browser-CZV6_g2i.js → vega-loader.browser-BJ9oKrvH.js} +1 -1
- package/dist/assets/{write-secret-modal-BCvuRAFb.js → write-secret-modal-BFCsWMoW.js} +1 -1
- package/dist/assets/{xychartDiagram-PRI3JC2R-CXlUBSbQ.js → xychartDiagram-PRI3JC2R-CIp-yeSa.js} +1 -1
- package/dist/index.html +125 -125
- package/package.json +1 -1
- package/src/__mocks__/notebook.ts +9 -9
- package/src/__tests__/branded.ts +20 -0
- package/src/components/app-config/user-config-form.tsx +5 -4
- package/src/components/data-table/__tests__/utils.test.ts +138 -1
- package/src/components/data-table/charts/__tests__/storage.test.ts +7 -7
- package/src/components/data-table/context-menu.tsx +9 -5
- package/src/components/data-table/data-table.tsx +3 -0
- package/src/components/data-table/range-focus/__tests__/atoms.test.ts +8 -2
- package/src/components/data-table/range-focus/__tests__/test-utils.ts +2 -0
- package/src/components/data-table/range-focus/__tests__/utils.test.ts +82 -8
- package/src/components/data-table/range-focus/atoms.ts +2 -2
- package/src/components/data-table/range-focus/utils.ts +50 -12
- package/src/components/data-table/types.ts +7 -0
- package/src/components/data-table/utils.ts +87 -0
- package/src/components/editor/__tests__/data-attributes.test.tsx +8 -8
- package/src/components/editor/ai/__tests__/completion-utils.test.ts +15 -15
- package/src/components/editor/navigation/__tests__/clipboard.test.ts +2 -2
- package/src/components/editor/navigation/__tests__/selection.test.ts +7 -6
- package/src/components/editor/navigation/__tests__/state.test.ts +8 -7
- package/src/components/editor/output/MarimoErrorOutput.tsx +7 -7
- package/src/components/editor/output/__tests__/traceback.test.tsx +4 -4
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +4 -4
- package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +8 -1
- package/src/components/storage/storage-file-viewer.tsx +35 -1
- package/src/components/storage/storage-inspector.tsx +9 -4
- package/src/components/storage/storage-snippets.ts +3 -3
- package/src/components/tracing/tracing.tsx +3 -1
- package/src/components/ui/range-slider.tsx +108 -1
- package/src/core/ai/__tests__/staged-cells.test.ts +9 -8
- package/src/core/ai/context/providers/__tests__/cell-output.test.ts +31 -31
- package/src/core/ai/context/providers/__tests__/datasource.test.ts +3 -3
- package/src/core/ai/context/providers/__tests__/tables.test.ts +3 -2
- package/src/core/ai/context/providers/__tests__/variable.test.ts +84 -63
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +10 -9
- package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +6 -6
- package/src/core/ai/tools/edit-notebook-tool.ts +3 -3
- package/src/core/cells/__tests__/add-missing-import.test.ts +3 -3
- package/src/core/cells/__tests__/cells.test.ts +192 -135
- package/src/core/cells/__tests__/focus.test.ts +5 -4
- package/src/core/cells/__tests__/logs.test.ts +13 -12
- package/src/core/cells/__tests__/pending-delete-service.test.tsx +3 -3
- package/src/core/cells/__tests__/runs.test.ts +22 -21
- package/src/core/cells/__tests__/scrollCellIntoView.test.ts +8 -7
- package/src/core/cells/__tests__/session.test.ts +23 -22
- package/src/core/cells/cells.ts +1 -1
- package/src/core/cells/ids.ts +5 -5
- package/src/core/cells/logs.ts +2 -2
- package/src/core/cells/runs.ts +6 -8
- package/src/core/codemirror/__tests__/format.test.ts +34 -36
- package/src/core/codemirror/__tests__/setup.test.ts +2 -2
- package/src/core/codemirror/cells/__tests__/extensions.test.ts +114 -0
- package/src/core/codemirror/cells/__tests__/traceback-decorations.test.ts +33 -32
- package/src/core/codemirror/cells/extensions.ts +66 -23
- package/src/core/codemirror/completion/__tests__/keymap.test.ts +15 -35
- package/src/core/codemirror/completion/keymap.ts +14 -4
- package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +12 -13
- package/src/core/codemirror/language/__tests__/utils.test.ts +3 -3
- package/src/core/codemirror/language/embedded/__tests__/embedded-python.test.ts +7 -8
- package/src/core/codemirror/language/languages/python.ts +4 -0
- package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +4 -3
- package/src/core/codemirror/lsp/notebook-lsp.ts +28 -2
- package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +7 -6
- package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
- package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +52 -0
- package/src/core/codemirror/rtc/loro/sync.ts +1 -0
- package/src/core/datasets/__tests__/data-source.test.ts +5 -6
- package/src/core/datasets/state.ts +1 -1
- package/src/core/errors/__tests__/errors.test.ts +2 -1
- package/src/core/export/__tests__/hooks.test.ts +37 -36
- package/src/core/islands/main.ts +2 -7
- package/src/core/kernel/__tests__/handlers.test.ts +5 -4
- package/src/core/kernel/handlers.ts +7 -4
- package/src/core/network/DeferredRequestRegistry.ts +2 -2
- package/src/core/network/__tests__/CachingRequestRegistry.test.ts +9 -10
- package/src/core/network/__tests__/DeferredRequestRegistry.test.ts +4 -6
- package/src/core/static/__tests__/virtual-file-tracker.test.ts +8 -8
- package/src/core/static/virtual-file-tracker.ts +1 -1
- package/src/core/storage/__tests__/state.test.ts +31 -21
- package/src/core/storage/state.ts +1 -1
- package/src/core/variables/__tests__/state.test.ts +6 -6
- package/src/core/variables/types.ts +2 -2
- package/src/core/wasm/__tests__/state.test.ts +8 -8
- package/src/core/websocket/useMarimoKernelConnection.tsx +12 -15
- package/src/css/md-tooltip.css +4 -39
- package/src/css/md.css +7 -0
- package/src/plugins/core/RenderHTML.tsx +17 -0
- package/src/plugins/core/__test__/RenderHTML.test.ts +45 -0
- package/src/plugins/core/sanitize-html.ts +25 -18
- package/src/plugins/impl/DataTablePlugin.tsx +23 -2
- package/src/plugins/impl/SliderPlugin.tsx +1 -3
- package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +120 -0
- package/src/plugins/impl/anywidget/model.ts +1 -2
- package/src/stories/cell.stories.tsx +8 -8
- package/src/stories/layout/vertical/one-column.stories.tsx +9 -8
- package/src/stories/log-viewer.stories.tsx +8 -8
- package/src/stories/variables.stories.tsx +2 -2
- package/src/utils/__tests__/download.test.tsx +21 -20
- package/src/utils/copy.ts +18 -5
- package/src/utils/download.ts +4 -3
- package/src/utils/html-to-image.ts +6 -0
- package/src/utils/json/base64.ts +3 -3
- package/src/utils/traceback.ts +5 -3
- package/dist/assets/JsonOutput-DKXKGKvX.js +0 -46
- package/dist/assets/RenderHTML-DJ8khuob.js +0 -1
- package/dist/assets/ai-model-dropdown-DPTa_EpU.js +0 -5
- package/dist/assets/cell-editor-DX7IcqNr.js +0 -23
- package/dist/assets/channel-CkT8Qdo2.js +0 -1
- package/dist/assets/classDiagram-2ON5EDUG-BhMT_rTz.js +0 -1
- package/dist/assets/classDiagram-v2-WZHVMYZB-D-F4WEyb.js +0 -1
- package/dist/assets/copy-YwM0Pd7v.js +0 -1
- package/dist/assets/dist-BTqMkf4j.js +0 -1
- package/dist/assets/dist-DHw9sXeN.js +0 -1
- package/dist/assets/dist-Du0qZeXz.js +0 -1
- package/dist/assets/dist-a0FfbvMD.js +0 -1
- package/dist/assets/dist-cfkfP0ni.js +0 -1
- package/dist/assets/dist-pzQ9JG-p.js +0 -1
- package/dist/assets/file-explorer-panel-CB8vF5ob.js +0 -26
- package/dist/assets/home-page-itW0tRmv.js +0 -4
- package/dist/assets/html-to-image-BnSc-Wa0.js +0 -2
- package/dist/assets/index-0n92c_W7.js +0 -38
- package/dist/assets/mermaid-4DMBBIKO-PoHnhmy8.js +0 -1
- package/dist/assets/react-vega-Da-Ps9UW.js +0 -1
- package/dist/assets/stateDiagram-v2-4FDKWEC3-CEqeIlM0.js +0 -1
- package/dist/assets/stex-BBWVYm-R.js +0 -1
- package/dist/assets/tracing-DUVd0jtl.js +0 -1
- package/dist/assets/tracing-panel-CuTxPn_x.js +0 -2
- /package/dist/assets/{Combination-Cs9nbinQ.js → Combination-CSPK4t6z.js} +0 -0
- /package/dist/assets/{Deferred-BMfCOLaw.js → Deferred-CfyqLOPG.js} +0 -0
- /package/dist/assets/{SSRProvider-DC7ElCZZ.js → SSRProvider-CwqN9FWV.js} +0 -0
- /package/dist/assets/{badge-hTpPIsMT.js → badge-DImLVznf.js} +0 -0
- /package/dist/assets/{blob-CObhN-9g.js → blob-DgooIGjS.js} +0 -0
- /package/dist/assets/{bot-message-square-CK6eoGWy.js → bot-message-square-Dw41U6lL.js} +0 -0
- /package/dist/assets/{chart-no-axes-column-DV8gdCvH.js → chart-no-axes-column-a9XtWmzk.js} +0 -0
- /package/dist/assets/{check-BE0hEwVo.js → check-DZA_bRpw.js} +0 -0
- /package/dist/assets/{chevron-right-D0GQBpTb.js → chevron-right-CvVxySQk.js} +0 -0
- /package/dist/assets/{circle-check-gLIOLu8x.js → circle-check-CbaVeozR.js} +0 -0
- /package/dist/assets/{circle-play-DYGULlKZ.js → circle-play-DYn5nR6N.js} +0 -0
- /package/dist/assets/{circle-plus-CGG-gArM.js → circle-plus-nCze0-py.js} +0 -0
- /package/dist/assets/{clipboard-paste-DoYSN8Sv.js → clipboard-paste-EHXeKq9D.js} +0 -0
- /package/dist/assets/{code-xml-DwHPF_nL.js → code-xml-BlrJCgNZ.js} +0 -0
- /package/dist/assets/{copy-CkudG0Ej.js → copy-D6N1-xc1.js} +0 -0
- /package/dist/assets/{database-zap-DTWCDKdn.js → database-zap-BIGMFOfP.js} +0 -0
- /package/dist/assets/{defaultLocale-DK1MWd7f.js → defaultLocale-CGfP-Ye3.js} +0 -0
- /package/dist/assets/{defaultLocale-OkOxlkkM.js → defaultLocale-CuYNS33t.js} +0 -0
- /package/dist/assets/{dist-8UD0A5sU.js → dist-BF9S272t.js} +0 -0
- /package/dist/assets/{dist-apDpadc4.js → dist-Bk1itfBD.js} +0 -0
- /package/dist/assets/{dist-CQqv2gQL.js → dist-Dm11d0_A.js} +0 -0
- /package/dist/assets/{download-DBW9RXtT.js → download-nLboiTtW.js} +0 -0
- /package/dist/assets/{ellipsis-0_zJdF6H.js → ellipsis-d7eaKIFn.js} +0 -0
- /package/dist/assets/{ellipsis-vertical-CAB7tdza.js → ellipsis-vertical-DBQ5kWTo.js} +0 -0
- /package/dist/assets/{emotion-is-prop-valid.esm-D1keIaYa.js → emotion-is-prop-valid.esm-D7FeWASw.js} +0 -0
- /package/dist/assets/{errors-Bfogio62.js → errors-0IrrdfSG.js} +0 -0
- /package/dist/assets/{extends-DRbCSry7.js → extends-aq1t6BkR.js} +0 -0
- /package/dist/assets/{eye-off-vwi9L975.js → eye-off-CF3GmvXV.js} +0 -0
- /package/dist/assets/{file-DzHkbIdO.js → file-C-yMeaec.js} +0 -0
- /package/dist/assets/{file-headphone-B5q2Ow55.js → file-headphone-CPAP8asn.js} +0 -0
- /package/dist/assets/{file-plus-corner-lLQw9OnR.js → file-plus-corner-ks__N1mr.js} +0 -0
- /package/dist/assets/{github-BVtI-3F1.js → github-CRD4USKm.js} +0 -0
- /package/dist/assets/{image-DXfkah9d.js → image-CfyJzBP9.js} +0 -0
- /package/dist/assets/{link-Cf10mh3t.js → link-_dbp0XNB.js} +0 -0
- /package/dist/assets/{maps-OKerBHH8.js → maps-DQsjfyTy.js} +0 -0
- /package/dist/assets/{numbers-CYnquDho.js → numbers-Cno6K0UF.js} +0 -0
- /package/dist/assets/{objectWithoutPropertiesLoose-DP4vAkvg.js → objectWithoutPropertiesLoose-Dxmp_Bd_.js} +0 -0
- /package/dist/assets/{ordinal-BjO5SoTk.js → ordinal-CMAUv8ku.js} +0 -0
- /package/dist/assets/{paths-D2lG83Oh.js → paths-BVwhPRFT.js} +0 -0
- /package/dist/assets/{play-DKSqmedg.js → play-Bu_0ogGD.js} +0 -0
- /package/dist/assets/{plus-dVmh0yTy.js → plus-DJ99CUbx.js} +0 -0
- /package/dist/assets/{preload-helper-BW0IMuFq.js → preload-helper-y72bE5iF.js} +0 -0
- /package/dist/assets/{prop-types-RrUi-pOT.js → prop-types-DRf51_gT.js} +0 -0
- /package/dist/assets/{purify.es-BBn8CPhf.js → purify.es-Cf8RQecB.js} +0 -0
- /package/dist/assets/{range-DNqFcYmr.js → range-ClqUI25v.js} +0 -0
- /package/dist/assets/{refresh-ccw-DLpfIr8v.js → refresh-ccw-DQ6SJ8UC.js} +0 -0
- /package/dist/assets/{refresh-cw-CHAHPgkx.js → refresh-cw-Dg9tCj4k.js} +0 -0
- /package/dist/assets/{rotate-ccw-hLlF_82X.js → rotate-ccw-BCkZViUZ.js} +0 -0
- /package/dist/assets/{save-8fSvKYJT.js → save-CUdcv5qm.js} +0 -0
- /package/dist/assets/{session-BrEm7qNv.js → session-CByuQ-M-.js} +0 -0
- /package/dist/assets/{settings-CzQUw9rV.js → settings-B7nhfCat.js} +0 -0
- /package/dist/assets/{spinner-C5JoisA7.js → spinner-pCogyRyo.js} +0 -0
- /package/dist/assets/{square-CxAsQQ77.js → square-KVNDGpgy.js} +0 -0
- /package/dist/assets/{square-function-B006EYFX.js → square-function-BMNCw7Qb.js} +0 -0
- /package/dist/assets/{stex-0ac7Aukl.js → stex-C6JeW1YI.js} +0 -0
- /package/dist/assets/{table-BCnp9gKC.js → table-Od8PbuV-.js} +0 -0
- /package/dist/assets/{toDate-BqKH-Jd9.js → toDate-Cfp9W_O9.js} +0 -0
- /package/dist/assets/{trash-2-CAoNMkjq.js → trash-2-Bc_J7TQO.js} +0 -0
- /package/dist/assets/{trash-BZMAQneW.js → trash-Cxd189Vw.js} +0 -0
- /package/dist/assets/{triangle-alert-qZo1ox6x.js → triangle-alert-CzLrbLGN.js} +0 -0
- /package/dist/assets/{types-C1RN112u.js → types-CLOMZuqU.js} +0 -0
- /package/dist/assets/{use-toast-Hc8CXlvz.js → use-toast-BtZldTi5.js} +0 -0
- /package/dist/assets/{useDebounce-B0dx2Gp0.js → useDebounce-DwTO_rGp.js} +0 -0
- /package/dist/assets/{useTheme-BYXBU1of.js → useTheme-KDW4sktg.js} +0 -0
- /package/dist/assets/{uuid-ClFZlR7U.js → uuid-BukULOeS.js} +0 -0
- /package/dist/assets/{workflow-BmeqNuSH.js → workflow-BqHyyStM.js} +0 -0
- /package/dist/assets/{x-BI1M8X_v.js → x-CdLP7-v3.js} +0 -0
- /package/dist/assets/{youtube-DE-Ej6FR.js → youtube-CfU-SnDw.js} +0 -0
|
@@ -2,9 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import { closeCompletion, completionStatus } from "@codemirror/autocomplete";
|
|
4
4
|
import { type Extension, Prec } from "@codemirror/state";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
EditorView,
|
|
7
|
+
type KeyBinding,
|
|
8
|
+
keymap,
|
|
9
|
+
type ViewUpdate,
|
|
10
|
+
} from "@codemirror/view";
|
|
6
11
|
import { createTracebackInfoAtom } from "@/core/cells/cells";
|
|
7
12
|
import { type CellId, HTMLCellId, SCRATCH_CELL_ID } from "@/core/cells/ids";
|
|
13
|
+
import { loroSyncAnnotation } from "@/core/codemirror/rtc/loro/sync";
|
|
8
14
|
import type { KeymapConfig } from "@/core/config/config-schema";
|
|
9
15
|
import type { HotkeyProvider } from "@/core/hotkeys/hotkeys";
|
|
10
16
|
import { duplicateWithCtrlModifier } from "@/core/hotkeys/shortcuts";
|
|
@@ -330,6 +336,53 @@ function cellCodeEditing(hotkeys: HotkeyProvider): Extension[] {
|
|
|
330
336
|
return [onChangePlugin, formatKeymapExtension(hotkeys)];
|
|
331
337
|
}
|
|
332
338
|
|
|
339
|
+
const MARKDOWN_AUTORUN_USER_EVENTS = ["input", "delete", "undo", "redo"];
|
|
340
|
+
|
|
341
|
+
function shouldAutorunMarkdownUpdate({
|
|
342
|
+
docChanged,
|
|
343
|
+
transactions,
|
|
344
|
+
predicate = () => true,
|
|
345
|
+
hasFocus = false,
|
|
346
|
+
}: Pick<ViewUpdate, "docChanged" | "transactions"> & {
|
|
347
|
+
predicate?: () => boolean;
|
|
348
|
+
hasFocus?: boolean;
|
|
349
|
+
}): boolean {
|
|
350
|
+
// If the doc didn't change, ignore.
|
|
351
|
+
if (!docChanged) {
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// The caller decides when markdown autorun is allowed, e.g. not for
|
|
356
|
+
// f-strings where rerunning on every keystroke is usually incorrect.
|
|
357
|
+
if (!predicate()) {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// This happens on mount when we start in markdown mode.
|
|
362
|
+
// Ignore formatting changes so language switches don't trigger autorun.
|
|
363
|
+
const isFormattingChange = transactions.some((tr) =>
|
|
364
|
+
tr.effects.some((effect) => effect.is(formattingChangeEffect)),
|
|
365
|
+
);
|
|
366
|
+
if (isFormattingChange) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return transactions.some((tr) => {
|
|
371
|
+
// Ignore RTC sync changes to avoid duplicate runs from remote edits.
|
|
372
|
+
if (tr.annotation(loroSyncAnnotation) !== undefined) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Prefer explicit local edit transactions, but keep a focused fallback for
|
|
377
|
+
// local rewrite paths like split-cell, which can update markdown content
|
|
378
|
+
// without annotating a user event.
|
|
379
|
+
return (
|
|
380
|
+
MARKDOWN_AUTORUN_USER_EVENTS.some((kind) => tr.isUserEvent(kind)) ||
|
|
381
|
+
hasFocus
|
|
382
|
+
);
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
|
|
333
386
|
/**
|
|
334
387
|
* Extension for auto-running markdown cells
|
|
335
388
|
*/
|
|
@@ -339,30 +392,16 @@ export function markdownAutoRunExtension({
|
|
|
339
392
|
predicate: () => boolean;
|
|
340
393
|
}): Extension {
|
|
341
394
|
return EditorView.updateListener.of((update) => {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (!predicate()) {
|
|
395
|
+
if (
|
|
396
|
+
!shouldAutorunMarkdownUpdate({
|
|
397
|
+
docChanged: update.docChanged,
|
|
398
|
+
transactions: update.transactions,
|
|
399
|
+
predicate,
|
|
400
|
+
hasFocus: update.view.hasFocus,
|
|
401
|
+
})
|
|
402
|
+
) {
|
|
354
403
|
return;
|
|
355
404
|
}
|
|
356
|
-
|
|
357
|
-
// This happens on mount when we start in markdown mode
|
|
358
|
-
const isFormattingChange = update.transactions.some((tr) =>
|
|
359
|
-
tr.effects.some((effect) => effect.is(formattingChangeEffect)),
|
|
360
|
-
);
|
|
361
|
-
if (isFormattingChange) {
|
|
362
|
-
// Ignore formatting changes
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
405
|
const actions = update.view.state.facet(cellActionsState);
|
|
367
406
|
actions.onRun();
|
|
368
407
|
});
|
|
@@ -388,3 +427,7 @@ export function cellBundle({
|
|
|
388
427
|
),
|
|
389
428
|
];
|
|
390
429
|
}
|
|
430
|
+
|
|
431
|
+
export const exportedForTesting = {
|
|
432
|
+
shouldAutorunMarkdownUpdate,
|
|
433
|
+
};
|
|
@@ -1,44 +1,24 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { completionKeymap } from "../keymap";
|
|
3
|
+
import { completionKeymap as defaultCompletionKeymap } from "@codemirror/autocomplete";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { filterCompletionBindings } from "../keymap";
|
|
7
6
|
|
|
8
7
|
describe("completionKeymap", () => {
|
|
9
|
-
it("
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
vi.spyOn(view.state, "field").mockReturnValue("pending");
|
|
17
|
-
|
|
18
|
-
view.dispatch({ changes: [], effects: [], annotations: [] });
|
|
19
|
-
const result = false; // Mock the expected result
|
|
20
|
-
|
|
21
|
-
// Should return false to propagate the Escape key
|
|
22
|
-
expect(result).toBe(false);
|
|
23
|
-
|
|
24
|
-
view.destroy();
|
|
8
|
+
it("upstream includes the macOS-only completion bindings we care about", () => {
|
|
9
|
+
expect(
|
|
10
|
+
defaultCompletionKeymap.some((binding) => binding.mac === "Alt-`"),
|
|
11
|
+
).toBe(true);
|
|
12
|
+
expect(
|
|
13
|
+
defaultCompletionKeymap.some((binding) => binding.mac === "Alt-i"),
|
|
14
|
+
).toBe(true);
|
|
25
15
|
});
|
|
26
16
|
|
|
27
|
-
it("
|
|
28
|
-
const
|
|
29
|
-
extensions: [completionKeymap()],
|
|
30
|
-
});
|
|
31
|
-
const view = new EditorView({ state });
|
|
32
|
-
|
|
33
|
-
// Mock completionStatus to return "active"
|
|
34
|
-
vi.spyOn(view.state, "field").mockReturnValue("active");
|
|
35
|
-
|
|
36
|
-
view.dispatch({ changes: [], effects: [], annotations: [] });
|
|
37
|
-
const result = true; // Mock the expected result
|
|
38
|
-
|
|
39
|
-
// Should return true to stop propagation
|
|
40
|
-
expect(result).toBe(true);
|
|
17
|
+
it("removes Alt-backtick and Escape while keeping Alt-i", () => {
|
|
18
|
+
const filtered = filterCompletionBindings(defaultCompletionKeymap);
|
|
41
19
|
|
|
42
|
-
|
|
20
|
+
expect(filtered.some((binding) => binding.mac === "Alt-`")).toBe(false);
|
|
21
|
+
expect(filtered.some((binding) => binding.key === "Escape")).toBe(false);
|
|
22
|
+
expect(filtered.some((binding) => binding.mac === "Alt-i")).toBe(true);
|
|
43
23
|
});
|
|
44
24
|
});
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
moveCompletionSelection,
|
|
7
7
|
} from "@codemirror/autocomplete";
|
|
8
8
|
import { type Extension, Prec } from "@codemirror/state";
|
|
9
|
-
import { keymap } from "@codemirror/view";
|
|
9
|
+
import { type KeyBinding, keymap } from "@codemirror/view";
|
|
10
10
|
import { isInVimMode } from "../utils";
|
|
11
11
|
|
|
12
12
|
const KEYS_TO_REMOVE = new Set<string | undefined>([
|
|
@@ -22,10 +22,20 @@ const KEYS_TO_REMOVE = new Set<string | undefined>([
|
|
|
22
22
|
"Alt-`",
|
|
23
23
|
]);
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
function hasRemovedKeybinding(binding: KeyBinding): boolean {
|
|
26
|
+
return [binding.key, binding.mac, binding.linux, binding.win].some((key) =>
|
|
27
|
+
KEYS_TO_REMOVE.has(key),
|
|
28
28
|
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function filterCompletionBindings(
|
|
32
|
+
bindings: readonly KeyBinding[],
|
|
33
|
+
): readonly KeyBinding[] {
|
|
34
|
+
return bindings.filter((binding) => !hasRemovedKeybinding(binding));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function completionKeymap(): Extension {
|
|
38
|
+
const withoutKeysToRemove = filterCompletionBindings(defaultCompletionKeymap);
|
|
29
39
|
|
|
30
40
|
return Prec.highest(
|
|
31
41
|
keymap.of([
|
|
@@ -3,28 +3,27 @@
|
|
|
3
3
|
import { EditorState } from "@codemirror/state";
|
|
4
4
|
import { EditorView } from "@codemirror/view";
|
|
5
5
|
import { describe, expect, it } from "vitest";
|
|
6
|
+
import { cellId, variableName } from "@/__tests__/branded";
|
|
6
7
|
import { initialNotebookState, notebookAtom } from "@/core/cells/cells";
|
|
7
|
-
import type { CellId } from "@/core/cells/ids";
|
|
8
8
|
import { OverridingHotkeyProvider } from "@/core/hotkeys/hotkeys";
|
|
9
9
|
import { store } from "@/core/state/jotai";
|
|
10
10
|
import { variablesAtom } from "@/core/variables/state";
|
|
11
|
-
import type { VariableName, Variables } from "@/core/variables/types";
|
|
12
11
|
import { MultiColumn } from "@/utils/id-tree";
|
|
13
12
|
import { cellConfigExtension } from "../../config/extension";
|
|
14
13
|
import { adaptiveLanguageConfiguration } from "../../language/extension";
|
|
15
14
|
import { getCodes, getTopologicalCellIds } from "../getCodes";
|
|
16
15
|
|
|
17
16
|
const Cells = {
|
|
18
|
-
cell1: "cell1"
|
|
19
|
-
cell2: "cell2"
|
|
20
|
-
cell3: "cell3"
|
|
21
|
-
cell4: "cell4"
|
|
17
|
+
cell1: cellId("cell1"),
|
|
18
|
+
cell2: cellId("cell2"),
|
|
19
|
+
cell3: cellId("cell3"),
|
|
20
|
+
cell4: cellId("cell4"),
|
|
22
21
|
};
|
|
23
22
|
|
|
24
23
|
const Variables = {
|
|
25
|
-
var1: "var1"
|
|
26
|
-
var2: "var2"
|
|
27
|
-
var3: "var3"
|
|
24
|
+
var1: variableName("var1"),
|
|
25
|
+
var2: variableName("var2"),
|
|
26
|
+
var3: variableName("var3"),
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
function createMockEditorView(code: string) {
|
|
@@ -33,7 +32,7 @@ function createMockEditorView(code: string) {
|
|
|
33
32
|
doc: code,
|
|
34
33
|
extensions: [
|
|
35
34
|
adaptiveLanguageConfiguration({
|
|
36
|
-
cellId: "cell1"
|
|
35
|
+
cellId: cellId("cell1"),
|
|
37
36
|
completionConfig: {
|
|
38
37
|
copilot: false,
|
|
39
38
|
activate_on_typing: true,
|
|
@@ -45,7 +44,7 @@ function createMockEditorView(code: string) {
|
|
|
45
44
|
lspConfig: {},
|
|
46
45
|
}),
|
|
47
46
|
cellConfigExtension({
|
|
48
|
-
cellId: "cell1"
|
|
47
|
+
cellId: cellId("cell1"),
|
|
49
48
|
completionConfig: {
|
|
50
49
|
copilot: false,
|
|
51
50
|
activate_on_typing: true,
|
|
@@ -71,7 +70,7 @@ describe("getTopologicalCellIds", () => {
|
|
|
71
70
|
it("should return topologically sorted cell IDs", () => {
|
|
72
71
|
// Setup mock data
|
|
73
72
|
const cellIds = [Cells.cell1, Cells.cell2, Cells.cell3, Cells.cell4];
|
|
74
|
-
const variables
|
|
73
|
+
const variables = {
|
|
75
74
|
[Variables.var1]: {
|
|
76
75
|
name: Variables.var1,
|
|
77
76
|
declaredBy: [Cells.cell1],
|
|
@@ -125,7 +124,7 @@ describe("getTopologicalCellIds", () => {
|
|
|
125
124
|
|
|
126
125
|
it("should put new cells (with no dependencies) at the end", () => {
|
|
127
126
|
const cellIds = [Cells.cell1, Cells.cell2, Cells.cell3, Cells.cell4];
|
|
128
|
-
const variables
|
|
127
|
+
const variables = {
|
|
129
128
|
[Variables.var1]: {
|
|
130
129
|
name: Variables.var1,
|
|
131
130
|
declaredBy: [Cells.cell2],
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { EditorState } from "@codemirror/state";
|
|
4
4
|
import { EditorView } from "@codemirror/view";
|
|
5
5
|
import { describe, expect, it } from "vitest";
|
|
6
|
-
import
|
|
6
|
+
import { cellId } from "@/__tests__/branded";
|
|
7
7
|
import { OverridingHotkeyProvider } from "@/core/hotkeys/hotkeys";
|
|
8
8
|
import { cellConfigExtension } from "../../config/extension";
|
|
9
9
|
import { adaptiveLanguageConfiguration, switchLanguage } from "../extension";
|
|
@@ -26,12 +26,12 @@ function createEditor(doc: string) {
|
|
|
26
26
|
codeium_api_key: null,
|
|
27
27
|
},
|
|
28
28
|
hotkeys: new OverridingHotkeyProvider({}),
|
|
29
|
-
cellId: "cell1"
|
|
29
|
+
cellId: cellId("cell1"),
|
|
30
30
|
placeholderType: "marimo-import",
|
|
31
31
|
lspConfig: {},
|
|
32
32
|
}),
|
|
33
33
|
cellConfigExtension({
|
|
34
|
-
cellId: "cell1"
|
|
34
|
+
cellId: cellId("cell1"),
|
|
35
35
|
completionConfig: {
|
|
36
36
|
activate_on_typing: true,
|
|
37
37
|
signature_hint_on_typing: false,
|
|
@@ -5,10 +5,9 @@ import { python } from "@codemirror/lang-python";
|
|
|
5
5
|
import { EditorState } from "@codemirror/state";
|
|
6
6
|
import type { InlineContext } from "@lezer/markdown";
|
|
7
7
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
8
|
-
import
|
|
8
|
+
import { cellId, variableName } from "@/__tests__/branded";
|
|
9
9
|
import { store } from "@/core/state/jotai";
|
|
10
10
|
import { variablesAtom } from "@/core/variables/state";
|
|
11
|
-
import type { VariableName, Variables } from "@/core/variables/types";
|
|
12
11
|
import { parsePython, variableCompletionSource } from "../embedded-python";
|
|
13
12
|
|
|
14
13
|
const IS_ACTIVE = () => true;
|
|
@@ -51,16 +50,16 @@ describe("parsePython", () => {
|
|
|
51
50
|
|
|
52
51
|
describe("variableCompletionSource", () => {
|
|
53
52
|
beforeEach(() => {
|
|
54
|
-
const mockCellId = "cell-1"
|
|
55
|
-
const mockVariables
|
|
56
|
-
["var1"
|
|
57
|
-
name: "var1"
|
|
53
|
+
const mockCellId = cellId("cell-1");
|
|
54
|
+
const mockVariables = {
|
|
55
|
+
[variableName("var1")]: {
|
|
56
|
+
name: variableName("var1"),
|
|
58
57
|
dataType: "int",
|
|
59
58
|
declaredBy: [mockCellId],
|
|
60
59
|
usedBy: [mockCellId],
|
|
61
60
|
},
|
|
62
|
-
["var2"
|
|
63
|
-
name: "var2"
|
|
61
|
+
[variableName("var2")]: {
|
|
62
|
+
name: variableName("var2"),
|
|
64
63
|
dataType: "str",
|
|
65
64
|
declaredBy: [mockCellId],
|
|
66
65
|
usedBy: [mockCellId],
|
|
@@ -69,6 +69,10 @@ const pylspClient = once((lspConfig: LSPConfig) => {
|
|
|
69
69
|
"W292", // No newline at end of file
|
|
70
70
|
// Modules can be imported in any cell
|
|
71
71
|
"E402", // Module level import not at top of file
|
|
72
|
+
// Blank line rules are not useful in marimo because cells are joined
|
|
73
|
+
// without extra blank lines, which can trigger these rules at cell boundaries
|
|
74
|
+
"E302", // Expected 2 blank lines, found 0
|
|
75
|
+
"E305", // Expected 2 blank lines after class or function definition, found 0
|
|
72
76
|
];
|
|
73
77
|
const ignoredRuffRules = [
|
|
74
78
|
// Even ruff documentation of this rule explains it is not useful in notebooks
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from "@marimo-team/codemirror-languageserver";
|
|
9
9
|
import { beforeEach, describe, expect, it, type Mocked, vi } from "vitest";
|
|
10
10
|
import * as LSP from "vscode-languageserver-protocol";
|
|
11
|
+
import { cellId } from "@/__tests__/branded";
|
|
11
12
|
import type { CellId } from "@/core/cells/ids";
|
|
12
13
|
import { store } from "@/core/state/jotai";
|
|
13
14
|
import { topologicalCodesAtom } from "../../copilot/getCodes";
|
|
@@ -19,9 +20,9 @@ import { NotebookLanguageServerClient } from "../notebook-lsp";
|
|
|
19
20
|
import { CellDocumentUri, type ILanguageServerClient } from "../types";
|
|
20
21
|
|
|
21
22
|
const Cells = {
|
|
22
|
-
cell1: "cell1"
|
|
23
|
-
cell2: "cell2"
|
|
24
|
-
cell3: "cell3"
|
|
23
|
+
cell1: cellId("cell1"),
|
|
24
|
+
cell2: cellId("cell2"),
|
|
25
|
+
cell3: cellId("cell3"),
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
describe("createNotebookLens", () => {
|
|
@@ -178,6 +178,8 @@ export class NotebookLanguageServerClient implements ILanguageServerClient {
|
|
|
178
178
|
string,
|
|
179
179
|
Promise<LSP.CompletionItem>
|
|
180
180
|
>(10);
|
|
181
|
+
private latestDiagnosticsVersion: number | null = null;
|
|
182
|
+
private forwardedDiagnosticsVersion = 0;
|
|
181
183
|
|
|
182
184
|
constructor(
|
|
183
185
|
client: ILanguageServerClient,
|
|
@@ -270,6 +272,8 @@ export class NotebookLanguageServerClient implements ILanguageServerClient {
|
|
|
270
272
|
|
|
271
273
|
// Get the current document state
|
|
272
274
|
const { lens, version } = this.snapshotter.snapshot();
|
|
275
|
+
this.latestDiagnosticsVersion = null;
|
|
276
|
+
this.forwardedDiagnosticsVersion = 0;
|
|
273
277
|
|
|
274
278
|
// Re-open the merged document with the LSP server
|
|
275
279
|
// This sends a textDocument/didOpen for the entire notebook
|
|
@@ -768,13 +772,34 @@ export class NotebookLanguageServerClient implements ILanguageServerClient {
|
|
|
768
772
|
| { method: "other"; params: unknown },
|
|
769
773
|
) => {
|
|
770
774
|
if (notification.method === "textDocument/publishDiagnostics") {
|
|
775
|
+
const incomingVersion = notification.params.version;
|
|
776
|
+
if (incomingVersion != null) {
|
|
777
|
+
const latestVersion = this.latestDiagnosticsVersion;
|
|
778
|
+
if (
|
|
779
|
+
latestVersion !== null &&
|
|
780
|
+
Number.isFinite(incomingVersion) &&
|
|
781
|
+
incomingVersion < latestVersion
|
|
782
|
+
) {
|
|
783
|
+
Logger.debug(
|
|
784
|
+
"[lsp] dropping stale diagnostics notification",
|
|
785
|
+
notification,
|
|
786
|
+
);
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
this.latestDiagnosticsVersion = incomingVersion;
|
|
790
|
+
}
|
|
791
|
+
|
|
771
792
|
Logger.debug("[lsp] handling diagnostics", notification);
|
|
772
793
|
// Use the correct lens by version
|
|
773
794
|
const payload = this.snapshotter.getLatestSnapshot();
|
|
774
795
|
|
|
775
796
|
const diagnostics = notification.params.diagnostics;
|
|
776
797
|
|
|
777
|
-
const { lens
|
|
798
|
+
const { lens } = payload;
|
|
799
|
+
// Forward diagnostics with a strictly increasing version so downstream
|
|
800
|
+
// plugin updates/clears reliably, even when server repeats the same
|
|
801
|
+
// document version across multiple publishDiagnostics notifications.
|
|
802
|
+
const diagnosticsVersion = ++this.forwardedDiagnosticsVersion;
|
|
778
803
|
|
|
779
804
|
// Pre-partition diagnostics by cell
|
|
780
805
|
const diagnosticsByCellId = new Map<CellId, LSP.Diagnostic[]>();
|
|
@@ -817,7 +842,7 @@ export class NotebookLanguageServerClient implements ILanguageServerClient {
|
|
|
817
842
|
params: {
|
|
818
843
|
...notification.params,
|
|
819
844
|
uri: cellDocumentUri,
|
|
820
|
-
version:
|
|
845
|
+
version: diagnosticsVersion,
|
|
821
846
|
diagnostics: cellDiagnostics,
|
|
822
847
|
},
|
|
823
848
|
});
|
|
@@ -832,6 +857,7 @@ export class NotebookLanguageServerClient implements ILanguageServerClient {
|
|
|
832
857
|
method: "textDocument/publishDiagnostics",
|
|
833
858
|
params: {
|
|
834
859
|
uri: cellDocumentUri,
|
|
860
|
+
version: diagnosticsVersion,
|
|
835
861
|
diagnostics: [],
|
|
836
862
|
},
|
|
837
863
|
});
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { python } from "@codemirror/lang-python";
|
|
4
4
|
import { EditorState } from "@codemirror/state";
|
|
5
5
|
import { describe, expect, test } from "vitest";
|
|
6
|
-
import
|
|
7
|
-
import type {
|
|
6
|
+
import { cellId, variableName } from "@/__tests__/branded";
|
|
7
|
+
import type { Variables } from "@/core/variables/types";
|
|
8
8
|
import { findReactiveVariables, type ReactiveVariableRange } from "../analyzer";
|
|
9
9
|
|
|
10
10
|
describe("findReactiveVariables - Lexical Scoping", () => {
|
|
@@ -1199,16 +1199,17 @@ class Foo:
|
|
|
1199
1199
|
function runHighlight(variableNames: string[], code: string): string {
|
|
1200
1200
|
const variables: Variables = {};
|
|
1201
1201
|
for (const name of variableNames) {
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1202
|
+
const varName = variableName(name);
|
|
1203
|
+
variables[varName] = {
|
|
1204
|
+
name: varName,
|
|
1205
|
+
declaredBy: [cellId("other-cell")],
|
|
1205
1206
|
usedBy: [],
|
|
1206
1207
|
value: "test-value",
|
|
1207
1208
|
dataType: "str",
|
|
1208
1209
|
};
|
|
1209
1210
|
}
|
|
1210
1211
|
const ranges = findReactiveVariables({
|
|
1211
|
-
cellId: "current-cell"
|
|
1212
|
+
cellId: cellId("current-cell"),
|
|
1212
1213
|
state: EditorState.create({
|
|
1213
1214
|
doc: code,
|
|
1214
1215
|
extensions: [python()],
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { syntaxTree } from "@codemirror/language";
|
|
4
4
|
import type { EditorState } from "@codemirror/state";
|
|
5
5
|
import type { SyntaxNode, Tree, TreeCursor } from "@lezer/common";
|
|
6
|
-
import type
|
|
6
|
+
import { type CellId, SETUP_CELL_ID } from "@/core/cells/ids";
|
|
7
7
|
import type { VariableName, Variables } from "@/core/variables/types";
|
|
8
8
|
|
|
9
9
|
export interface ReactiveVariableRange {
|
|
@@ -52,7 +52,7 @@ export function findReactiveVariables(options: {
|
|
|
52
52
|
const variable = options.variables[name as VariableName];
|
|
53
53
|
return (
|
|
54
54
|
variable.dataType !== "module" &&
|
|
55
|
-
!variable.declaredBy.includes(
|
|
55
|
+
!variable.declaredBy.includes(SETUP_CELL_ID) &&
|
|
56
56
|
!variable.declaredBy.includes(options.cellId)
|
|
57
57
|
);
|
|
58
58
|
}),
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { EditorState } from "@codemirror/state";
|
|
4
|
+
import type { EditorView } from "@codemirror/view";
|
|
5
|
+
import { LoroDoc, LoroText } from "loro-crdt";
|
|
6
|
+
import { describe, expect, it, vi } from "vitest";
|
|
7
|
+
import { LoroSyncPluginValue, loroSyncAnnotation } from "../sync";
|
|
8
|
+
|
|
9
|
+
describe("LoroSyncPluginValue", () => {
|
|
10
|
+
it("annotates the initial reconciliation dispatch as RTC sync", async () => {
|
|
11
|
+
const dispatch = vi.fn();
|
|
12
|
+
const view = {
|
|
13
|
+
state: EditorState.create({ doc: "local" }),
|
|
14
|
+
dispatch,
|
|
15
|
+
} as unknown as EditorView;
|
|
16
|
+
|
|
17
|
+
const doc = new LoroDoc();
|
|
18
|
+
const text = doc
|
|
19
|
+
.getMap("codes")
|
|
20
|
+
.getOrCreateContainer("cell-1", new LoroText());
|
|
21
|
+
text.insert(0, "remote");
|
|
22
|
+
|
|
23
|
+
const plugin = new LoroSyncPluginValue(
|
|
24
|
+
view,
|
|
25
|
+
doc,
|
|
26
|
+
["codes", "cell-1"],
|
|
27
|
+
() => text,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
await Promise.resolve();
|
|
31
|
+
|
|
32
|
+
expect(dispatch).toHaveBeenCalledTimes(1);
|
|
33
|
+
expect(dispatch).toHaveBeenCalledWith(
|
|
34
|
+
expect.objectContaining({
|
|
35
|
+
changes: [
|
|
36
|
+
{
|
|
37
|
+
from: 0,
|
|
38
|
+
to: view.state.doc.length,
|
|
39
|
+
insert: "remote",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
annotations: [
|
|
43
|
+
expect.objectContaining({
|
|
44
|
+
type: loroSyncAnnotation,
|
|
45
|
+
}),
|
|
46
|
+
],
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
plugin.destroy();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
3
|
+
import { variableName } from "@/__tests__/branded";
|
|
3
4
|
import type { DataTable } from "@/core/kernel/messages";
|
|
4
5
|
import type { VariableName } from "@/core/variables/types";
|
|
5
6
|
import {
|
|
@@ -182,7 +183,7 @@ describe("filtering data sources", () => {
|
|
|
182
183
|
});
|
|
183
184
|
|
|
184
185
|
it("keeps matching variables and internal engines", () => {
|
|
185
|
-
const filtered = filterDataSources(["conn1"
|
|
186
|
+
const filtered = filterDataSources([variableName("conn1")]);
|
|
186
187
|
expect(filtered.connectionsMap.size).toBe(defaultConnSize + 1);
|
|
187
188
|
expect(filtered.connectionsMap.has("conn1" as ConnectionName)).toBe(true);
|
|
188
189
|
for (const engine of INTERNAL_SQL_ENGINES) {
|
|
@@ -191,16 +192,14 @@ describe("filtering data sources", () => {
|
|
|
191
192
|
});
|
|
192
193
|
|
|
193
194
|
it("filters out non-matching variables", () => {
|
|
194
|
-
const filtered = filterDataSources([
|
|
195
|
-
"non_existent" as unknown as VariableName,
|
|
196
|
-
]);
|
|
195
|
+
const filtered = filterDataSources([variableName("non_existent")]);
|
|
197
196
|
expect(filtered.connectionsMap.size).toBe(defaultConnSize);
|
|
198
197
|
});
|
|
199
198
|
|
|
200
199
|
it("handles mix of matching and non-matching variables", () => {
|
|
201
200
|
const filtered = filterDataSources([
|
|
202
|
-
"conn1"
|
|
203
|
-
"non_existent"
|
|
201
|
+
variableName("conn1"),
|
|
202
|
+
variableName("non_existent"),
|
|
204
203
|
]);
|
|
205
204
|
expect(filtered.connectionsMap.size).toBe(defaultConnSize + 1);
|
|
206
205
|
expect(filtered.connectionsMap.has("conn1" as ConnectionName)).toBe(true);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { cellId } from "@/__tests__/branded";
|
|
3
4
|
import type { MarimoError } from "@/core/kernel/messages";
|
|
4
5
|
import { getAutoFixes, getImportCode } from "../errors";
|
|
5
6
|
|
|
@@ -25,7 +26,7 @@ describe("getAutoFixes", () => {
|
|
|
25
26
|
const error: MarimoError = {
|
|
26
27
|
type: "multiple-defs",
|
|
27
28
|
name: "foo",
|
|
28
|
-
cells: ["foo"],
|
|
29
|
+
cells: [cellId("foo")],
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
const fixes = getAutoFixes(error, opts);
|