diff --git a/platform/searchEverywhere/backend/src/impl/SeBackendService.kt b/platform/searchEverywhere/backend/src/impl/SeBackendService.kt index 2af8aee5cc43..3bb85d9fc639 100644 --- a/platform/searchEverywhere/backend/src/impl/SeBackendService.kt +++ b/platform/searchEverywhere/backend/src/impl/SeBackendService.kt @@ -259,6 +259,18 @@ class SeBackendService(val project: Project, private val coroutineScope: Corouti } } + suspend fun isExtendedInfoEnabled( + session: SeSession, + dataContextId: DataContextId, + providerIds: List, + isAllTab: Boolean, + ): Boolean { + return providerIds.any { providerId -> + val provider = getProvidersHolder(session, dataContextId)?.get(providerId, isAllTab) + provider?.isExtendedInfoEnabled() ?: false + } + } + companion object { @JvmStatic fun getInstance(project: Project): SeBackendService = project.service() diff --git a/platform/searchEverywhere/backend/src/impl/SeRemoteApiImpl.kt b/platform/searchEverywhere/backend/src/impl/SeRemoteApiImpl.kt index d5472dfc0646..50b0b8a9f694 100644 --- a/platform/searchEverywhere/backend/src/impl/SeRemoteApiImpl.kt +++ b/platform/searchEverywhere/backend/src/impl/SeRemoteApiImpl.kt @@ -149,4 +149,9 @@ class SeRemoteApiImpl : SeRemoteApi { val project = projectId.findProjectOrNull() ?: return false return SeBackendService.getInstance(project).isPreviewEnabled(session, dataContextId, providerIds, isAllTab) } + + override suspend fun isExtendedInfoEnabled(projectId: ProjectId, session: SeSession, dataContextId: DataContextId, providerIds: List, isAllTab: Boolean): Boolean { + val project = projectId.findProjectOrNull() ?: return false + return SeBackendService.getInstance(project).isExtendedInfoEnabled(session, dataContextId, providerIds, isAllTab) + } } diff --git a/platform/searchEverywhere/backend/src/providers/classes/SeClassesProvider.kt b/platform/searchEverywhere/backend/src/providers/classes/SeClassesProvider.kt index 8860c455beaf..0b34dc4de432 100644 --- a/platform/searchEverywhere/backend/src/providers/classes/SeClassesProvider.kt +++ b/platform/searchEverywhere/backend/src/providers/classes/SeClassesProvider.kt @@ -18,7 +18,8 @@ import org.jetbrains.annotations.Nls class SeClassesProvider(private val contributorWrapper: SeAsyncContributorWrapper) : SeWrappedLegacyContributorItemsProvider(), SeSearchScopesProvider, SeTypeVisibilityStateProvider, - SeItemsPreviewProvider { + SeItemsPreviewProvider, + SeExtendedInfoProvider { override val id: String get() = SeProviderIdUtils.CLASSES_ID override val displayName: @Nls String get() = contributorWrapper.contributor.fullGroupName diff --git a/platform/searchEverywhere/backend/src/providers/files/SeFilesProvider.kt b/platform/searchEverywhere/backend/src/providers/files/SeFilesProvider.kt index bed5b85988d6..bc63e712bf33 100644 --- a/platform/searchEverywhere/backend/src/providers/files/SeFilesProvider.kt +++ b/platform/searchEverywhere/backend/src/providers/files/SeFilesProvider.kt @@ -18,7 +18,8 @@ import org.jetbrains.annotations.Nls class SeFilesProvider(private val contributorWrapper: SeAsyncContributorWrapper) : SeWrappedLegacyContributorItemsProvider(), SeSearchScopesProvider, SeTypeVisibilityStateProvider, - SeItemsPreviewProvider{ + SeItemsPreviewProvider, + SeExtendedInfoProvider { override val id: String get() = SeProviderIdUtils.FILES_ID override val displayName: @Nls String get() = contributorWrapper.contributor.fullGroupName diff --git a/platform/searchEverywhere/backend/src/providers/recentFiles/SeRecentFilesProvider.kt b/platform/searchEverywhere/backend/src/providers/recentFiles/SeRecentFilesProvider.kt index 8651605e0db0..4a8b2683a639 100644 --- a/platform/searchEverywhere/backend/src/providers/recentFiles/SeRecentFilesProvider.kt +++ b/platform/searchEverywhere/backend/src/providers/recentFiles/SeRecentFilesProvider.kt @@ -5,6 +5,7 @@ import com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor import com.intellij.ide.util.gotoByName.FileTypeRef import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer +import com.intellij.platform.searchEverywhere.SeExtendedInfoProvider import com.intellij.platform.searchEverywhere.* import com.intellij.platform.searchEverywhere.backend.providers.target.SeTargetsProviderDelegate import com.intellij.platform.searchEverywhere.providers.SeAsyncContributorWrapper @@ -13,7 +14,9 @@ import org.jetbrains.annotations.ApiStatus.Internal import org.jetbrains.annotations.Nls @Internal -class SeRecentFilesProvider(private val contributorWrapper: SeAsyncContributorWrapper) : SeWrappedLegacyContributorItemsProvider(), SeItemsPreviewProvider { +class SeRecentFilesProvider(private val contributorWrapper: SeAsyncContributorWrapper) : SeWrappedLegacyContributorItemsProvider(), + SeItemsPreviewProvider, + SeExtendedInfoProvider { override val id: String get() = SeProviderIdUtils.RECENT_FILES_ID override val displayName: @Nls String get() = contributorWrapper.contributor.fullGroupName diff --git a/platform/searchEverywhere/backend/src/providers/symbols/SeSymbolsProvider.kt b/platform/searchEverywhere/backend/src/providers/symbols/SeSymbolsProvider.kt index 65b2222248d9..280442f26b73 100644 --- a/platform/searchEverywhere/backend/src/providers/symbols/SeSymbolsProvider.kt +++ b/platform/searchEverywhere/backend/src/providers/symbols/SeSymbolsProvider.kt @@ -18,7 +18,8 @@ import org.jetbrains.annotations.Nls class SeSymbolsProvider(private val contributorWrapper: SeAsyncContributorWrapper) : SeWrappedLegacyContributorItemsProvider(), SeSearchScopesProvider, SeTypeVisibilityStateProvider, - SeItemsPreviewProvider{ + SeItemsPreviewProvider, + SeExtendedInfoProvider { override val id: String get() = SeProviderIdUtils.SYMBOLS_ID override val displayName: @Nls String get() = contributorWrapper.contributor.fullGroupName diff --git a/platform/searchEverywhere/backend/src/providers/text/SeTextItemsProvider.kt b/platform/searchEverywhere/backend/src/providers/text/SeTextItemsProvider.kt index e1617935fd7d..035f2fa08756 100644 --- a/platform/searchEverywhere/backend/src/providers/text/SeTextItemsProvider.kt +++ b/platform/searchEverywhere/backend/src/providers/text/SeTextItemsProvider.kt @@ -45,7 +45,8 @@ class SeTextSearchItem( @ApiStatus.Internal class SeTextItemsProvider(project: Project, private val contributorWrapper: SeAsyncContributorWrapper) : SeWrappedLegacyContributorItemsProvider(), SeSearchScopesProvider, - SeItemsPreviewProvider{ + SeItemsPreviewProvider, + SeExtendedInfoProvider { override val id: String get() = SeProviderIdUtils.TEXT_ID override val displayName: @Nls String get() = contributor.fullGroupName diff --git a/platform/searchEverywhere/frontend/src/SeFrontendItemDataProvidersFacade.kt b/platform/searchEverywhere/frontend/src/SeFrontendItemDataProvidersFacade.kt index 8185f34da5fe..361b2c5413a8 100644 --- a/platform/searchEverywhere/frontend/src/SeFrontendItemDataProvidersFacade.kt +++ b/platform/searchEverywhere/frontend/src/SeFrontendItemDataProvidersFacade.kt @@ -97,6 +97,12 @@ class SeFrontendItemDataProvidersFacade(private val projectId: ProjectId, ) } + suspend fun isExtendedInfoEnabled(): Boolean { + return SeRemoteApi.getInstance().isExtendedInfoEnabled( + projectId, providerIds = providerIds, session = session, dataContextId = dataContextId, isAllTab = isAllTab + ) + } + companion object { private const val DEFAULT_CHUNK_SIZE: Int = 50 } diff --git a/platform/searchEverywhere/frontend/src/SeTab.kt b/platform/searchEverywhere/frontend/src/SeTab.kt index 1da5dac4f5d3..9edfc603c5ba 100644 --- a/platform/searchEverywhere/frontend/src/SeTab.kt +++ b/platform/searchEverywhere/frontend/src/SeTab.kt @@ -47,4 +47,6 @@ interface SeTab : Disposable { suspend fun isPreviewEnabled(): Boolean suspend fun getPreviewInfo(itemData: SeItemData): SePreviewInfo? + + suspend fun isExtendedInfoEnabled(): Boolean } \ No newline at end of file diff --git a/platform/searchEverywhere/frontend/src/providers/actions/SeActionsAdaptedProvider.kt b/platform/searchEverywhere/frontend/src/providers/actions/SeActionsAdaptedProvider.kt index 43bbb22e04da..916fd1b0143c 100644 --- a/platform/searchEverywhere/frontend/src/providers/actions/SeActionsAdaptedProvider.kt +++ b/platform/searchEverywhere/frontend/src/providers/actions/SeActionsAdaptedProvider.kt @@ -39,7 +39,7 @@ class SeActionItem( } @Internal -class SeActionsAdaptedProvider(private val contributorWrapper: SeAsyncContributorWrapper) : SeWrappedLegacyContributorItemsProvider() { +class SeActionsAdaptedProvider(private val contributorWrapper: SeAsyncContributorWrapper) : SeWrappedLegacyContributorItemsProvider(), SeExtendedInfoProvider { override val id: String get() = SeProviderIdUtils.ACTIONS_ID override val displayName: @Nls String get() = contributor.fullGroupName diff --git a/platform/searchEverywhere/frontend/src/resultsProcessing/SeTabDelegate.kt b/platform/searchEverywhere/frontend/src/resultsProcessing/SeTabDelegate.kt index 09bdd23313a7..3f3199b0c158 100644 --- a/platform/searchEverywhere/frontend/src/resultsProcessing/SeTabDelegate.kt +++ b/platform/searchEverywhere/frontend/src/resultsProcessing/SeTabDelegate.kt @@ -163,6 +163,10 @@ class SeTabDelegate( return providers.getValue().isPreviewEnabled() } + suspend fun isExtendedInfoEnabled(): Boolean { + return providers.getValue().isExtendedInfoEnabled() + } + override fun dispose() {} private class Providers( @@ -266,6 +270,10 @@ class SeTabDelegate( suspend fun isPreviewEnabled(): Boolean { return localProviders.values.any { it.isPreviewEnabled() } || frontendProvidersFacade?.isPreviewEnabled() == true } + + suspend fun isExtendedInfoEnabled(): Boolean { + return localProviders.values.any { it.isExtendedInfoEnabled() } || frontendProvidersFacade?.isExtendedInfoEnabled() == true + } } // Workaround for: IJPL-188383 Search Everywhere, All tab: 'Top Hit' filter is duplicated diff --git a/platform/searchEverywhere/frontend/src/tabs/actions/SeActionsTab.kt b/platform/searchEverywhere/frontend/src/tabs/actions/SeActionsTab.kt index 759d907e0d01..a43ba7bcc11e 100644 --- a/platform/searchEverywhere/frontend/src/tabs/actions/SeActionsTab.kt +++ b/platform/searchEverywhere/frontend/src/tabs/actions/SeActionsTab.kt @@ -63,6 +63,10 @@ class SeActionsTab(private val delegate: SeTabDelegate) : SeTab { return delegate.getPreviewInfo(itemData, false) } + override suspend fun isExtendedInfoEnabled(): Boolean { + return delegate.isExtendedInfoEnabled() + } + override fun dispose() { Disposer.dispose(delegate) } diff --git a/platform/searchEverywhere/frontend/src/tabs/all/SeAllTab.kt b/platform/searchEverywhere/frontend/src/tabs/all/SeAllTab.kt index ba68d57a4824..cc23d1640cf9 100644 --- a/platform/searchEverywhere/frontend/src/tabs/all/SeAllTab.kt +++ b/platform/searchEverywhere/frontend/src/tabs/all/SeAllTab.kt @@ -67,6 +67,10 @@ class SeAllTab(private val delegate: SeTabDelegate) : SeTab { return delegate.getUpdatedPresentation(item) } + override suspend fun isExtendedInfoEnabled(): Boolean { + return delegate.isExtendedInfoEnabled() + } + override suspend fun performExtendedAction(item: SeItemData): Boolean { return delegate.performExtendedAction(item) } diff --git a/platform/searchEverywhere/frontend/src/tabs/classes/SeClassesTab.kt b/platform/searchEverywhere/frontend/src/tabs/classes/SeClassesTab.kt index c07efb1ee623..ce548f0bcb30 100644 --- a/platform/searchEverywhere/frontend/src/tabs/classes/SeClassesTab.kt +++ b/platform/searchEverywhere/frontend/src/tabs/classes/SeClassesTab.kt @@ -65,6 +65,10 @@ class SeClassesTab(private val delegate: SeTabDelegate) : SeTab { return delegate.getPreviewInfo(itemData, false) } + override suspend fun isExtendedInfoEnabled(): Boolean { + return delegate.isExtendedInfoEnabled() + } + override fun dispose() { Disposer.dispose(delegate) } diff --git a/platform/searchEverywhere/frontend/src/tabs/files/SeFilesTab.kt b/platform/searchEverywhere/frontend/src/tabs/files/SeFilesTab.kt index 6ccaf359f8de..f133d473ed16 100644 --- a/platform/searchEverywhere/frontend/src/tabs/files/SeFilesTab.kt +++ b/platform/searchEverywhere/frontend/src/tabs/files/SeFilesTab.kt @@ -66,6 +66,10 @@ class SeFilesTab(private val delegate: SeTabDelegate) : SeTab { return delegate.getPreviewInfo(itemData, false) } + override suspend fun isExtendedInfoEnabled(): Boolean { + return delegate.isExtendedInfoEnabled() + } + override fun dispose() { Disposer.dispose(delegate) } diff --git a/platform/searchEverywhere/frontend/src/tabs/mocks/SeTabMock.kt b/platform/searchEverywhere/frontend/src/tabs/mocks/SeTabMock.kt index 0e537eb70cce..a1dc05d48861 100644 --- a/platform/searchEverywhere/frontend/src/tabs/mocks/SeTabMock.kt +++ b/platform/searchEverywhere/frontend/src/tabs/mocks/SeTabMock.kt @@ -45,6 +45,10 @@ class SeTabMock( return delegate.isPreviewEnabled() } + override suspend fun isExtendedInfoEnabled(): Boolean { + return delegate.isExtendedInfoEnabled() + } + override fun dispose() { Disposer.dispose(delegate) } diff --git a/platform/searchEverywhere/frontend/src/tabs/symbols/SeSymbolsTab.kt b/platform/searchEverywhere/frontend/src/tabs/symbols/SeSymbolsTab.kt index c31392431284..edd7adcdf1dd 100644 --- a/platform/searchEverywhere/frontend/src/tabs/symbols/SeSymbolsTab.kt +++ b/platform/searchEverywhere/frontend/src/tabs/symbols/SeSymbolsTab.kt @@ -65,6 +65,10 @@ class SeSymbolsTab(private val delegate: SeTabDelegate) : SeTab { return delegate.getPreviewInfo(itemData, false) } + override suspend fun isExtendedInfoEnabled(): Boolean { + return delegate.isExtendedInfoEnabled() + } + override fun dispose() { Disposer.dispose(delegate) } diff --git a/platform/searchEverywhere/frontend/src/tabs/text/SeTextTab.kt b/platform/searchEverywhere/frontend/src/tabs/text/SeTextTab.kt index 79a846a54c09..fd9ada36a200 100644 --- a/platform/searchEverywhere/frontend/src/tabs/text/SeTextTab.kt +++ b/platform/searchEverywhere/frontend/src/tabs/text/SeTextTab.kt @@ -68,6 +68,10 @@ class SeTextTab(private val delegate: SeTabDelegate, registerShortcut: (AnAction return delegate.getPreviewInfo(itemData, false) } + override suspend fun isExtendedInfoEnabled(): Boolean { + return delegate.isExtendedInfoEnabled() + } + override fun dispose() { Disposer.dispose(filterEditorDisposable) Disposer.dispose(delegate) diff --git a/platform/searchEverywhere/frontend/src/ui/SePopupContentPane.kt b/platform/searchEverywhere/frontend/src/ui/SePopupContentPane.kt index c4d595dd774d..94d735d99da9 100644 --- a/platform/searchEverywhere/frontend/src/ui/SePopupContentPane.kt +++ b/platform/searchEverywhere/frontend/src/ui/SePopupContentPane.kt @@ -152,8 +152,6 @@ class SePopupContentPane( resultList.setFocusable(false) - updateExtendedInfoContainer() - RowsGridBuilder(this) .row().cell(headerPane, horizontalAlign = HorizontalAlign.FILL, resizableColumn = true) .row().cell(textField, horizontalAlign = HorizontalAlign.FILL, resizableColumn = true) @@ -300,6 +298,9 @@ class SePopupContentPane( } } } + withContext(Dispatchers.EDT) { + updateExtendedInfoContainer() + } } } @@ -581,14 +582,12 @@ class SePopupContentPane( vmState.value?.let { vm -> vm.selectNextTab() logTabSwitchedEvent(e) - updateExtendedInfoContainer() } } val prevTabAction: (AnActionEvent) -> Unit = { e -> vmState.value?.let { vm -> vm.selectPreviousTab() logTabSwitchedEvent(e) - updateExtendedInfoContainer() } } @@ -751,11 +750,10 @@ class SePopupContentPane( .show(relativePoint) } - private fun createExtendedInfoComponent(): ExtendedInfoComponent? { - if (isExtendedInfoEnabled()) { + private suspend fun createExtendedInfoComponent(): ExtendedInfoComponent? { + if (isExtendedInfoEnabled() && vm.isExtendedInfoEnabledInTab()) { val leftText = fun(element: Any): String? { val leftText = (element as? SeResultListItemRow)?.item?.presentation?.extendedInfo?.text - extendedInfoContainer.isVisible = !leftText.isNullOrEmpty() return leftText } @@ -788,7 +786,7 @@ class SePopupContentPane( return null } - private fun updateExtendedInfoContainer() { + private suspend fun updateExtendedInfoContainer() { extendedInfoContainer.removeAll() extendedInfoComponent = createExtendedInfoComponent() extendedInfoComponent?.let { extendedInfoContainer.add(it.component) } diff --git a/platform/searchEverywhere/frontend/src/vm/SePopupVm.kt b/platform/searchEverywhere/frontend/src/vm/SePopupVm.kt index f3c614724ee7..2da1dd69e638 100644 --- a/platform/searchEverywhere/frontend/src/vm/SePopupVm.kt +++ b/platform/searchEverywhere/frontend/src/vm/SePopupVm.kt @@ -250,6 +250,10 @@ class SePopupVm( return previewFetcher?.fetchPreview(usages) } + suspend fun isExtendedInfoEnabledInTab(): Boolean { + return currentTab.isExtendedInfoEnabled() + } + private val popupVm = this inner class ShowInFindToolWindowAction : DumbAwareAction(IdeBundle.messagePointer("show.in.find.window.button.name"), diff --git a/platform/searchEverywhere/frontend/src/vm/SeTabVm.kt b/platform/searchEverywhere/frontend/src/vm/SeTabVm.kt index ebe4e70774e2..d2f144d24caa 100644 --- a/platform/searchEverywhere/frontend/src/vm/SeTabVm.kt +++ b/platform/searchEverywhere/frontend/src/vm/SeTabVm.kt @@ -239,6 +239,10 @@ class SeTabVm( } suspend fun getPreviewInfo(itemData: SeItemData): SePreviewInfo? = tab.getPreviewInfo(itemData) + + suspend fun isExtendedInfoEnabled() : Boolean { + return tab.isExtendedInfoEnabled() + } } private const val ESSENTIALS_THROTTLE_DELAY: Long = 100 diff --git a/platform/searchEverywhere/shared/src/SeExtendedInfoProvider.kt b/platform/searchEverywhere/shared/src/SeExtendedInfoProvider.kt new file mode 100644 index 000000000000..d75b82c297e2 --- /dev/null +++ b/platform/searchEverywhere/shared/src/SeExtendedInfoProvider.kt @@ -0,0 +1,7 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.platform.searchEverywhere + +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +interface SeExtendedInfoProvider \ No newline at end of file diff --git a/platform/searchEverywhere/shared/src/impl/SeRemoteApi.kt b/platform/searchEverywhere/shared/src/impl/SeRemoteApi.kt index 9b3141cb0c88..fa9772414739 100644 --- a/platform/searchEverywhere/shared/src/impl/SeRemoteApi.kt +++ b/platform/searchEverywhere/shared/src/impl/SeRemoteApi.kt @@ -131,6 +131,12 @@ interface SeRemoteApi : RemoteApi { isAllTab: Boolean, ): Boolean + suspend fun isExtendedInfoEnabled(projectId: ProjectId, + session: SeSession, + dataContextId: DataContextId, + providerIds: List, + isAllTab: Boolean): Boolean + companion object { @JvmStatic suspend fun getInstance(): SeRemoteApi { diff --git a/platform/searchEverywhere/shared/src/providers/SeAdaptedItemsProvider.kt b/platform/searchEverywhere/shared/src/providers/SeAdaptedItemsProvider.kt index 6d8493b83deb..c0ea49dc329a 100644 --- a/platform/searchEverywhere/shared/src/providers/SeAdaptedItemsProvider.kt +++ b/platform/searchEverywhere/shared/src/providers/SeAdaptedItemsProvider.kt @@ -3,6 +3,7 @@ package com.intellij.platform.searchEverywhere.providers import com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor import com.intellij.ide.actions.searcheverywhere.SearchEverywherePreviewProvider +import com.intellij.ide.actions.searcheverywhere.SearchEverywhereExtendedInfoProvider import com.intellij.openapi.application.EDT import com.intellij.openapi.util.Disposer import com.intellij.platform.searchEverywhere.* @@ -55,6 +56,10 @@ class SeAdaptedItemsProvider(contributor: SearchEverywhereContributor) : Se return contributorWrapper.contributor is SearchEverywherePreviewProvider } + fun isExtendedInfoProvider(): Boolean { + return contributorWrapper.contributor is SearchEverywhereExtendedInfoProvider + } + override fun dispose() { Disposer.dispose(contributorWrapper) } diff --git a/platform/searchEverywhere/shared/src/providers/SeLocalItemDataProvider.kt b/platform/searchEverywhere/shared/src/providers/SeLocalItemDataProvider.kt index ca88d4d24d39..4d563a44814c 100644 --- a/platform/searchEverywhere/shared/src/providers/SeLocalItemDataProvider.kt +++ b/platform/searchEverywhere/shared/src/providers/SeLocalItemDataProvider.kt @@ -1,6 +1,7 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.platform.searchEverywhere.providers +import com.intellij.ide.actions.searcheverywhere.SearchEverywhereExtendedInfoProvider import com.intellij.ide.actions.searcheverywhere.statistics.SearchEverywhereUsageTriggerCollector import com.intellij.openapi.Disposable import com.intellij.openapi.application.EDT @@ -118,6 +119,15 @@ class SeLocalItemDataProvider( return provider is SeItemsPreviewProvider } + fun isExtendedInfoEnabled(): Boolean { + if (provider is SeTopHitItemsProvider) { + return provider.contributor is SearchEverywhereExtendedInfoProvider + } else if (provider is SeAdaptedItemsProvider) { + return provider.isExtendedInfoProvider() + } + return provider is SeExtendedInfoProvider + } + override fun dispose() { SeLog.log(SeLog.LIFE_CYCLE, "$logLabel provider ${id.value} disposed") Disposer.dispose(provider)