import * as vscode from "vscode";
import type * as Y from "yjs";
import type { FileMeta } from "../lib/editor-protocol";
import type { ForgeApi } from "./forge";
import type { RoomClient } from "./room-client";
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const READ_ONLY_KINDS = new Set(["lfs", "symlink", "binary", "too-large", "gitlink"]);
/**
* `gitfor:` file system over the branch tree plus the live room. Directory listings come from the tree at
* the session head, overlaid with files created or deleted in the room; file contents are the shared
* Y.Text, so every reader sees co-editors' edits. Writes go into the room, never straight to git.
*/
/** Rewrites `text` to `next` touching only the differing middle, so remote cursors stay put. */
function replaceText(text: Y.Text, next: string): void {
const current = text.toString();
let start = 0;
while (start < current.length && start < next.length && current[start] === next[start]) start++;
let end = 0;
while (
end < current.length - start &&
end < next.length - start &&
current[current.length - 1 - end] === next[next.length - 1 - end]
)
end++;
text.delete(start, current.length - start - end);
text.insert(start, next.slice(start, next.length - end));
}
export class GitforFileSystem implements vscode.FileSystemProvider {
private readonly emitter = new vscode.EventEmitter<vscode.FileChangeEvent[]>();
readonly onDidChangeFile = this.emitter.event;
private headFiles = new Set<string>();
private headDirs = new Set<string>([""]);
private loaded: Promise<void> | null = null;
/** Set by the extension: paths whose open editor is already bound to the room. */
isBound: (path: string, content: string) => boolean = () => false;