Move useful terminal methods to component, remove old addon registration
This commit is contained in:
parent
eda3a8e7bc
commit
fbcb02a863
3 changed files with 65 additions and 45 deletions
|
|
@ -5,68 +5,53 @@
|
|||
@inject ScriptDebugger Debugger
|
||||
|
||||
<div class="terminal @(Visible ? "" : "hidden")">
|
||||
<Xterm @ref="Terminal" Options="_options" OnFirstRender="@OnFirstRender" Addons="@Addons" />
|
||||
<Terminal @ref="_terminal" Options="_options" OnFirstRender="@OnFirstRender" Addons="@_addons" />
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool Visible { get; set; } = false;
|
||||
private Xterm Terminal;
|
||||
private TaskCompletionSource<string> InputTaskCompletionSource;
|
||||
private bool Visible { get; set; }
|
||||
private Terminal? _terminal;
|
||||
|
||||
private TerminalOptions _options = new TerminalOptions
|
||||
private TerminalOptions _options = new()
|
||||
{
|
||||
CursorBlink = true,
|
||||
CursorStyle = CursorStyle.Bar,
|
||||
};
|
||||
|
||||
private HashSet<string> Addons = new HashSet<string>()
|
||||
private HashSet<string> _addons = new()
|
||||
{
|
||||
"readline",
|
||||
"addon-fit"
|
||||
};
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Debugger.OnDebugStart = async (ps) =>
|
||||
Debugger.OnDebugStart = async _ =>
|
||||
{
|
||||
Terminal?.Clear();
|
||||
if (_terminal is null)
|
||||
return;
|
||||
|
||||
await _terminal.Clear();
|
||||
Visible = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await Terminal.Addon("addon-fit").InvokeVoidAsync("fit");
|
||||
await _terminal.FitAsync();
|
||||
};
|
||||
|
||||
Debugger.OnOutput = async (level, message) =>
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case LogLevel.Error:
|
||||
await Terminal.WriteLine($"\x1b[0;31m{message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Warning:
|
||||
await Terminal.WriteLine($"\x1b[0;33m{message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Debug:
|
||||
await Terminal.WriteLine($"\x1b[0;37m{message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Trace:
|
||||
await Terminal.WriteLine($"\x1b[0;36m{message}");
|
||||
break;
|
||||
|
||||
case LogLevel.Information:
|
||||
await Terminal.WriteLine($"\x1b[0;37m{message}");
|
||||
break;
|
||||
}
|
||||
if (_terminal is not null)
|
||||
await _terminal.WriteLine(message, level);
|
||||
};
|
||||
|
||||
Debugger.OnDebugBreak = async (context) =>
|
||||
Debugger.OnDebugBreak = async context =>
|
||||
{
|
||||
if (_terminal is null)
|
||||
return;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var input = await ReadLine();
|
||||
var input = await _terminal.ReadLineAsync();
|
||||
|
||||
if (input.Trim().Equals("exit", StringComparison.OrdinalIgnoreCase))
|
||||
break;
|
||||
|
|
@ -84,11 +69,7 @@
|
|||
|
||||
private async Task OnFirstRender()
|
||||
{
|
||||
await Terminal.Addon("addon-fit").InvokeVoidAsync("fit");
|
||||
}
|
||||
|
||||
private async Task<string> ReadLine()
|
||||
{
|
||||
return await Terminal.Addon("readline").InvokeAsync<string>("read", "> ");
|
||||
if (_terminal is not null)
|
||||
await _terminal.FitAsync();
|
||||
}
|
||||
}
|
||||
|
|
@ -38,11 +38,6 @@
|
|||
<script src="_framework/blazor.webview.js"></script>
|
||||
|
||||
<script>
|
||||
XtermBlazor.registerAddons({
|
||||
"readline": new XtermAddons.Readline(),
|
||||
"addon-fit": new XtermAddons.Fit()
|
||||
});
|
||||
|
||||
window.sendMessage = function (message) {
|
||||
window.external.sendMessage(message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using LANCommander.UI.Extensions;
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using XtermBlazor;
|
||||
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
|
||||
|
||||
namespace LANCommander.UI.Components;
|
||||
|
||||
|
|
@ -16,4 +17,47 @@ public partial class Terminal : Xterm
|
|||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await JS.ExecuteVoidAsync("RegisterXtermAddons");
|
||||
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
|
||||
if (firstRender)
|
||||
await FitAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a line to the terminal with a specified log level
|
||||
/// </summary>
|
||||
/// <param name="message">Message to send</param>
|
||||
/// <param name="level">LogLevel to write</param>
|
||||
public async Task WriteLine(string message, LogLevel level = LogLevel.Information)
|
||||
{
|
||||
var code = level switch
|
||||
{
|
||||
LogLevel.Error => 31,
|
||||
LogLevel.Warning => 33,
|
||||
LogLevel.Debug => 37,
|
||||
LogLevel.Trace => 36,
|
||||
LogLevel.Information => 37,
|
||||
_ => 37,
|
||||
};
|
||||
|
||||
await base.WriteLine($"\x1b[0;{code}m{message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rerenders the terminal and changes the size to fit within the element's rect. Utilizes the `addon-fit` addon.
|
||||
/// </summary>
|
||||
public async Task FitAsync()
|
||||
=> await Addon("addon-fit").InvokeVoidAsync("fit");
|
||||
|
||||
/// <summary>
|
||||
/// Wait for user input in the terminal
|
||||
/// </summary>
|
||||
/// <param name="prefix"></param>
|
||||
public async Task<string> ReadLineAsync(string prefix = "> ")
|
||||
=> await Addon("readline").InvokeAsync<string>("read", prefix);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue