initial commit
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using Godot.Collections;
|
||||
|
||||
[Tool]
|
||||
public partial class TerminalTextEdit : TextEdit
|
||||
{
|
||||
private Dictionary _psProcess = new Dictionary();
|
||||
private FileAccess _psOutputPipe;
|
||||
private FileAccess _psInputPipe;
|
||||
|
||||
// Track historical boundaries so users can't delete past output
|
||||
private int _protectedLine = 0;
|
||||
private int _protectedColumn = 0;
|
||||
private bool _isUpdatingText = false;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
// Initial setup
|
||||
Text = "ReEdit Terminal - 0.1.3\nWindows PowerShell\nCopyright (C) Microsoft Corporation. All rights reserved.\n\nTry the new cross-platform PowerShell https://aka.ms/pscore6\n\n";
|
||||
_protectedLine = GetLineCount() - 1;
|
||||
_protectedColumn = GetLine(_protectedLine).Length;
|
||||
|
||||
// Force caret to the active prompt area
|
||||
SetCaretLine(_protectedLine);
|
||||
SetCaretColumn(_protectedColumn);
|
||||
|
||||
TextChanged += OnTextChanged;
|
||||
StartPowerShell();
|
||||
}
|
||||
|
||||
private void StartPowerShell()
|
||||
{
|
||||
var args = new string[] {
|
||||
"-NoExit",
|
||||
"-NoProfile",
|
||||
"-Command",
|
||||
"$OutputEncoding = [System.Text.Encoding]::UTF8"
|
||||
};
|
||||
|
||||
_psProcess = OS.ExecuteWithPipe("powershell.exe", args);
|
||||
|
||||
if (_psProcess.Count == 0)
|
||||
{
|
||||
AppendSystemText("\n[Error: Failed to initialize PowerShell process.]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
_psOutputPipe = (FileAccess)_psProcess["stdio"];
|
||||
_psInputPipe = (FileAccess)_psProcess["stdio"];
|
||||
}
|
||||
|
||||
public override void _GuiInput(InputEvent @event)
|
||||
{
|
||||
if (@event is InputEventKey keyEvent && keyEvent.Pressed)
|
||||
{
|
||||
if (keyEvent.Keycode == Key.Backspace)
|
||||
{
|
||||
if (GetCaretLine() < _protectedLine ||
|
||||
(GetCaretLine() == _protectedLine && GetCaretColumn() <= _protectedColumn))
|
||||
{
|
||||
AcceptEvent(); // Kill the input event before it acts
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyEvent.Keycode == Key.Enter || keyEvent.Keycode == Key.KpEnter)
|
||||
{
|
||||
string activeLine = GetLine(GetCaretLine());
|
||||
string command = activeLine.Substring(_protectedColumn).Trim();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(command) && _psInputPipe != null)
|
||||
{
|
||||
_psInputPipe.StoreLine(command);
|
||||
}
|
||||
|
||||
_isUpdatingText = true;
|
||||
InsertTextAtCaret("\n");
|
||||
_protectedLine = GetLineCount() - 1;
|
||||
_protectedColumn = 0;
|
||||
_isUpdatingText = false;
|
||||
|
||||
AcceptEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTextChanged()
|
||||
{
|
||||
if (_isUpdatingText) return;
|
||||
|
||||
if (GetCaretLine() < _protectedLine ||
|
||||
(GetCaretLine() == _protectedLine && GetCaretColumn() < _protectedColumn))
|
||||
{
|
||||
_isUpdatingText = true;
|
||||
SetCaretLine(_protectedLine);
|
||||
SetCaretColumn(GetLine(_protectedLine).Length);
|
||||
_isUpdatingText = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (_psOutputPipe != null && _psOutputPipe.GetLength() > 0)
|
||||
{
|
||||
string newText = _psOutputPipe.GetAsText();
|
||||
if (!string.IsNullOrEmpty(newText))
|
||||
{
|
||||
AppendSystemText(newText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendSystemText(string incoming)
|
||||
{
|
||||
_isUpdatingText = true;
|
||||
|
||||
int oldCaretLine = GetCaretLine();
|
||||
int oldCaretCol = GetCaretColumn();
|
||||
SetCaretLine(GetLineCount() - 1);
|
||||
SetCaretColumn(GetLine(GetLineCount() - 1).Length);
|
||||
InsertTextAtCaret(incoming);
|
||||
_protectedLine = GetLineCount() - 1;
|
||||
_protectedColumn = GetLine(_protectedLine).Length;
|
||||
SetCaretLine(_protectedLine);
|
||||
SetCaretColumn(_protectedColumn);
|
||||
|
||||
_isUpdatingText = false;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (_psProcess.Count > 0 && _psProcess.ContainsKey("pid"))
|
||||
{
|
||||
int pid = (int)_psProcess["pid"];
|
||||
OS.Kill(pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user