Vendor all 4 Pi packages (tui, ai, agent-core, coding-agent) from pi-mono v0.57.1 as @gsd/* workspace packages under packages/. This replaces the compiled npm dependency (@mariozechner/pi-coding-agent) and patch-package workflow, giving direct source access for modifications. - Copy Pi source from pi-mono v0.57.1 into packages/ - Create workspace package.json + tsconfig.json for each package - Rename ~240 imports from @mariozechner/pi-* to @gsd/pi-* - Apply existing patches as source edits (setModel persist, VT input) - Remove @mariozechner/pi-coding-agent dep and patch-package - Update build pipeline to build packages in dependency order - Add pi-upstream git remote for future selective syncing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
46 lines
1.3 KiB
TypeScript
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;
|
|
}
|
|
}
|