[terminal] IJPL-178962 Hyperlinks: get rid of lists of events where not needed

The whole List<Event> thing exists only on the higher level,
and not even used for anything practical at the moment.
Let's not propagate this approach to lower level stuff
unless needed.

This might be reverted if we actually start to process EDT events
in bulks on the frontend side, then we can send several events
at once.

GitOrigin-RevId: 949dac5fb986be0a78c1a6afdd3008d984623f9f
This commit is contained in:
Sergei Tachenov
2025-07-29 08:27:10 +00:00
committed by intellij-monorepo-bot
parent 2b936d0dea
commit cfe8a8159e
4 changed files with 11 additions and 6 deletions
@@ -14,6 +14,7 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import org.jetbrains.plugins.terminal.block.reworked.*
import org.jetbrains.plugins.terminal.block.reworked.hyperlinks.isSplitHyperlinksSupportEnabled
@@ -92,7 +93,11 @@ internal class StateAwareTerminalSession(
coroutineScope.launch(CoroutineName("StateAwareTerminalSession: models updating")) {
val originalOutputFlow = if (outputHyperlinkFacade != null && alternateBufferHyperlinkFacade != null) {
merge(delegate.getOutputFlow(), outputHyperlinkFacade.resultFlow, alternateBufferHyperlinkFacade.resultFlow)
merge(
delegate.getOutputFlow(),
outputHyperlinkFacade.resultFlow.map { listOf(it) },
alternateBufferHyperlinkFacade.resultFlow.map { listOf(it) },
)
}
else {
delegate.getOutputFlow()
@@ -25,7 +25,7 @@ internal class BackendTerminalHyperlinkFacade(
private val highlighter = BackendTerminalHyperlinkHighlighter(project, coroutineScope, outputModel, isInAlternateBuffer)
private val model = TerminalHyperlinksModel(if (isInAlternateBuffer) "Backend AltBuf" else "Backend Output", outputModel)
val resultFlow: Flow<List<TerminalHyperlinksChangedEvent>> get() = highlighter.resultFlow
val resultFlow: Flow<TerminalHyperlinksChangedEvent> get() = highlighter.resultFlow
fun updateModelState(event: TerminalHyperlinksChangedEvent): Boolean {
if (event.documentModificationStamp < outputModel.document.modificationStamp) return false
@@ -45,7 +45,7 @@ internal class BackendTerminalHyperlinkHighlighter(
private val highlightTask = MutableStateFlow<HighlightTask?>(highlightAllTask())
private val filterWrapper = CompositeFilterWrapper(project, coroutineScope)
val resultFlow: Flow<List<TerminalHyperlinksChangedEvent>>
val resultFlow: Flow<TerminalHyperlinksChangedEvent>
get() = channelFlow {
val channel = this
// asynchronous because we don't want to block the main event processing coroutine
@@ -116,7 +116,7 @@ internal class BackendTerminalHyperlinkHighlighter(
private val outputModel: FrozenTerminalOutputModel,
val startOffset: TerminalOffset,
) {
suspend fun run(filter: CompositeFilter, channel: SendChannel<List<TerminalHyperlinksChangedEvent>>) {
suspend fun run(filter: CompositeFilter, channel: SendChannel<TerminalHyperlinksChangedEvent>) {
val document = outputModel.document
val firstID = hyperlinkId.get() + 1
var firstOffset: TerminalOffset? = null
@@ -148,7 +148,7 @@ internal class BackendTerminalHyperlinkHighlighter(
require(!(firstBatch && lastBatch))
if (results.isNotEmpty() || firstBatch || lastBatch) {
val event = createEvent(results, firstBatch)
channel.send(listOf(event))
channel.send(event)
logEvent(event)
}
}
@@ -315,7 +315,7 @@ internal class BackendTerminalHyperlinkHighlighterTest : BasePlatformTestCase()
// do what StateAwareTerminalSession does, but with less infrastructure around
val eventJob = launch(CoroutineName("BackendTerminalHyperlinkHighlighterTest event processing"), start = UNDISPATCHED) {
merge(updateEvents, backendFacade.resultFlow).collect { events ->
merge(updateEvents, backendFacade.resultFlow.map { listOf(it) }).collect { events ->
events.forEach { event ->
when (event) {
is TerminalContentUpdatedEvent -> {