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; } }