From 5eaf80c615156f9076ff447f80d6a1fb9e86186b Mon Sep 17 00:00:00 2001 From: detachhead Date: Fri, 3 Jul 2026 21:20:47 +1000 Subject: [PATCH] improve logic for determining whether a git log editor tab should be closable --- .../com/intellij/vcs/log/impl/IdeVcsLogManager.kt | 6 +----- .../com/intellij/vcs/log/impl/VcsLogTabsManager.kt | 4 ++-- .../intellij/vcs/log/ui/CanCloseVirtualLogFile.kt | 2 +- .../intellij/vcs/log/ui/editor/DefaultVcsLogFile.kt | 5 ++--- .../vcs/log/ui/editor/VcsLogVirtualFileSystem.kt | 13 ++++++++----- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/IdeVcsLogManager.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/IdeVcsLogManager.kt index d584ce208412a..532f0a5e850df 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/IdeVcsLogManager.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/IdeVcsLogManager.kt @@ -4,7 +4,6 @@ package com.intellij.vcs.log.impl import com.intellij.openapi.application.EdtImmediate import com.intellij.openapi.application.UiImmediate import com.intellij.openapi.components.service -import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer import com.intellij.openapi.vfs.VirtualFile @@ -22,7 +21,6 @@ import com.intellij.vcs.log.impl.VcsLogNavigationUtil.showCommit import com.intellij.vcs.log.impl.VcsLogNavigationUtil.showCommitSync import com.intellij.vcs.log.ui.MainVcsLogUi import com.intellij.vcs.log.ui.VcsLogUiEx -import com.intellij.vcs.log.ui.editor.VcsLogVirtualFileSystem import com.intellij.vcs.log.util.VcsLogUtil import com.intellij.vcs.log.visible.filters.VcsLogFilterObject import kotlinx.coroutines.CoroutineScope @@ -62,9 +60,7 @@ internal class IdeVcsLogManager( mainUiHolderState.collect { holder -> val showLogInEditorWindow = service()[CommonUiProperties.SHOW_IN_EDITOR] val ui = if (showLogInEditorWindow) { - val file = VcsLogVirtualFileSystem.Holder.getInstance(). - createVcsLogFile(project, "", null) - val editor = FileEditorManager.getInstance(project).openFile(file, false, true) + val editor = tabsManager.openEditorLogTab("", false, null) VcsLogEditorUtil.findVcsLogUi(editor,MainVcsLogUi::class.java) } else { createLogUi(getMainLogUiFactory(MAIN_LOG_ID, null)) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogTabsManager.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogTabsManager.kt index 0ea3573eb923b..9fb6c1cd9361c 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogTabsManager.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogTabsManager.kt @@ -135,8 +135,8 @@ internal class VcsLogTabsManager( throw UnsupportedOperationException("Only log in editor or tool window is supported") } - private fun openEditorLogTab(tabId: String, focus: Boolean, filters: VcsLogFilterCollection?): Array { - val file = VcsLogVirtualFileSystem.Holder.getInstance().createVcsLogFile(project, tabId, filters) + fun openEditorLogTab(tabId: String, focus: Boolean, filters: VcsLogFilterCollection?): Array { + val file = VcsLogVirtualFileSystem.Holder.getInstance().createVcsLogFile(project, tabId, filters, uiProperties.tabs.isNotEmpty()) installFilesListener() uiProperties.addTab(tabId, VcsLogTabLocation.EDITOR) return FileEditorManager.getInstance(project).openFile(file, focus, true) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CanCloseVirtualLogFile.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CanCloseVirtualLogFile.kt index 10c946bd14fa8..76aaab2973099 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CanCloseVirtualLogFile.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CanCloseVirtualLogFile.kt @@ -10,6 +10,6 @@ class CanCloseVirtualLogFile: VirtualFilePreCloseCheck { * don't allow the first vcs log window to be closed */ override fun canCloseFile(file: VirtualFile): Boolean { - return file !is DefaultVcsLogFile || !file.isFirstLogFile + return file !is DefaultVcsLogFile || file.canClose } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/editor/DefaultVcsLogFile.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/editor/DefaultVcsLogFile.kt index 1e2255896d37d..dada7cc7e6978 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/editor/DefaultVcsLogFile.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/editor/DefaultVcsLogFile.kt @@ -36,6 +36,8 @@ import javax.swing.JComponent internal class DefaultVcsLogFile( private val pathId: VcsLogVirtualFileSystem.VcsLogComplexPath, private var filters: VcsLogFilterCollection? = null, + // the first log file always gets created with an empty log ID in IdeVcsLogManager.createUi, which should never be closable + var canClose: Boolean = pathId.logId != "" ) : VcsLogFile(VcsLogTabsUtil.getFullName(pathId.logId)), VirtualFilePathWrapper { //NON-NLS not displayed @@ -97,9 +99,6 @@ internal class DefaultVcsLogFile( return tabId.hashCode() } - // the first log file always gets created with an empty log ID in IdeVcsLogManager.createUi - val isFirstLogFile by lazy { pathId.logId == "" } - companion object { private val LOG = logger() } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/editor/VcsLogVirtualFileSystem.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/editor/VcsLogVirtualFileSystem.kt index 712b746f1817c..15bd1eb146eeb 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/editor/VcsLogVirtualFileSystem.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/editor/VcsLogVirtualFileSystem.kt @@ -13,15 +13,18 @@ internal class VcsLogVirtualFileSystem : ComplexPathVirtualFileSystem(GsonComplexPathSerializer(VcsLogComplexPath::class.java)) { override fun findOrCreateFile(project: Project, path: VcsLogComplexPath): VirtualFile { - return createVcsLogFile(path, null) + return createVcsLogFile(path, null, true) // TODO: should this ever be false? } - fun createVcsLogFile(project: Project, tabId: String, filters: VcsLogFilterCollection?): VirtualFile { - return createVcsLogFile(VcsLogComplexPath(project.locationHash, project.locationHash, tabId), filters) + /** + * @param canClose if `null`, infer whether the file can be closed based on whether it's the initially opened one. + */ + fun createVcsLogFile(project: Project, tabId: String, filters: VcsLogFilterCollection?, canClose: Boolean): VirtualFile { + return createVcsLogFile(VcsLogComplexPath(project.locationHash, project.locationHash, tabId), filters, canClose) } - private fun createVcsLogFile(pathId: VcsLogComplexPath, filters: VcsLogFilterCollection?): DefaultVcsLogFile { - return DefaultVcsLogFile(pathId, filters) + private fun createVcsLogFile(pathId: VcsLogComplexPath, filters: VcsLogFilterCollection?, canClose: Boolean): DefaultVcsLogFile { + return DefaultVcsLogFile(pathId, filters, canClose) } override fun getProtocol(): String = Holder.PROTOCOL