IJPL-245430 move bookmark integrations to optional modules

Language Server products intentionally do not include the platform bookmarks plugin. After bookmarks were pluginized, Java and VCS Log still had direct dependencies on bookmark implementation modules, which could exclude Java Core during plugin set resolution.

Move the Java package and VCS Log bookmark providers into optional content modules loaded only with the relevant plugins, while keeping a small VCS Log support extension point in the core module. This preserves bookmark behavior when the bookmarks plugin is present without forcing bookmarks into products that exclude it.

IJ-MR-184958 IJ-MR-184993 IJ-MR-179029 IJ-MR-184126 IJ-MR-181153 IJ-MR-146078 IJ-MR-175479 IJ-MR-186058 IJ-MR-193195 IJ-MR-196957 IJ-MR-199124 IJ-MR-197441 IJ-MR-204135 IJ-MR-204674

GitOrigin-RevId: f6bad861b518b5a6cdbaeed0e133c94041821b6d
This commit is contained in:
Vladimir Krivosheev
2026-05-28 16:51:57 +00:00
committed by intellij-monorepo-bot
parent ef17f89f1a
commit 53068bf8e9
31 changed files with 332 additions and 69 deletions
+2
View File
@@ -617,6 +617,7 @@
<module fileurl="file://$PROJECT_DIR$/java/java-analysis-api/intellij.java.analysis.iml" filepath="$PROJECT_DIR$/java/java-analysis-api/intellij.java.analysis.iml" />
<module fileurl="file://$PROJECT_DIR$/java/java-analysis-impl/intellij.java.analysis.impl.iml" filepath="$PROJECT_DIR$/java/java-analysis-impl/intellij.java.analysis.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/java/java-backend/intellij.java.backend.iml" filepath="$PROJECT_DIR$/java/java-backend/intellij.java.backend.iml" />
<module fileurl="file://$PROJECT_DIR$/java/java-bookmarks/intellij.java.bookmarks.iml" filepath="$PROJECT_DIR$/java/java-bookmarks/intellij.java.bookmarks.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/ByteCodeViewer/intellij.java.byteCodeViewer.iml" filepath="$PROJECT_DIR$/plugins/ByteCodeViewer/intellij.java.byteCodeViewer.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/ByteCodeViewer/intellij.java.byteCodeViewer.tests.iml" filepath="$PROJECT_DIR$/plugins/ByteCodeViewer/intellij.java.byteCodeViewer.tests.iml" />
<module fileurl="file://$PROJECT_DIR$/java/codeserver/core/intellij.java.codeserver.core.iml" filepath="$PROJECT_DIR$/java/codeserver/core/intellij.java.codeserver.core.iml" />
@@ -1716,6 +1717,7 @@
<module fileurl="file://$PROJECT_DIR$/platform/vcs-log/graph/intellij.platform.vcs.log.graph.impl.iml" filepath="$PROJECT_DIR$/platform/vcs-log/graph/intellij.platform.vcs.log.graph.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/vcs-log/graph/intellij.platform.vcs.log.graph.impl.tests.iml" filepath="$PROJECT_DIR$/platform/vcs-log/graph/intellij.platform.vcs.log.graph.impl.tests.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/vcs-log/impl/intellij.platform.vcs.log.impl.iml" filepath="$PROJECT_DIR$/platform/vcs-log/impl/intellij.platform.vcs.log.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/vcs-log/impl/bookmarks/intellij.platform.vcs.log.impl.bookmarks.iml" filepath="$PROJECT_DIR$/platform/vcs-log/impl/bookmarks/intellij.platform.vcs.log.impl.bookmarks.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/vcs-log/impl/intellij.platform.vcs.log.impl.tests.iml" filepath="$PROJECT_DIR$/platform/vcs-log/impl/intellij.platform.vcs.log.impl.tests.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/vcs-api/shared/intellij.platform.vcs.shared.iml" filepath="$PROJECT_DIR$/platform/vcs-api/shared/intellij.platform.vcs.shared.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/vcs-tests/intellij.platform.vcs.testFramework.iml" filepath="$PROJECT_DIR$/platform/vcs-tests/intellij.platform.vcs.testFramework.iml" />
+2
View File
@@ -296,6 +296,7 @@ java/idea-ui
java/java-analysis-api
java/java-analysis-impl
java/java-backend
java/java-bookmarks
java/java-copyright
java/java-features-trainer
java/java-frontback-impl
@@ -916,6 +917,7 @@ platform/vcs-log/api
platform/vcs-log/graph
platform/vcs-log/graph-api
platform/vcs-log/impl
platform/vcs-log/impl/bookmarks
platform/vcs-tests
platform/warmup
platform/warmup/performanceTesting
@@ -860,7 +860,6 @@
<saveFileAsTemplateHandler implementation="com.intellij.ide.fileTemplates.SaveJavaAsTemplateHandler"/>
<packageDependencies.visitor language="JAVA" implementationClass="com.intellij.packageDependencies.JavaDependencyVisitorFactory"/>
<pathMacroFilter implementation="com.intellij.execution.configuration.JavaRunConfigurationPathMacroFilter"/>
<bookmarkProvider implementation="com.intellij.ide.bookmark.providers.PackageBookmarkProvider"/>
<favoriteNodeProvider implementation="com.intellij.ide.favoritesTreeView.PsiPackageFavoriteNodeProvider"/>
<favoriteNodeProvider implementation="com.intellij.ide.favoritesTreeView.PsiMethodFavoriteNodeProvider"/>
<favoriteNodeProvider implementation="com.intellij.ide.favoritesTreeView.PsiFieldFavoriteNodeProvider"/>
+53
View File
@@ -0,0 +1,53 @@
### auto-generated section `build intellij.java.bookmarks` start
load("@rules_jvm//:jvm.bzl", "jvm_library")
jvm_library(
name = "bookmarks",
module_name = "intellij.java.bookmarks",
visibility = ["//visibility:public"],
srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form"], allow_empty = True),
resources = glob(["resources/**/*"]),
resource_strip_prefix = "resources",
deps = [
"//platform/bookmarks",
"//platform/core-api:core",
"//platform/core-impl",
"//platform/editor-ui-api:editor-ui",
"//platform/lang-api:lang",
"//platform/lang-impl",
"//platform/projectModel-api:projectModel",
"//platform/util",
"//platform/util:util-ui",
"//java/java-impl:impl",
"//java/java-psi-api:psi",
]
)
jvm_library(
name = "bookmarks_test_lib",
testonly = True,
module_name = "intellij.java.bookmarks",
visibility = ["//visibility:public"],
srcs = glob([], allow_empty = True),
runtime_deps = [
":bookmarks",
"//platform/bookmarks:bookmarks_test_lib",
"//platform/core-api:core_test_lib",
"//platform/core-impl:core-impl_test_lib",
"//platform/editor-ui-api:editor-ui_test_lib",
"//platform/lang-api:lang_test_lib",
"//platform/lang-impl:lang-impl_test_lib",
"//platform/projectModel-api:projectModel_test_lib",
"//platform/util:util_test_lib",
"//platform/util:util-ui_test_lib",
"//java/java-impl:impl_test_lib",
"//java/java-psi-api:psi_test_lib",
]
)
### auto-generated section `build intellij.java.bookmarks` end
### auto-generated section `iml intellij.java.bookmarks` start
exports_files([
"intellij.java.bookmarks.iml",
], visibility = ["//visibility:public"])
### auto-generated section `iml intellij.java.bookmarks` end
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="5" platform="JVM 25" allPlatforms="JVM [25]" useProjectSettings="false">
<compilerSettings>
<option name="additionalArguments" value="-Xjvm-default=all -XXLanguage:+AllowEagerSupertypeAccessibilityChecks -progressive" />
</compilerSettings>
<compilerArguments>
<stringArguments>
<stringArg name="jvmTarget" arg="25" />
<stringArg name="apiVersion" arg="2.3" />
<stringArg name="languageVersion" arg="2.3" />
</stringArguments>
<arrayArguments>
<arrayArg name="pluginClasspaths">
<args>$KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar</args>
</arrayArg>
</arrayArguments>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="intellij.platform.bookmarks" />
<orderEntry type="module" module-name="intellij.platform.core" />
<orderEntry type="module" module-name="intellij.platform.core.impl" />
<orderEntry type="module" module-name="intellij.platform.editor.ui" />
<orderEntry type="module" module-name="intellij.platform.lang" />
<orderEntry type="module" module-name="intellij.platform.lang.impl" />
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="module" module-name="intellij.platform.util" />
<orderEntry type="module" module-name="intellij.platform.util.ui" />
<orderEntry type="module" module-name="intellij.java.impl" />
<orderEntry type="module" module-name="intellij.java.psi" />
</component>
</module>
@@ -0,0 +1,13 @@
<idea-plugin package="com.intellij.java.bookmarks">
<!-- region Generated dependencies - run `Generate Product Layouts` to regenerate -->
<dependencies>
<module name="intellij.java.impl"/>
<module name="intellij.java.psi"/>
<module name="intellij.platform.bookmarks"/>
</dependencies>
<!-- endregion -->
<extensions defaultExtensionNs="com.intellij">
<bookmarkProvider implementation="com.intellij.java.bookmarks.PackageBookmarkProvider"/>
</extensions>
</idea-plugin>
@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.bookmark.providers
package com.intellij.java.bookmarks
import com.intellij.ide.bookmark.Bookmark
import com.intellij.ide.projectView.impl.nodes.PackageElement
@@ -1,12 +1,11 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.bookmark.providers
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.bookmarks
import com.intellij.ide.bookmark.Bookmark
import com.intellij.ide.bookmark.BookmarkProvider
import com.intellij.ide.projectView.impl.nodes.PackageElement
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.JavaPsiFacade
@@ -17,9 +16,6 @@ internal class PackageBookmarkProvider(private val project: Project) : BookmarkP
internal val moduleManager: ModuleManager?
get() = if (project.isDisposed) null else ModuleManager.getInstance(project)
internal val projectSettingsService: ProjectSettingsService?
get() = if (project.isDisposed) null else ProjectSettingsService.getInstance(project)
override fun compare(bookmark1: Bookmark, bookmark2: Bookmark): Int {
bookmark1 as PackageBookmark
bookmark2 as PackageBookmark
@@ -1,5 +1,5 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.bookmark.providers
package com.intellij.java.bookmarks
import com.intellij.ide.bookmark.ui.tree.BookmarkNode
import com.intellij.ide.projectView.PresentationData
-3
View File
@@ -97,7 +97,6 @@ jvm_library(
"//libraries/markdown",
"//platform/threadDumpParser",
"//platform/eel-provider",
"//platform/bookmarks",
"//platform/todo",
"//java/codeserver/highlighting",
"//java/codeserver/core",
@@ -285,8 +284,6 @@ jvm_library(
"//platform/threadDumpParser:threadDumpParser_test_lib",
"//platform/eel-provider",
"//platform/eel-provider:eel-provider_test_lib",
"//platform/bookmarks",
"//platform/bookmarks:bookmarks_test_lib",
"//platform/todo",
"//platform/todo:todo_test_lib",
"//java/codeserver/highlighting",
-1
View File
@@ -132,7 +132,6 @@
<orderEntry type="module" module-name="intellij.libraries.markdown" />
<orderEntry type="module" module-name="intellij.platform.threadDumpParser" />
<orderEntry type="module" module-name="intellij.platform.eel.provider" />
<orderEntry type="module" module-name="intellij.platform.bookmarks" />
<orderEntry type="module" module-name="intellij.platform.todo" />
<orderEntry type="module" module-name="intellij.java.codeserver.highlighting" />
<orderEntry type="module" module-name="intellij.java.codeserver.core" />
@@ -8,7 +8,6 @@
<module name="intellij.regexp"/>
<module name="intellij.platform.externalSystem"/>
<module name="intellij.platform.externalSystem.impl"/>
<module name="intellij.platform.bookmarks.backend"/>
<module name="intellij.platform.todo.backend"/>
<module name="intellij.platform.backend"/>
<module name="intellij.java.frontback.impl"/>
@@ -26,7 +25,6 @@
<module name="intellij.java.structureView"/>
<module name="intellij.jsp"/>
<module name="intellij.jsp.spi"/>
<module name="intellij.platform.bookmarks"/>
<module name="intellij.platform.structureView.impl"/>
<module name="intellij.platform.todo"/>
<module name="intellij.spellchecker"/>
+1
View File
@@ -18,6 +18,7 @@
- name: intellij.java.psi
- name: intellij.java.psi.impl
- name: intellij.java.frontback.impl
- name: intellij.java.bookmarks
- name: intellij.platform.jps.build.javac.rt
- name: intellij.java.guiForms.compiler
- name: intellij.java.compiler.antTasks
@@ -45,6 +45,7 @@
<module name="intellij.java.structureView" required-if-available="intellij.platform.backend"/>
<module name="intellij.java.impl" required-if-available="intellij.platform.backend"/>
<module name="intellij.java.bookmarks" loading="optional"/>
<module name="intellij.java.impl.refactorings" required-if-available="intellij.platform.backend"/>
<module name="intellij.java.compiler.impl" required-if-available="intellij.platform.backend"/>
<module name="intellij.java.typeMigration" required-if-available="intellij.platform.backend"/>
@@ -1,6 +1,9 @@
- name: lib/modules/intellij.platform.bookmarks.jar
contentModules:
- name: intellij.platform.bookmarks
- name: lib/modules/intellij.platform.vcs.log.impl.bookmarks.jar
contentModules:
- name: intellij.platform.vcs.log.impl.bookmarks
- name: lib/platform-bookmarks-plugin.jar
modules:
- name: intellij.platform.bookmarks.plugin
@@ -11,5 +11,6 @@
<module name="intellij.platform.bookmarks.frontend"/>
<module name="intellij.platform.debugger.impl.bookmarks"/>
<module name="intellij.platform.frontend.split.bookmarks"/>
<module name="intellij.platform.vcs.log.impl.bookmarks" loading="optional"/>
</content>
</idea-plugin>
@@ -53,7 +53,7 @@
<projectSettings service="com.intellij.ide.bookmarks.BookmarkManager"/>
</extensions>
<actions>
<actions resource-bundle="messages.ActionsBundle">
<group id="Bookmarks" popup="true">
<action id="AddAnotherBookmark" class="com.intellij.ide.bookmark.actions.AddAnotherBookmarkAction"/>
<action id="EditBookmark" icon="AllIcons.Actions.Edit"
-2
View File
@@ -53,7 +53,6 @@ jvm_library(
"//platform/util/coroutines",
"//platform/util/storages",
"//platform/vcs-impl/shared",
"//platform/bookmarks",
"//libraries/kotlinx/collections-immutable:libraries-kotlinx-collections-immutable",
"//platform/util:util-ui",
]
@@ -121,7 +120,6 @@ jvm_library(
"//platform/vcs-impl/shared:shared_test_lib",
"//libraries/mockito",
"//libraries/mockito:mockito_test_lib",
"//platform/bookmarks:bookmarks_test_lib",
"//libraries/kotlinx/collections-immutable:libraries-kotlinx-collections-immutable_test_lib",
"//platform/util:util-ui_test_lib",
]
@@ -0,0 +1,63 @@
### auto-generated section `build intellij.platform.vcs.log.impl.bookmarks` start
load("@rules_jvm//:jvm.bzl", "jvm_library")
jvm_library(
name = "bookmarks",
module_name = "intellij.platform.vcs.log.impl.bookmarks",
visibility = ["//visibility:public"],
srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form"], allow_empty = True),
resources = glob(["resources/**/*"]),
resource_strip_prefix = "resources",
deps = [
"//platform/analysis-api:analysis",
"//platform/bookmarks",
"//platform/core-api:core",
"//platform/core-impl",
"//platform/core-ui",
"//platform/editor-ui-api:editor-ui",
"//platform/ide-core",
"//platform/lang-api:lang",
"//platform/projectModel-api:projectModel",
"//platform/util",
"//platform/util:util-ui",
"//platform/vcs-impl",
"//platform/vcs-impl/shared",
"//platform/vcs-log/api:vcs-log",
"//platform/vcs-log/impl",
"//platform/vcs-api/shared",
]
)
jvm_library(
name = "bookmarks_test_lib",
testonly = True,
module_name = "intellij.platform.vcs.log.impl.bookmarks",
visibility = ["//visibility:public"],
srcs = glob([], allow_empty = True),
runtime_deps = [
":bookmarks",
"//platform/analysis-api:analysis_test_lib",
"//platform/bookmarks:bookmarks_test_lib",
"//platform/core-api:core_test_lib",
"//platform/core-impl:core-impl_test_lib",
"//platform/core-ui:core-ui_test_lib",
"//platform/editor-ui-api:editor-ui_test_lib",
"//platform/ide-core:ide-core_test_lib",
"//platform/lang-api:lang_test_lib",
"//platform/projectModel-api:projectModel_test_lib",
"//platform/util:util_test_lib",
"//platform/util:util-ui_test_lib",
"//platform/vcs-impl:vcs-impl_test_lib",
"//platform/vcs-impl/shared:shared_test_lib",
"//platform/vcs-log/api:vcs-log_test_lib",
"//platform/vcs-log/impl:impl_test_lib",
"//platform/vcs-api/shared:shared_test_lib",
]
)
### auto-generated section `build intellij.platform.vcs.log.impl.bookmarks` end
### auto-generated section `iml intellij.platform.vcs.log.impl.bookmarks` start
exports_files([
"intellij.platform.vcs.log.impl.bookmarks.iml",
], visibility = ["//visibility:public"])
### auto-generated section `iml intellij.platform.vcs.log.impl.bookmarks` end
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="5" platform="JVM 25" allPlatforms="JVM [25]" useProjectSettings="false">
<compilerSettings>
<option name="additionalArguments" value="-Xjvm-default=all -XXLanguage:+AllowEagerSupertypeAccessibilityChecks -progressive" />
</compilerSettings>
<compilerArguments>
<stringArguments>
<stringArg name="jvmTarget" arg="25" />
<stringArg name="apiVersion" arg="2.3" />
<stringArg name="languageVersion" arg="2.3" />
</stringArguments>
<arrayArguments>
<arrayArg name="pluginClasspaths">
<args>$KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar</args>
</arrayArg>
</arrayArguments>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="intellij.platform.analysis" />
<orderEntry type="module" module-name="intellij.platform.bookmarks" />
<orderEntry type="module" module-name="intellij.platform.core" />
<orderEntry type="module" module-name="intellij.platform.core.impl" />
<orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="module" module-name="intellij.platform.editor.ui" />
<orderEntry type="module" module-name="intellij.platform.ide.core" />
<orderEntry type="module" module-name="intellij.platform.lang" />
<orderEntry type="module" module-name="intellij.platform.projectModel" />
<orderEntry type="module" module-name="intellij.platform.util" />
<orderEntry type="module" module-name="intellij.platform.util.ui" />
<orderEntry type="module" module-name="intellij.platform.vcs.impl" />
<orderEntry type="module" module-name="intellij.platform.vcs.impl.shared" />
<orderEntry type="module" module-name="intellij.platform.vcs.log" />
<orderEntry type="module" module-name="intellij.platform.vcs.log.impl" />
<orderEntry type="module" module-name="intellij.platform.vcs.shared" />
</component>
</module>
@@ -0,0 +1,31 @@
<idea-plugin>
<!-- region Generated dependencies - run `Generate Product Layouts` to regenerate -->
<dependencies>
<module name="intellij.platform.analysis"/>
<module name="intellij.platform.bookmarks"/>
<module name="intellij.platform.core"/>
<module name="intellij.platform.core.impl"/>
<module name="intellij.platform.core.ui"/>
<module name="intellij.platform.editor.ui"/>
<module name="intellij.platform.ide.core"/>
<module name="intellij.platform.lang"/>
<module name="intellij.platform.projectModel"/>
<module name="intellij.platform.util.ui"/>
<module name="intellij.platform.vcs.impl"/>
<module name="intellij.platform.vcs.impl.shared"/>
<module name="intellij.platform.vcs.log"/>
<module name="intellij.platform.vcs.log.impl"/>
<module name="intellij.platform.vcs.shared"/>
</dependencies>
<!-- endregion -->
<extensions defaultExtensionNs="com.intellij">
<vcs.log.bookmarkSupport implementation="com.intellij.platform.vcs.log.impl.bookmarks.VcsLogBookmarkSupportImpl"/>
<bookmarkProvider implementation="com.intellij.platform.vcs.log.impl.bookmarks.VcsLogBookmarkProvider"/>
</extensions>
<projectListeners>
<listener class="com.intellij.platform.vcs.log.impl.bookmarks.VcsLogBookmarksManagerListener"
topic="com.intellij.ide.bookmark.BookmarksListener"/>
</projectListeners>
</idea-plugin>
@@ -1,5 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.vcs.log.ui
package com.intellij.platform.vcs.log.impl.bookmarks
import com.intellij.ide.bookmark.Bookmark
import com.intellij.ide.bookmark.BookmarkGroup
@@ -10,15 +10,12 @@ import com.intellij.ide.bookmark.BookmarksManager
import com.intellij.ide.bookmark.ui.tree.BookmarkNode
import com.intellij.ide.projectView.PresentationData
import com.intellij.ide.util.treeView.AbstractTreeNode
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vcs.VcsNotifier
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.ui.SimpleTextAttributes
import com.intellij.util.messages.Topic
import com.intellij.vcs.log.CommitId
import com.intellij.vcs.log.Hash
import com.intellij.vcs.log.VcsLogBundle
@@ -26,9 +23,10 @@ import com.intellij.vcs.log.data.LoadingDetails
import com.intellij.vcs.log.impl.HashImpl
import com.intellij.vcs.log.impl.VcsLogNavigationUtil
import com.intellij.vcs.log.impl.VcsProjectLog
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.Nls
import java.util.EventListener
import com.intellij.vcs.log.ui.VcsBookmarkRef
import com.intellij.vcs.log.ui.VcsLogBookmarkSupport
import com.intellij.vcs.log.ui.VcsLogBookmarksListener
import com.intellij.vcs.log.ui.VcsLogNotificationIdsHolder
import java.util.Objects
private const val ROOT_KEY = "root"
@@ -53,9 +51,7 @@ internal class VcsLogBookmarkProvider(private val project: Project) : BookmarkPr
}
override fun createBookmark(context: Any?): Bookmark? = when (context) {
is CommitId -> {
VcsLogBookmark(this, context.root, context.hash)
}
is CommitId -> VcsLogBookmark(this, context.root, context.hash)
else -> null
}
}
@@ -72,11 +68,11 @@ internal class VcsLogBookmark(override val provider: VcsLogBookmarkProvider,
override fun canNavigate(): Boolean = true
override fun canNavigateToSource(): Boolean = false
override fun navigate(requestFocus: Boolean) {
VcsLogNavigationUtil.jumpToRevisionAsync(provider.project, root, hash).whenComplete { result: Boolean?, error ->
VcsLogNavigationUtil.jumpToRevisionAsync(provider.project, root, hash).whenComplete { result: Boolean?, _ ->
if (result != true) {
val commitPresentation = VcsLogBundle.message("vcs.log.commit.prefix", hash)
val message = VcsLogBundle.message("vcs.log.commit.not.found", commitPresentation)
VcsNotifier.getInstance(provider.project).notifyWarning(VcsLogNotificationIdsHolder.COMMIT_NOT_FOUND, "", message);
VcsNotifier.getInstance(provider.project).notifyWarning(VcsLogNotificationIdsHolder.COMMIT_NOT_FOUND, "", message)
}
}
}
@@ -129,16 +125,8 @@ private fun getDefaultBookmarkDescription(project: Project, root: VirtualFile, h
return details.subject.ifBlank { VcsLogBundle.message("vcs.log.bookmark.description.empty.subject") }
}
@Service(Service.Level.PROJECT)
internal class VcsLogBookmarkReferenceProvider(val project: Project) {
companion object {
@JvmStatic
fun getBookmarkRefs(project: Project, hash: Hash, root: VirtualFile): List<VcsBookmarkRef> {
return project.service<VcsLogBookmarkReferenceProvider>().getBookmarkRefs(hash, root)
}
}
fun getBookmarkRefs(hash: Hash, root: VirtualFile): List<VcsBookmarkRef> {
internal class VcsLogBookmarkSupportImpl : VcsLogBookmarkSupport {
override fun getRefs(project: Project, hash: Hash, root: VirtualFile): List<VcsBookmarkRef> {
val bookmarksManager = BookmarksManager.getInstance(project) ?: return emptyList()
return bookmarksManager.bookmarks
.filterIsInstance<VcsLogBookmark>()
@@ -154,7 +142,7 @@ internal class VcsLogBookmarkReferenceProvider(val project: Project) {
}
}
internal class VcsLogBookmarksManagerListener(val project: Project) : BookmarksListener {
internal class VcsLogBookmarksManagerListener(private val project: Project) : BookmarksListener {
private fun updateBookmark(bookmark: Bookmark) {
if (bookmark is VcsLogBookmark) {
project.messageBus.syncPublisher(VcsLogBookmarksListener.TOPIC).logBookmarksChanged()
@@ -177,19 +165,3 @@ internal class VcsLogBookmarksManagerListener(val project: Project) : BookmarksL
updateBookmark(bookmark)
}
}
@ApiStatus.Internal
class VcsBookmarkRef(val bookmark: Bookmark, val type: BookmarkType, val text: @Nls String)
internal interface VcsLogBookmarksListener : EventListener {
companion object {
@JvmField
@Topic.AppLevel
val TOPIC = Topic(VcsLogBookmarksListener::class.java, Topic.BroadcastDirection.NONE)
}
/**
* Allows notifying VCS Log that the [VcsLogBookmarkReferenceProvider.getBookmarkRefs] might have changed.
*/
fun logBookmarksChanged() = Unit
}
@@ -59,7 +59,6 @@
<orderEntry type="module" module-name="intellij.platform.util.io.storages" />
<orderEntry type="module" module-name="intellij.platform.vcs.impl.shared" />
<orderEntry type="module" module-name="intellij.libraries.mockito" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.bookmarks" />
<orderEntry type="module" module-name="intellij.libraries.kotlinx.collections.immutable" />
<orderEntry type="module" module-name="intellij.platform.util.ui" />
</component>
@@ -11,7 +11,6 @@
<module name="intellij.libraries.opentelemetry.semconv"/>
<module name="intellij.platform.analysis"/>
<module name="intellij.platform.analysis.impl"/>
<module name="intellij.platform.bookmarks"/>
<module name="intellij.platform.core"/>
<module name="intellij.platform.core.impl"/>
<module name="intellij.platform.core.ui"/>
@@ -60,6 +59,9 @@
<extensionPoint name="vcsLogRefreshActionListener"
interface="com.intellij.vcs.log.ui.actions.VcsLogRefreshActionListener"
dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.vcs.log.bookmarkSupport"
interface="com.intellij.vcs.log.ui.VcsLogBookmarkSupport"
dynamic="true"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
@@ -142,8 +144,6 @@
<editorTabTitleProvider implementation="com.intellij.vcs.log.ui.editor.DefaultVcsLogFileTabTitleProvider"/>
<openTelemetryExporterProvider implementation="com.intellij.vcs.log.statistics.VcsLogTelemetryExporter"/>
<bookmarkProvider implementation="com.intellij.vcs.log.ui.VcsLogBookmarkProvider"/>
<registryKey key="vcs.log.table.show.centered"
defaultValue="true"
description="Handles scrolling to the selected commit in the VCS log table. If true, the selected commit will be centered. If false, it will be on the bottom of the table."/>."
@@ -161,8 +161,6 @@
<projectListeners>
<listener topic="com.intellij.openapi.wm.ex.ToolWindowManagerListener"
class="com.intellij.vcs.log.impl.VcsLogToolwindowManagerListener"/>
<listener class="com.intellij.vcs.log.ui.VcsLogBookmarksManagerListener"
topic="com.intellij.ide.bookmark.BookmarksListener"/>
</projectListeners>
<actions resource-bundle="messages.VcsLogBundle">
@@ -413,4 +411,3 @@
</group>
</actions>
</idea-plugin>
@@ -0,0 +1,44 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.vcs.log.ui
import com.intellij.ide.bookmark.Bookmark
import com.intellij.ide.bookmark.BookmarkType
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.messages.Topic
import com.intellij.vcs.log.Hash
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.Nls
import java.util.EventListener
@ApiStatus.Internal
interface VcsLogBookmarkSupport {
fun getRefs(project: Project, hash: Hash, root: VirtualFile): List<VcsBookmarkRef>
companion object {
private val EP = ExtensionPointName.create<VcsLogBookmarkSupport>("com.intellij.vcs.log.bookmarkSupport")
@JvmStatic
fun getBookmarkRefs(project: Project, hash: Hash, root: VirtualFile): List<VcsBookmarkRef> {
return EP.extensionList.flatMap { it.getRefs(project, hash, root) }
}
}
}
@ApiStatus.Internal
class VcsBookmarkRef(val bookmark: Bookmark, val type: BookmarkType, val text: @Nls String)
@ApiStatus.Internal
interface VcsLogBookmarksListener : EventListener {
companion object {
@JvmField
@Topic.AppLevel
val TOPIC: Topic<VcsLogBookmarksListener> = Topic(VcsLogBookmarksListener::class.java, Topic.BroadcastDirection.NONE)
}
/**
* Allows notifying VCS Log that the [VcsLogBookmarkSupport.getBookmarkRefs] might have changed.
*/
fun logBookmarksChanged(): Unit = Unit
}
@@ -18,7 +18,7 @@ import com.intellij.vcs.log.impl.CommonUiProperties
import com.intellij.vcs.log.impl.onPropertyChange
import com.intellij.vcs.log.paint.GraphCellPainter
import com.intellij.vcs.log.paint.SimpleGraphCellPainter
import com.intellij.vcs.log.ui.VcsLogBookmarkReferenceProvider.Companion.getBookmarkRefs
import com.intellij.vcs.log.ui.VcsLogBookmarkSupport
import com.intellij.vcs.log.ui.VcsLogBookmarksListener
import com.intellij.vcs.log.ui.frame.CommitPresentationUtil
import com.intellij.vcs.log.ui.render.GraphCommitCell
@@ -44,7 +44,7 @@ internal fun getDefaultDynamicColumns() = listOf<VcsLogDefaultColumn<*>>(Author,
@ApiStatus.Internal
sealed class VcsLogDefaultColumn<T>(
@NonNls override val id: String,
@param:NonNls override val id: String,
override val localizedName: @Nls String,
override val isDynamic: Boolean = true,
) : VcsLogColumn<T> {
@@ -96,7 +96,7 @@ object Commit : VcsLogDefaultColumn<GraphCommitCell>("Default.Subject", VcsLogBu
commitId,
getValue(model, metadata),
model.getRefsAtRow(row),
if (metadata !is LoadingDetails) getBookmarkRefs(model.logData.project, metadata.id, metadata.root) else emptyList(),
if (metadata !is LoadingDetails) VcsLogBookmarkSupport.getBookmarkRefs(model.logData.project, metadata.id, metadata.root) else emptyList(),
printElements,
metadata is LoadingDetails
)
@@ -52,4 +52,4 @@
<orderEntry type="module" module-name="intellij.platform.util" />
<orderEntry type="module" module-name="intellij.platform.util.ui" />
</component>
</module>
</module>
@@ -28,6 +28,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.PropertyKey
import java.util.concurrent.atomic.AtomicBoolean
import javax.swing.JComponent
@@ -199,6 +200,7 @@ internal class BreakpointListProvider(private val project: Project) : BookmarksL
}
}
@ApiStatus.Internal
@Service(Service.Level.PROJECT)
class BreakpointListUpdaterService(internal val cs: CoroutineScope) {
@Volatile
@@ -114,7 +114,6 @@
<projectService serviceImplementation="com.intellij.platform.debugger.impl.ui.evaluate.quick.common.ValueLookupManager"/>
<bookmarksListProvider implementation="com.intellij.xdebugger.impl.breakpoints.BreakpointListProvider"/>
<remote.customDataContextSerializer implementation="com.intellij.xdebugger.impl.ui.XDebuggerTreeSelectedValuesSerializer"/>
<remote.customDataContextSerializer implementation="com.intellij.xdebugger.impl.ui.XDebuggerTreeSelectedStacksSerializer"/>
<projectSettings service="com.intellij.xdebugger.impl.XDebuggerHistoryManager"/>