From 56fd3d3cedc24bc5891d78557155972859003c6d Mon Sep 17 00:00:00 2001 From: David Kincaid Date: Tue, 2 Jan 2024 07:12:56 -0500 Subject: [PATCH] Launching the editor opens a new custom terminal --- package.json | 10 ++++++++ src/extension.ts | 59 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3da1afda1..f277ed1c1 100644 --- a/package.json +++ b/package.json @@ -233,6 +233,16 @@ "default": "godot4", "description": "The absolute path to the Godot 4 editor executable" }, + "godotTools.editor.verbose": { + "type": "boolean", + "default": false, + "description": "Whether to launch the Godot Editor with the --verbose flag" + }, + "godotTools.editor.revealTerminal": { + "type": "boolean", + "default": true, + "description": "Whether to reveal the terminal when launching the Godot Editor" + }, "godotTools.lsp.serverProtocol": { "type": [ "string" diff --git a/src/extension.ts b/src/extension.ts index d47dfcae3..cebcc17da 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,6 +1,6 @@ import * as path from "path"; import * as vscode from "vscode"; -import { attemptSettingsUpdate } from "./utils"; +import { attemptSettingsUpdate, get_extension_uri } from "./utils"; import { GDInlayHintsProvider, GDHoverProvider, @@ -15,7 +15,6 @@ import { ClientConnectionManager } from "./lsp"; import { ScenePreviewProvider } from "./scene_tools"; import { GodotDebugger } from "./debugger"; import { FormattingProvider } from "./formatter"; -import { exec, execSync } from "child_process"; import { get_configuration, find_file, @@ -27,6 +26,7 @@ import { verify_godot_version, } from "./utils"; import { prompt_for_godot_executable } from "./utils/prompts"; +import { killSubProcesses, subProcess } from "./utils/subspawn"; interface Extension { context?: vscode.ExtensionContext; @@ -157,7 +157,24 @@ async function open_workspace_with_editor() { switch (result.status) { case "SUCCESS": { - exec(`${godotPath} --path "${projectDir}" -e`); + let command = `${godotPath} --path "${projectDir}" -e`; + if (get_configuration("editor.verbose")) { + command += " -v"; + } + const existingTerminal = vscode.window.terminals.find(t => t.name === "Godot Editor"); + if (existingTerminal) { + existingTerminal.dispose(); + } + const options: vscode.ExtensionTerminalOptions = { + name: "Godot Editor", + iconPath: get_extension_uri("resources/godot_icon.svg"), + pty: new GodotEditorTerminal(command), + isTransient: true, + }; + const terminal = vscode.window.createTerminal(options); + if (get_configuration("editor.revealTerminal")) { + terminal.show(); + } break; } case "WRONG_VERSION": { @@ -172,3 +189,39 @@ async function open_workspace_with_editor() { } } } + +class GodotEditorTerminal implements vscode.Pseudoterminal { + private writeEmitter = new vscode.EventEmitter(); + onDidWrite: vscode.Event = this.writeEmitter.event; + private closeEmitter = new vscode.EventEmitter(); + onDidClose?: vscode.Event = this.closeEmitter.event; + + constructor(private command: string) { } + + open(initialDimensions: vscode.TerminalDimensions | undefined): void { + const proc = subProcess("GodotEditor", this.command, { shell: true, detached: true }); + this.writeEmitter.fire("Starting Godot Editor process...\r\n"); + + proc.stdout.on("data", (data) => { + const out = data.toString().trim(); + if (out) { + this.writeEmitter.fire(data + "\r\n"); + } + }); + + proc.stderr.on("data", (data) => { + const out = data.toString().trim(); + if (out) { + this.writeEmitter.fire(data + "\r\n"); + } + }); + + proc.on("close", (code) => { + this.writeEmitter.fire(`Godot Editor stopped with exit code: ${code}\r\n`); + }); + } + + close(): void { + killSubProcesses("GodotEditor"); + } +}