(command: string, callbacks: RooTerminalCallbacks)
| 79 | } |
| 80 | |
| 81 | public override runCommand(command: string, callbacks: RooTerminalCallbacks): RooTerminalProcessResultPromise { |
| 82 | // We set busy before the command is running because the terminal may be |
| 83 | // waiting on terminal integration, and we must prevent another instance |
| 84 | // from selecting the terminal for use during that time. |
| 85 | this.busy = true |
| 86 | |
| 87 | const process = new TerminalProcess(this) |
| 88 | process.command = command |
| 89 | this.process = process |
| 90 | |
| 91 | // Set up event handlers from callbacks before starting process. |
| 92 | // This ensures that we don't miss any events because they are |
| 93 | // configured before the process starts. |
| 94 | process.on("line", (line) => callbacks.onLine(line, process)) |
| 95 | process.once("completed", (output) => callbacks.onCompleted(output, process)) |
| 96 | process.once("shell_execution_started", (pid) => callbacks.onShellExecutionStarted(pid, process)) |
| 97 | process.once("shell_execution_complete", (details) => callbacks.onShellExecutionComplete(details, process)) |
| 98 | process.once("no_shell_integration", (details) => callbacks.onNoShellIntegration?.(details, process)) |
| 99 | |
| 100 | const promise = new Promise<void>((resolve, reject) => { |
| 101 | // Set up event handlers |
| 102 | process.once("continue", () => resolve()) |
| 103 | process.once("error", (error) => { |
| 104 | console.error(`[Terminal ${this.id}] error:`, error) |
| 105 | reject(error) |
| 106 | }) |
| 107 | |
| 108 | if (Terminal.isActiveShellCmdExe()) { |
| 109 | // Keep this defensive fallback for callers that invoke Terminal.runCommand() |
| 110 | // directly instead of routing through executeCommandInTerminal(). |
| 111 | // cmd.exe cannot emit OSC 633;A — skip the timeout entirely and go |
| 112 | // straight to the execa fallback (VS Code issue #164646). |
| 113 | ShellIntegrationManager.zshCleanupTmpDir(this.id) |
| 114 | process.emit("no_shell_integration", { |
| 115 | message: |
| 116 | "cmd.exe does not support shell integration (VS Code issue #164646). Command will run via fallback.", |
| 117 | commandSubmitted: false, |
| 118 | }) |
| 119 | } else { |
| 120 | // Wait for shell integration before executing the command |
| 121 | pWaitFor(() => this.terminal.shellIntegration !== undefined, { |
| 122 | timeout: Terminal.getShellIntegrationTimeout(), |
| 123 | }) |
| 124 | .then(() => { |
| 125 | // Clean up temporary directory if shell integration is available, zsh did its job: |
| 126 | ShellIntegrationManager.zshCleanupTmpDir(this.id) |
| 127 | |
| 128 | // Run the command in the terminal |
| 129 | process.run(command) |
| 130 | }) |
| 131 | .catch(() => { |
| 132 | console.log(`[Terminal ${this.id}] Shell integration not available. Command execution aborted.`) |
| 133 | |
| 134 | // Clean up temporary directory if shell integration is not available |
| 135 | ShellIntegrationManager.zshCleanupTmpDir(this.id) |
| 136 | |
| 137 | process.emit("no_shell_integration", { |
| 138 | message: `Shell integration initialization sequence '\\x1b]633;A' was not received within ${Terminal.getShellIntegrationTimeout() / 1000}s. Shell integration has been disabled for this terminal instance. Increase the timeout in the settings if necessary.`, |
no test coverage detected