mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
terminal: simplify scraping output (IJ-CR-121332)
GitOrigin-RevId: 927d3066c83eb475695e9614808dadb05988d134
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8017a66973
commit
9241925fa9
@@ -52,7 +52,7 @@ internal class ShellCommandOutputScraper(private val session: TerminalSession,
|
||||
|
||||
fun scrapeOutput(): StyledCommandOutput {
|
||||
session.model.withContentLock {
|
||||
val outputBuilder = OutputBuilder(textBuffer.width)
|
||||
val outputBuilder = OutputBuilder()
|
||||
if (!textBuffer.isUsingAlternateBuffer) {
|
||||
outputBuilder.addLines(textBuffer.historyBuffer)
|
||||
}
|
||||
@@ -62,11 +62,10 @@ internal class ShellCommandOutputScraper(private val session: TerminalSession,
|
||||
}
|
||||
}
|
||||
|
||||
private class OutputBuilder(private val columns: Int) {
|
||||
private class OutputBuilder {
|
||||
private val output: StringBuilder = StringBuilder()
|
||||
private val styles: MutableList<StyleRange> = mutableListOf()
|
||||
private var pendingNewLines: Int = 0
|
||||
private var pendingNuls: Int = 0
|
||||
|
||||
fun addLines(linesBuffer: LinesBuffer) {
|
||||
for (i in 0 until linesBuffer.lineCount) {
|
||||
@@ -75,26 +74,13 @@ private class OutputBuilder(private val columns: Int) {
|
||||
}
|
||||
|
||||
private fun addLine(line: TerminalLine) {
|
||||
var addedLength = 0
|
||||
line.forEachEntry { entry ->
|
||||
val charBuffer: CharBuffer = entry.text
|
||||
val length = charBuffer.length
|
||||
addedLength += length
|
||||
if (length > 0) {
|
||||
if (entry.isNul) {
|
||||
pendingNuls += length
|
||||
}
|
||||
else {
|
||||
addTextChunk(charBuffer.normalize(), entry.style)
|
||||
}
|
||||
if (entry.text.isNotEmpty() && !entry.isNul) {
|
||||
addTextChunk(entry.text.normalize(), entry.style)
|
||||
}
|
||||
}
|
||||
if (line.isWrapped) {
|
||||
pendingNuls += (columns - addedLength).coerceAtLeast(0)
|
||||
}
|
||||
else {
|
||||
if (!line.isWrapped) {
|
||||
pendingNewLines++
|
||||
pendingNuls = 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,10 +95,6 @@ private class OutputBuilder(private val columns: Int) {
|
||||
output.append("\n")
|
||||
}
|
||||
pendingNewLines = 0
|
||||
repeat(pendingNuls) {
|
||||
output.append(' ')
|
||||
}
|
||||
pendingNuls = 0
|
||||
val startOffset = output.length
|
||||
output.append(text)
|
||||
if (style != TextStyle.EMPTY) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.testFramework.ProjectRule
|
||||
import com.intellij.testFramework.RuleChain
|
||||
import com.jediterm.core.util.TermSize
|
||||
import kotlinx.coroutines.*
|
||||
import org.jetbrains.plugins.terminal.block.testApps.MoveCursorToLineEndAndPrint
|
||||
import org.jetbrains.plugins.terminal.block.testApps.SimpleTextRepeater
|
||||
import org.jetbrains.plugins.terminal.exp.*
|
||||
import org.jetbrains.plugins.terminal.exp.completion.IJShellRuntimeDataProvider
|
||||
@@ -118,6 +119,39 @@ class BlockTerminalTest(private val shellPath: String) {
|
||||
assertCommandResult(0, SimpleTextRepeater.Helper.getExpectedOutput(items), outputFuture)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `mix of empty area and text #1`() {
|
||||
val termSize = TermSize(10, 10)
|
||||
val session = startBlockTerminalSession(termSize)
|
||||
val outputFuture: CompletableFuture<CommandResult> = getCommandResultFuture(session)
|
||||
val textsToPrint = listOf("foo")
|
||||
session.sendCommandToExecuteWithoutAddingToHistory(MoveCursorToLineEndAndPrint.Helper.generateCommandLine(textsToPrint))
|
||||
assertCommandResult(0, MoveCursorToLineEndAndPrint.Helper.getExpectedOutput(termSize, textsToPrint), outputFuture)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `mix of empty area and text #2`() {
|
||||
val termSize = TermSize(10, 10)
|
||||
val session = startBlockTerminalSession(termSize)
|
||||
val outputFuture: CompletableFuture<CommandResult> = getCommandResultFuture(session)
|
||||
val textsToPrint = listOf("foo", "a".repeat(termSize.columns + 1), "b")
|
||||
session.sendCommandToExecuteWithoutAddingToHistory(MoveCursorToLineEndAndPrint.Helper.generateCommandLine(textsToPrint))
|
||||
assertCommandResult(0, MoveCursorToLineEndAndPrint.Helper.getExpectedOutput(termSize, textsToPrint), outputFuture)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `mix of empty area and text #3`() {
|
||||
val termSize = TermSize(15, 15)
|
||||
val session = startBlockTerminalSession(termSize)
|
||||
val outputFuture: CompletableFuture<CommandResult> = getCommandResultFuture(session)
|
||||
val textsToPrint = ('a'..'z').map {
|
||||
val cnt = it - 'a'
|
||||
it.toString().repeat(cnt) + cnt.toString()
|
||||
}
|
||||
session.sendCommandToExecuteWithoutAddingToHistory(MoveCursorToLineEndAndPrint.Helper.generateCommandLine(textsToPrint))
|
||||
assertCommandResult(0, MoveCursorToLineEndAndPrint.Helper.getExpectedOutput(termSize, textsToPrint), outputFuture)
|
||||
}
|
||||
|
||||
private fun createCommandSentDeferred(session: TerminalSession): CompletableDeferred<Unit> {
|
||||
val generatorCommandSent = CompletableDeferred<Unit>()
|
||||
val generatorCommandSentDisposable = Disposer.newDisposable().also { disposable ->
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2000-2023 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.testApps
|
||||
|
||||
import com.jediterm.core.util.TermSize
|
||||
import org.jetbrains.plugins.terminal.exp.util.TerminalSessionTestUtil
|
||||
|
||||
object MoveCursorToLineEndAndPrint {
|
||||
|
||||
@JvmStatic
|
||||
fun main(arg: Array<String>) {
|
||||
check(arg.isNotEmpty()) { "One or more arguments are expected, got " + arg.size }
|
||||
for (textToPrint in arg) {
|
||||
check(textToPrint.isNotEmpty())
|
||||
// [java.io.Console] doesn't provide terminal width =>
|
||||
// To place the cursor at the line end, move the cursor far away to the right - it should stop as it reaches the edge.
|
||||
val infiniteWidth = 10000
|
||||
print("\u001b[${infiniteWidth}C")
|
||||
print(textToPrint)
|
||||
}
|
||||
println() // new line to get rid of trailing '%' in zsh
|
||||
}
|
||||
|
||||
object Helper {
|
||||
fun generateCommandLine(textsToPrint: List<String>): String {
|
||||
return TerminalSessionTestUtil.getJavaShellCommand(MoveCursorToLineEndAndPrint::class.java, *textsToPrint.toTypedArray())
|
||||
}
|
||||
|
||||
fun getExpectedOutput(termSize: TermSize, textsToPrint: List<String>): String {
|
||||
return " ".repeat(termSize.columns - 1) + textsToPrint.dropLast(1).joinToString("") {
|
||||
val emptyColumns = termSize.columns - (it.length - 1) % termSize.columns
|
||||
check(emptyColumns > 0)
|
||||
if (emptyColumns == termSize.columns) {
|
||||
it.dropLast(1) // string ends at the right edge
|
||||
}
|
||||
else {
|
||||
it + " ".repeat(emptyColumns - 1)
|
||||
}
|
||||
} + textsToPrint.last() + System.lineSeparator()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user