From 910239dd08e1ee9c9c0bd41dd0d3dfec55b1f412 Mon Sep 17 00:00:00 2001 From: "Ekaterina.Itsenko" Date: Wed, 8 Jul 2026 12:51:21 +0200 Subject: [PATCH] [pycharm] PY-90736 Jupyter: add Marimo plugin promotion (cherry picked from commit 399a22c7931f5983b1a719a7d66524b69e6bbb1b) GitOrigin-RevId: 3760dcfccabb04e576836963561f2dbbbcec05d1 --- .../intellij.python.community.impl.xml | 1 + .../messages/PyBundle.properties | 1 + .../suggestions/MarimoSuggestionProvider.kt | 43 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 python/src/com/jetbrains/python/suggestions/MarimoSuggestionProvider.kt diff --git a/python/pluginResources/intellij.python.community.impl.xml b/python/pluginResources/intellij.python.community.impl.xml index b1c10ed7e045..ded6a95d6b3d 100644 --- a/python/pluginResources/intellij.python.community.impl.xml +++ b/python/pluginResources/intellij.python.community.impl.xml @@ -162,6 +162,7 @@ + diff --git a/python/pluginResources/messages/PyBundle.properties b/python/pluginResources/messages/PyBundle.properties index 2b8fcc753de5..090ae277f17b 100644 --- a/python/pluginResources/messages/PyBundle.properties +++ b/python/pluginResources/messages/PyBundle.properties @@ -1627,6 +1627,7 @@ advertiser.python.dap.plugin.enable.text=Enable Plugin debugger.dap.plugin.install.got.it.header=Try the Python DAP Debugger plugin debugger.dap.plugin.install.got.it.text=Install the Python DAP Debugger plugin for faster and more reliable Python debugging with debugpy debugger.dap.plugin.enable.got.it.text=Enable the Python DAP Debugger plugin for faster and more reliable Python debugging with debugpy +advertiser.marimo.plugin.suggestion.text=Open and run marimo reactive notebooks by installing the marimo plugin. action.PyInstallPackage.text=Install action.PyInstallPackageAction.text=Advanced Package Install\u2026 diff --git a/python/src/com/jetbrains/python/suggestions/MarimoSuggestionProvider.kt b/python/src/com/jetbrains/python/suggestions/MarimoSuggestionProvider.kt new file mode 100644 index 000000000000..c1a90107f2f9 --- /dev/null +++ b/python/src/com/jetbrains/python/suggestions/MarimoSuggestionProvider.kt @@ -0,0 +1,43 @@ +// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.jetbrains.python.suggestions + +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.FileIndexFacade +import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginSuggestion +import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginSuggestionProvider +import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.buildSuggestionIfNeeded +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiManager +import com.jetbrains.python.PyBundle +import com.jetbrains.python.PythonFileType +import com.jetbrains.python.psi.PyFile +import com.jetbrains.python.pyi.PyiFile + +private const val MARIMO_PLUGIN_ID: String = "io.marimo.notebook" +private const val MARIMO_PLUGIN_NAME: String = "marimo" +private const val MARIMO_PLUGIN_SUGGESTION_DISMISSED_KEY: String = "marimo.plugin.suggestion.dismissed" + +internal class MarimoSuggestionProvider : PluginSuggestionProvider { + override fun getSuggestion(project: Project, file: VirtualFile): PluginSuggestion? { + if (file.fileType != PythonFileType.INSTANCE || FileIndexFacade.getInstance(project).isInLibraryClasses(file)) { + return null + } + + val psiFile = PsiManager.getInstance(project).findFile(file) + if (psiFile == null || psiFile is PyiFile || psiFile !is PyFile || !psiFile.importsMarimo()) return null + + return buildSuggestionIfNeeded( + project, + pluginIds = listOf(MARIMO_PLUGIN_ID), + pluginName = MARIMO_PLUGIN_NAME, + suggestionText = PyBundle.message("advertiser.marimo.plugin.suggestion.text"), + suggestionDismissKey = MARIMO_PLUGIN_SUGGESTION_DISMISSED_KEY, + ) + } + + private fun PyFile.importsMarimo(): Boolean { + val imports = fromImports.mapNotNull { it.importSourceQName?.firstComponent } + + importTargets.mapNotNull { it.importedQName?.firstComponent } + return imports.contains("marimo") + } +} \ No newline at end of file