From d0a4e16b0b29efef99baa507b7224c4704c8339a Mon Sep 17 00:00:00 2001 From: Konstantin Hudyakov Date: Wed, 18 Jun 2025 10:56:09 +0300 Subject: [PATCH] [terminal] IJPL-192386 Add an ability to get terminal text from the TerminalWidget Support the classic terminal, new terminal (gen1) and the reworked terminal (gen2). This method is the fast solution, but probably not final, since we plan to have a better public API for the Reworked Terminal. So, mark it as experimental. GitOrigin-RevId: 1bae3499a909b4b9447af0b734a87eda53e8d67d --- platform/execution-impl/api-dump-experimental.txt | 1 + .../src/com/intellij/terminal/JBTerminalWidget.java | 5 +++++ .../src/com/intellij/terminal/ui/TerminalWidget.kt | 9 +++++++++ .../intellij/terminal/frontend/ReworkedTerminalView.kt | 4 ++++ .../intellij/terminal/frontend/ReworkedTerminalWidget.kt | 4 ++++ .../plugins/terminal/block/BlockTerminalView.kt | 8 ++++++++ .../plugins/terminal/block/OldPlainTerminalView.kt | 4 ++++ .../plugins/terminal/block/PlainTerminalView.kt | 4 ++++ .../plugins/terminal/block/SimpleTerminalView.kt | 4 ++++ .../plugins/terminal/block/TerminalContentView.kt | 6 ++++++ .../plugins/terminal/block/TerminalWidgetImpl.kt | 8 ++++++++ 11 files changed, 57 insertions(+) diff --git a/platform/execution-impl/api-dump-experimental.txt b/platform/execution-impl/api-dump-experimental.txt index 699973d41bb2..94b3fcdf0bb7 100644 --- a/platform/execution-impl/api-dump-experimental.txt +++ b/platform/execution-impl/api-dump-experimental.txt @@ -25,4 +25,5 @@ f:com.intellij.execution.util.EnvFilesUtilKt com.intellij.terminal.ui.TerminalWidget - com.intellij.openapi.ui.ComponentContainer - *a:getTerminalSizeInitializedFuture():java.util.concurrent.CompletableFuture +- *:getText():java.lang.CharSequence - *:isCommandRunning():Z diff --git a/platform/execution-impl/src/com/intellij/terminal/JBTerminalWidget.java b/platform/execution-impl/src/com/intellij/terminal/JBTerminalWidget.java index e81328c1a362..8b6d67467157 100644 --- a/platform/execution-impl/src/com/intellij/terminal/JBTerminalWidget.java +++ b/platform/execution-impl/src/com/intellij/terminal/JBTerminalWidget.java @@ -429,6 +429,11 @@ public class JBTerminalWidget extends JediTermWidget implements Disposable, UiCo } } + @Override + public @NotNull CharSequence getText() { + return widget().getText(); + } + @Override public boolean isCommandRunning() { try { diff --git a/platform/execution-impl/src/com/intellij/terminal/ui/TerminalWidget.kt b/platform/execution-impl/src/com/intellij/terminal/ui/TerminalWidget.kt index 16ba910e88a9..99fce0ae9c70 100644 --- a/platform/execution-impl/src/com/intellij/terminal/ui/TerminalWidget.kt +++ b/platform/execution-impl/src/com/intellij/terminal/ui/TerminalWidget.kt @@ -72,6 +72,15 @@ interface TerminalWidget : ComponentContainer { @RequiresEdt(generateAssertion = false) fun sendCommandToExecute(shellCommand: String) + /** + * Returns the **immutable** state of the terminal output text. + */ + @ApiStatus.Experimental + @RequiresEdt(generateAssertion = false) + fun getText(): CharSequence { + return "" + } + /** * Note that implementations might not guarantee that the result is 100% correct. */ diff --git a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/ReworkedTerminalView.kt b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/ReworkedTerminalView.kt index 4ba847bf1e39..2c7cf7e921de 100644 --- a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/ReworkedTerminalView.kt +++ b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/ReworkedTerminalView.kt @@ -199,6 +199,10 @@ internal class ReworkedTerminalView( terminalInput.sendBytes(bytes) } + override fun getText(): CharSequence { + return getCurEditor().document.immutableCharSequence + } + override fun isCommandRunning(): Boolean { // Will work only if there is a shell integration. // If there is no shell integration, then it is always false. diff --git a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/ReworkedTerminalWidget.kt b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/ReworkedTerminalWidget.kt index 21fa8ab0613d..1c8c6e519ec0 100644 --- a/plugins/terminal/frontend/src/com/intellij/terminal/frontend/ReworkedTerminalWidget.kt +++ b/plugins/terminal/frontend/src/com/intellij/terminal/frontend/ReworkedTerminalWidget.kt @@ -68,6 +68,10 @@ internal class ReworkedTerminalWidget( view.sendCommandToExecute(shellCommand) } + override fun getText(): CharSequence { + return view.getText() + } + override fun isCommandRunning(): Boolean { return view.isCommandRunning() } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/BlockTerminalView.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/BlockTerminalView.kt index a73c2b7ee7cc..406b31e74718 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/BlockTerminalView.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/BlockTerminalView.kt @@ -294,6 +294,14 @@ class BlockTerminalView( controller.startCommandExecution(shellCommand) } + override fun getText(): CharSequence { + alternateBufferView?.let { return it.getText() } + + val outputText = outputView.controller.outputModel.editor.document.text + val promptText = promptView.controller.model.editor.document.text + return "$outputText\n$promptText" + } + override fun dispose() {} private fun getDisposed(): () -> Boolean = outputView.controller.outputModel.editor.getDisposed() diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/OldPlainTerminalView.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/OldPlainTerminalView.kt index c4437b1fa62e..a3d1b4f58c3c 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/OldPlainTerminalView.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/OldPlainTerminalView.kt @@ -57,5 +57,9 @@ internal class OldPlainTerminalView(project: Project, widget.executeCommand(shellCommand) } + override fun getText(): CharSequence { + return widget.text + } + override fun dispose() {} } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/PlainTerminalView.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/PlainTerminalView.kt index ef51dec688ab..20b6083e1019 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/PlainTerminalView.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/PlainTerminalView.kt @@ -73,5 +73,9 @@ internal class PlainTerminalView( session.commandExecutionManager.sendCommandToExecute(shellCommand) } + override fun getText(): CharSequence { + return view.getText() + } + override fun dispose() {} } diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/SimpleTerminalView.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/SimpleTerminalView.kt index 645f3df547e8..5dc2527dded4 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/SimpleTerminalView.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/SimpleTerminalView.kt @@ -81,6 +81,10 @@ internal class SimpleTerminalView( fun isFocused(): Boolean = editor.contentComponent.hasFocus() + fun getText(): CharSequence { + return editor.document.immutableCharSequence + } + override fun dispose() { EditorFactory.getInstance().releaseEditor(editor) Disposer.dispose(controller) diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/TerminalContentView.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/TerminalContentView.kt index 28e04d4fea8f..fd6d5d88c55b 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/TerminalContentView.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/TerminalContentView.kt @@ -32,6 +32,12 @@ interface TerminalContentView : Disposable { @RequiresEdt(generateAssertion = false) fun sendCommandToExecute(shellCommand: String) + /** + * Returns the **immutable** state of the terminal output text. + */ + @RequiresEdt(generateAssertion = false) + fun getText(): CharSequence + @RequiresEdt(generateAssertion = false) fun isCommandRunning(): Boolean { return false diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/TerminalWidgetImpl.kt b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/TerminalWidgetImpl.kt index f33ae9675ecb..ebb5808a49ca 100644 --- a/plugins/terminal/src/org/jetbrains/plugins/terminal/block/TerminalWidgetImpl.kt +++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/block/TerminalWidgetImpl.kt @@ -124,6 +124,10 @@ internal class TerminalWidgetImpl( view.sendCommandToExecute(shellCommand) } + override fun getText(): CharSequence { + return view.getText() + } + override fun isCommandRunning(): Boolean { val connector = ttyConnector ?: return false return TerminalUtil.hasRunningCommands(connector) @@ -181,6 +185,10 @@ internal class TerminalWidgetImpl( postponedShellCommands.add(shellCommand) } + override fun getText(): CharSequence { + return "" + } + fun moveTerminationCallbacksTo(destView: TerminalContentView) { for (info in postponedTerminationCallbackInfos) { destView.addTerminationCallback(info.first, info.second)