The old Search Everywhere API is deprecated: please migrate to the new API before 2027.1

The old Search Everywhere API is deprecated starting with 2026.3. We plan for the platform to stop supporting SearchEverywhereContributor implementations in 2027.1.

ACTION POINT: If you have a SearchEverywhereContributor implementation, please port its functionality to the new API.

For the motivation behind the new API, read the blog post: Major Architectural Update: Introducing the New Search Everywhere API Built for Remote Development

What is deprecated

The old API in the com.intellij.ide.actions.searcheverywhere package. The main classes:

  • SearchEverywhereContributor, SearchEverywhereContributorFactory, WeightedSearchEverywhereContributor
  • AbstractGotoSEContributor and its subclasses, such as ClassSearchEverywhereContributor and SymbolSearchEverywhereContributor
  • SearchEverywhereManager, SearchEverywhereExtendedInfoProvider, SearchEverywherePreview, SearchEverywhereCommandInfo
  • The remote-support classes: RemoteSearchEverywhereConverter, RemoteSearchEverywherePresentation, and SearchEverywhereRemoteSupportService

API overview

The new API keeps the search logic and the data apart from the UI. Results are serializable, so the same provider works in a local IDE and in remote development.

Providing results

  • SeItemsProvider replaces SearchEverywhereContributor. Implement these methods:
    • collectItems(params: SeParams, collector: Collector): a suspend function. It sends each result to collector.put(item). put() suspends when the UI needs no more items, so you get back pressure without extra code.
    • itemSelected(item, modifiers, searchText): handles the selection. It returns true to close the popup.
    • canBeShownInFindResults() and, if you need it, performExtendedAction(item).
    • addDataForItem(item, sink), getPsiElementForItem(item), getVirtualFileForItem(item), and getNavigatableForItem(item): these supply data for actions on the selected item.
  • SeItemsProviderFactory creates the provider. Register it with the com.intellij.searchEverywhere.itemsProviderFactory extension point. The factory id must be the same as the provider id.
  • SeItem is one result. It gives an SeItemPresentation. Use SeBasicItemPresentationBuilder for a simple row, or SeTargetItemPresentationBuilder for a target-like row with an icon, a location, and a container text.

Goto-model providers: replacing AbstractGotoSEContributor

If your contributor extends AbstractGotoSEContributor and uses a FilteringGotoByModel (as Classes, Symbols, and Files do), use SeTargetItemsProvider instead.

The old API used inheritance: you extended AbstractGotoSEContributor and overrode its methods. The new API uses composition. SeTargetItemsProvider is a final class, so you cannot extend it. Your provider implements SeItemsProvider, keeps an SeTargetItemsProvider instance, and delegates to it:

class MyGotoProvider private constructor(
  private val targetProvider: SeTargetItemsProvider<MyFilterValue>,
) : SeItemsProvider {
  override val id: String get() = ID
  override val displayName: @Nls String get() = MyBundle.message("search.everywhere.my.tab")

  override suspend fun collectItems(params: SeParams, collector: SeItemsProvider.Collector): Unit =
    targetProvider.collectItems(params, collector)

  override suspend fun itemSelected(item: SeItem, modifiers: Int, searchText: String): Boolean =
    targetProvider.itemSelected(item, this, modifiers, searchText)

  override suspend fun performExtendedAction(item: SeItem): Boolean =
    targetProvider.performExtendedAction(item, this)

  override fun addDataForItem(item: SeItem, sink: DataSink): Unit = targetProvider.addDataForItem(item, sink)
  override fun getPsiElementForItem(item: SeItem): PsiElement? = targetProvider.getPsiElementForItem(item)
  override fun getVirtualFileForItem(item: SeItem): VirtualFile? = targetProvider.getVirtualFileForItem(item)
  override fun getNavigatableForItem(item: SeItem): Navigatable? = targetProvider.getNavigatableForItem(item)

  override suspend fun canBeShownInFindResults(): Boolean = true

  override fun dispose() {
    Disposer.dispose(targetProvider)
  }

  companion object {
    const val ID: String = "MyGotoProvider"

    suspend fun create(project: Project, dataContext: DataContext): MyGotoProvider {
      val targetProvider = SeTargetItemsProvider.create(
        project = project,
        dataContext = dataContext,
        operationDisposable = null,
        label = ID,
        gotoModelProvider = { project, scope, hiddenTypes -> MyGotoModel(project) },
      )
      return MyGotoProvider(targetProvider)
    }
  }
}

SeTargetItemsProvider.create(...) covers the things you used to override in AbstractGotoSEContributor:

  • gotoModelProvider builds your FilteringGotoByModel for the selected scope and the hidden filter values.
  • typeFilterProvider gives the type filters as PersistentSearchEverywhereContributorFilter instances, with a name for each.
  • extendedInfoCalculator (SeExtendedInfoCalculator) computes the footer info. The default reads it from the PSI element.
  • isFileProvider, acceptsBlankQuery, supportsScopes, and scopesProvider (SeTargetScopesProvider) control files, empty queries, and scopes.

The provider also gives you highlighting of the matched text, exact-match marking, previews (getPreviewInfo), and multi-selection. You do not write this code yourself.

Optional features

  • SeExtendedInfoProvider replaces SearchEverywhereExtendedInfoProvider for the footer.
  • SeItemsPreviewProvider and SePreviewInfoFactory replace SearchEverywherePreview.
  • SeCommandsProviderInterface and SeCommandInfoFactory replace SearchEverywhereCommandInfo.

Tabs

  • SeTab and SeTabFactory define a separate tab in the popup. Register the factory with the com.intellij.searchEverywhere.tabFactory extension point. Tabs exist only on the frontend. For a standard tab, start from SeDefaultTabBase.

Status of the new API

The new API is marked @ApiStatus.Experimental. We still change it based on your feedback. If the new API has no replacement for something you use in the old API, reply in this thread. Tell us your use case and the class or method you use.

Thanks for the guide. I migrated an All-tab contributor to SeItemsProvider, but dedicated tabs appear blocked:

SeTabFactory and SeDefaultTabBase are experimental, yet their module, intellij.platform.searchEverywhere.frontend, has internal visibility. Without a dependency, our factory fails with NoClassDefFoundError; declaring it causes the platform to reject our external plugin. Reproduced on 263.6800.43.

  • Will these tab APIs become externally accessible before legacy contributor support ends in 2027.1? Which build should we target?
  • Meanwhile, should plugins retain legacy contributors to preserve dedicated tabs?
  • Is SearchEverywhereManager.isShown() still the supported popup-lifecycle query? We found no public replacement; SeFrontendService is internal.

Hi @chbndrhnns,
Thank you for the feedback!

Will these tab APIs become externally accessible before legacy contributor support ends in 2027.1?

The module became internal accidentally, we will make it public as soon as possible. Most probably in 2026.3.1. Sorry about that. Ticket to follow: IJPL-259650.

Meanwhile, should plugins retain legacy contributors to preserve dedicated tabs?

Yes.

Is SearchEverywhereManager.isShown() still the supported popup-lifecycle query?

Yes, SearchEverywhereManager.isShown() is still the way to go.