54 lines
2 KiB
C#
54 lines
2 KiB
C#
using NozCli.Core.Client;
|
|
using NozCli.Core.Models;
|
|
|
|
namespace NozCli.Repl;
|
|
|
|
/// Shared mutable state across the REPL session.
|
|
public class ReplContext
|
|
{
|
|
public NozApiClient Api { get; }
|
|
public string CurrentPath { get; set; } = "~";
|
|
public List<NoteInfo> NoteCache { get; set; } = [];
|
|
public bool Running { get; set; } = true;
|
|
|
|
public ReplContext(NozApiClient api) => Api = api;
|
|
|
|
/// Returns the topic/folder prefix implied by CurrentPath, or null if at root.
|
|
public string? PathPrefix()
|
|
{
|
|
if (CurrentPath is "~" or "~/noosphere") return null;
|
|
var stripped = CurrentPath.Replace("~/noosphere/", "").Replace("~/noosphere", "");
|
|
return string.IsNullOrEmpty(stripped) ? null : stripped;
|
|
}
|
|
|
|
/// Notes visible at the current path level.
|
|
public IEnumerable<NoteInfo> NotesInView()
|
|
{
|
|
var prefix = PathPrefix();
|
|
return prefix is null
|
|
? NoteCache
|
|
: NoteCache.Where(n => n.Slug.StartsWith(prefix + "/"));
|
|
}
|
|
|
|
/// Resolves a short name (e.g. "hydroponik") to a full slug using the current path as prefix.
|
|
public string ResolveSlug(string nameOrSlug)
|
|
{
|
|
// Already a full slug
|
|
if (NoteCache.Any(n => n.Slug == nameOrSlug)) return nameOrSlug;
|
|
var prefix = PathPrefix();
|
|
var candidate = prefix is null ? nameOrSlug : $"{prefix}/{nameOrSlug}";
|
|
return NoteCache.Any(n => n.Slug == candidate) ? candidate : nameOrSlug;
|
|
}
|
|
|
|
/// Immediate sub-segments (topics or subfolders) at current path.
|
|
public IEnumerable<string> FoldersInView()
|
|
{
|
|
var prefix = PathPrefix();
|
|
var depth = prefix is null ? 0 : prefix.Split('/').Length;
|
|
return NoteCache
|
|
.Where(n => prefix is null || n.Slug.StartsWith(prefix + "/"))
|
|
.Select(n => n.Slug.Split('/').ElementAtOrDefault(depth))
|
|
.Where(s => s is not null)
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)!;
|
|
}
|
|
}
|