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

79 lines
2.5 KiB
C#

using NozCli.Repl;
using Spectre.Console;
namespace NozCli.Commands;
public class LsCommand : ICommand
{
public string Name => "ls";
public string Description => "List notes and folders at current path";
public string Usage => "ls [-l]";
public async Task ExecuteAsync(string[] args, ReplContext ctx)
{
var detailed = args.Contains("-l");
var folders = ctx.FoldersInView().OrderBy(f => f).ToList();
var prefix = ctx.PathPrefix();
// Determine which segments are folders (have children) vs direct notes
var directNotes = ctx.NotesInView()
.Where(n =>
{
var depth = prefix is null ? 0 : prefix.Split('/').Length;
return n.Slug.Split('/').Length == depth + 1;
})
.OrderBy(n => n.Title)
.ToList();
var subFolders = ctx.FoldersInView()
.Where(f => directNotes.All(n => n.Slug.Split('/').Last() != f))
.OrderBy(f => f)
.ToList();
if (!detailed)
{
foreach (var folder in subFolders)
AnsiConsole.MarkupLine($" [blue]{folder}/[/]");
foreach (var note in directNotes)
AnsiConsole.MarkupLine($" [white]{note.Slug.Split('/').Last()}[/]");
return;
}
var table = new Table().BorderStyle(Style.Plain).HideHeaders();
table.AddColumns("", "name", "status", "lang", "title");
foreach (var folder in subFolders)
{
var count = ctx.NotesInView()
.Count(n => n.Slug.StartsWith((prefix is null ? "" : prefix + "/") + folder + "/"));
table.AddRow(
"[blue]📁[/]",
$"[blue]{folder}/[/]",
$"[dim]{count} notes[/]",
"",
""
);
}
foreach (var note in directNotes)
{
var statusColor = note.Status switch
{
"seed" => "yellow",
"budding" => "purple",
"evergreen" => "teal",
_ => "grey"
};
table.AddRow(
"●",
$"[white]{note.Slug.Split('/').Last()}[/]",
$"[{statusColor}]{note.Status}[/]",
$"[dim]{note.Lang}[/]",
$"[dim]{note.Title}[/]"
);
}
AnsiConsole.Write(table);
await Task.CompletedTask;
}
}