mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 11:53:49 +07:00
[terminal] initialize filters lazily; allow adding custom filters
GitOrigin-RevId: 98be53c6a86b78f9254353aace74e3b871439638
This commit is contained in:
committed by
intellij-monorepo-bot
parent
2c5f4e42c2
commit
20e36a1bc2
@@ -11,54 +11,62 @@ import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.util.asDisposable
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.intellij.util.concurrency.SynchronizedClearableLazy
|
||||
import kotlinx.coroutines.*
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
internal class CompositeFilterWrapper(private val project: Project, private val coroutineScope: CoroutineScope) {
|
||||
private val filtersUpdatedListeners: MutableList<() -> Unit> = CopyOnWriteArrayList()
|
||||
|
||||
private val filtersComputationInProgress: AtomicBoolean = AtomicBoolean(false)
|
||||
private val customFilters: MutableList<Filter> = CopyOnWriteArrayList()
|
||||
|
||||
@Volatile
|
||||
private var cachedFilter: CompositeFilter? = null
|
||||
|
||||
@Volatile
|
||||
private var filtersComputed: CompletableDeferred<Unit> = CompletableDeferred()
|
||||
private var areFiltersInUse: Boolean = false
|
||||
|
||||
init {
|
||||
ConsoleFilterProvider.FILTER_PROVIDERS.addChangeListener({
|
||||
cachedFilter = null
|
||||
filtersComputed = CompletableDeferred()
|
||||
scheduleFiltersComputation()
|
||||
}, coroutineScope.asDisposable())
|
||||
scheduleFiltersComputation()
|
||||
private val filterDeferredLazy: SynchronizedClearableLazy<Deferred<CompositeFilter>> = SynchronizedClearableLazy {
|
||||
startFilterComputation()
|
||||
}
|
||||
|
||||
private fun scheduleFiltersComputation() {
|
||||
if (filtersComputationInProgress.compareAndSet(false, true)) {
|
||||
coroutineScope.launch {
|
||||
val filters = readAction {
|
||||
ConsoleViewUtil.computeConsoleFilters(project, null, GlobalSearchScope.allScope(project))
|
||||
}
|
||||
filtersComputationInProgress.set(false)
|
||||
cachedFilter = CompositeFilter(project, filters).also {
|
||||
it.setForceUseAllFilters(true)
|
||||
}
|
||||
withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
|
||||
fireFiltersUpdated()
|
||||
filtersComputed.complete(Unit)
|
||||
}
|
||||
}
|
||||
init {
|
||||
ConsoleFilterProvider.FILTER_PROVIDERS.addChangeListener(coroutineScope) {
|
||||
dropFilter()
|
||||
}
|
||||
}
|
||||
|
||||
fun addFilter(filter: Filter) {
|
||||
customFilters.add(filter)
|
||||
dropFilter()
|
||||
}
|
||||
|
||||
private fun dropFilter() {
|
||||
cachedFilter = null
|
||||
filterDeferredLazy.drop()
|
||||
if (areFiltersInUse) {
|
||||
// If filters have been requested already, there is some text in the editor.
|
||||
// This text needs to be reprocessed with the updated filters.
|
||||
// Trigger filter recomputation to fire the `filtersUpdated` event.
|
||||
filterDeferredLazy.value
|
||||
}
|
||||
}
|
||||
|
||||
private fun startFilterComputation(): Deferred<CompositeFilter> = coroutineScope.async {
|
||||
val filters = readAction {
|
||||
ConsoleViewUtil.computeConsoleFilters(project, null, GlobalSearchScope.allScope(project))
|
||||
}
|
||||
val compositeFilter = CompositeFilter(project, customFilters + filters).also {
|
||||
it.setForceUseAllFilters(true)
|
||||
}
|
||||
cachedFilter = compositeFilter
|
||||
withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
|
||||
fireFiltersUpdated()
|
||||
}
|
||||
compositeFilter
|
||||
}
|
||||
|
||||
fun addFiltersUpdatedListener(listener: () -> Unit) {
|
||||
filtersUpdatedListeners.add(listener)
|
||||
}
|
||||
@@ -77,12 +85,13 @@ internal class CompositeFilterWrapper(private val project: Project, private val
|
||||
cachedFilter?.let {
|
||||
return it
|
||||
}
|
||||
scheduleFiltersComputation()
|
||||
areFiltersInUse = true
|
||||
filterDeferredLazy.value
|
||||
return null
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
internal suspend fun awaitFiltersComputed() {
|
||||
filtersComputed.await()
|
||||
filterDeferredLazy.value.await()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 org.jetbrains.plugins.terminal.block.reworked.hyperlinks
|
||||
|
||||
import com.intellij.execution.filters.Filter
|
||||
import com.intellij.execution.impl.EditorHyperlinkListener
|
||||
import com.intellij.execution.impl.EditorHyperlinkSupport
|
||||
import com.intellij.execution.impl.ExpirableTokenProvider
|
||||
@@ -79,6 +80,10 @@ class TerminalHyperlinkHighlighter private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun addFilter(filter: Filter) {
|
||||
filterWrapper.addFilter(filter)
|
||||
}
|
||||
|
||||
private fun rehighlightAll() {
|
||||
tokenProvider.invalidateAll()
|
||||
hyperlinkSupport.clearHyperlinks(0, document.textLength)
|
||||
|
||||
Reference in New Issue
Block a user