How to run command in terminal or how to get access of org.jetbrains.plugins.terminal.ShellTerminalWidget?

Answered

I would like to create the RunConfiguration which will run command in intergrated terminal and its provides. By the word “provider” I mean powershell.exe or cmd.exe. I found how to run the command line using GlobalCommandLine or PtyCommandLine, but it's creates the process when I want to run command using cmd.exe or powershell.exe provider. I found new answer with strange class ShTerminalRunner, but it uses ShellTerminalWidget which located in org.jetbrains.plugins.terminal package and I can't access it from SDK Plugin (Or can, but I don't know how). Can we help me?

0
2 comments

Solved the code, but I already have an unfinished tasks. I've been added these to plugins:

"terminal",
"sh"

The code compiling problems is solved, but if I run the my RunConfiguration I will get an error:

java.lang.NoClassDefFoundError: org/jetbrains/plugins/terminal/TerminalToolWindowManager

Code:

import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.NlsContexts.TabTitle
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.ui.content.Content
import com.intellij.ui.content.ContentManager
import org.jetbrains.plugins.terminal.ShellTerminalWidget
import org.jetbrains.plugins.terminal.TerminalToolWindowFactory
import org.jetbrains.plugins.terminal.TerminalToolWindowManager
import org.jetbrains.plugins.terminal.arrangement.TerminalWorkingDirectoryManager
import java.io.IOException
import java.util.*

// From https://github.com/JetBrains/intellij-community/blob/master/plugins/sh/terminal/src/com/intellij/sh/run/terminal/ShTerminalRunner.java#L11
class ShTerminalRunner {

    private val LOG = Logger.getInstance(ShTerminalRunner::class.java)

    fun run(
        project: Project,
        command: String,
        workingDirectory: String,
        title: @TabTitle String,
        activateToolWindow: Boolean
    ) {
        val terminalToolWindowManager = TerminalToolWindowManager.getInstance(project)
        val window = ToolWindowManager.getInstance(project).getToolWindow(TerminalToolWindowFactory.TOOL_WINDOW_ID)
            ?: return
        val contentManager = window.contentManager
        val pair = getSuitableProcess(
            contentManager,
            workingDirectory
        )
        try {
            if (pair == null) {
                terminalToolWindowManager.createLocalShellWidget(
                    workingDirectory,
                    title,
                    activateToolWindow,
                    activateToolWindow
                ).executeCommand(command)
                return
            }
            if (activateToolWindow) {
                window.activate(null)
            }
            pair.first.displayName = title
            contentManager.setSelectedContent(pair.first)
            pair.second.executeCommand(command)
        } catch (e: IOException) {
            LOG.warn("Cannot run command:$command", e)
        }
    }

    private fun getSuitableProcess(
        contentManager: ContentManager,
        workingDirectory: String
    ): Pair<Content, ShellTerminalWidget>? {
        val selectedContent = contentManager.selectedContent
        if (selectedContent != null)
            return getSuitableProcess(selectedContent, workingDirectory)

        return Arrays.stream(contentManager.contents)
            .map { content -> getSuitableProcess(content, workingDirectory) }
            .filter(Objects::nonNull)
            .findFirst()
            .orElse(null)
    }

    private fun getSuitableProcess(
        content: Content,
        workingDirectory: String
    ): Pair<Content, ShellTerminalWidget>? {
        val widget = TerminalToolWindowManager.getWidgetByContent(content) as? ShellTerminalWidget ?: return null
        if (widget.typedShellCommand.isNotEmpty() || widget.hasRunningCommands())
            return null

        val currentWorkingDirectory = TerminalWorkingDirectoryManager.getWorkingDirectory(widget.asNewWidget())
        return if (!FileUtil.pathsEqual(workingDirectory, currentWorkingDirectory)) {
            null
        } else Pair(content, widget)
    }
}
0

As usual, my mistake was due to inattention. I just forgot to add the tag to plugin.xml, I understand it from here

After adding this tag:

<depends>org.jetbrains.plugins.terminal</depends>

My problem is solved

0

Please sign in to leave a comment.