singularity-forge/packages/tui/src/kill-ring.ts
Mikael Hugo 6725a55591 feat(web): add error boundaries, expand test coverage, add README
- Add class-based ErrorBoundary component wrapping all 7 main views
  inside WorkspaceChrome; fallback shows view name, error, reload button
- Add 30 new unit tests (boot null-project path × 9, onboarding
  pure-function logic × 21); all 43 web/lib tests pass
- Add web/README.md: architecture, auth flow, 7 views, dev setup,
  API route pattern, test instructions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-10 11:24:40 +02:00

46 lines
1.3 KiB
TypeScript

/**
* Ring buffer for Emacs-style kill/yank operations.
*
* Tracks killed (deleted) text entries. Consecutive kills can accumulate
* into a single entry. Supports yank (paste most recent) and yank-pop
* (cycle through older entries).
*/
export class KillRing {
private ring: string[] = [];
/**
* Add text to the kill ring.
*
* @param text - The killed text to add
* @param opts - Push options
* @param opts.prepend - If accumulating, prepend (backward deletion) or append (forward deletion)
* @param opts.accumulate - Merge with the most recent entry instead of creating a new one
*/
push(text: string, opts: { prepend: boolean; accumulate?: boolean }): void {
if (!text) return;
if (opts.accumulate && this.ring.length > 0) {
const last = this.ring.pop()!;
this.ring.push(opts.prepend ? text + last : last + text);
} else {
this.ring.push(text);
}
}
/** Get most recent entry without modifying the ring. */
peek(): string | undefined {
return this.ring.length > 0 ? this.ring[this.ring.length - 1] : undefined;
}
/** Move last entry to front (for yank-pop cycling). */
rotate(): void {
if (this.ring.length > 1) {
const last = this.ring.pop()!;
this.ring.unshift(last);
}
}
get length(): number {
return this.ring.length;
}
}