noz-cli/NozCli/Repl/ReplSession.cs
2026-05-16 19:25:39 +02:00

62 lines
2.1 KiB
C#

using NozCli.Core.Client;
using NozCli.Core.Config;
using NozCli.Core.Models;
using Spectre.Console;
namespace NozCli.Repl;
public static class ReplSession
{
public static async Task RunAsync(LocalConfig config)
{
using var api = new NozApiClient(config);
ServerCapabilities caps = default!;
await AnsiConsole.Status().StartAsync("Connecting…", async _ =>
caps = await api.GetConfigAsync());
AnsiConsole.MarkupLine($"[bold green]noz[/] [dim]· {caps.Server}[/]");
AnsiConsole.MarkupLine($"[dim]push={caps.AllowPush} delete={caps.AllowDelete} vault={caps.AllowVault}[/]\n");
var ctx = new ReplContext(api);
var registry = new CommandRegistry();
var input = new ReplInput(registry);
await AnsiConsole.Status().StartAsync("Loading notes…", async _ =>
ctx.NoteCache = await api.GetNotesAsync());
AnsiConsole.MarkupLine($"[dim]● {ctx.NoteCache.Count} notes cached[/]\n");
input.SetContext(ctx);
while (ctx.Running)
{
var prompt = $"[bold cyan]{ctx.CurrentPath}[/] [dim]»[/] ";
var line = input.Read(prompt);
if (line is null) break; // Ctrl-C / Ctrl-D
var parts = line.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 0) continue;
var name = parts[0];
var args = parts[1..];
if (name is "exit" or "quit" or "q")
{
AnsiConsole.MarkupLine("[dim]Bye.[/]");
break;
}
var cmd = registry.Find(name);
if (cmd is null)
{
AnsiConsole.MarkupLine($"[red]Unknown command:[/] {name} [dim](type 'help')[/]");
continue;
}
try { await cmd.ExecuteAsync(args, ctx); }
catch (HttpRequestException ex) { AnsiConsole.MarkupLine($"[red]Server error:[/] {ex.Message}"); }
catch (Exception ex) { AnsiConsole.MarkupLine($"[red]Error:[/] {ex.Message}"); }
}
}
}