import * as vscode from "vscode";
import { compileQuery, matchLines } from "../lib/text-search";
import type { LineMatch } from "../lib/text-search";
import type { ForgeApi } from "./forge";
import type { GitforFileSystem } from "./fs";
import type { RoomClient } from "./room-client";
const DEFAULT_FILE_RESULTS = 512;
const MAX_TEXT_RESULTS = 2000;
const MAX_SKIP = 5000;
/** `**\/name` and `**\/name/**` excludes name a directory anywhere; the server can skip those subtrees. */
const DIR_EXCLUDE = /^\*\*\/([^*?/[{}\]]+)(?:\/\*\*)?$/;
/** Characters of `pattern` appear in `path` in order (Quick Open style); the workbench ranks the results. */
function fuzzyMatch(path: string, pattern: string): boolean {
let index = 0;
for (const char of path) {
if (char === pattern[index]) index++;
if (index === pattern.length) return true;
}
return index === pattern.length;
}
function toMatches(uri: vscode.Uri, lines: LineMatch[]): vscode.TextSearchMatch[] {
return lines.map((line) => ({
uri,
ranges: line.ranges.map(([start, end]) => new vscode.Range(line.line, start, line.line, end)),
preview: { text: line.text, matches: line.ranges.map(([start, end]) => new vscode.Range(0, start, 0, end)) },
}));
}
/**
* Search for the `gitfor:` workspace. VS Code for the Web only searches a virtual file system through these
* providers; without them Search and Quick Open see nothing but the open editors. Quick Open lists the tree the
* file system already loaded. Text search runs on the forge over the head tree, while files the live room holds
* (edited, created or deleted in this session) are searched here from their shared text instead.
*/
export function registerSearch(api: ForgeApi, fs: GitforFileSystem, room: RoomClient): vscode.Disposable {
const files: vscode.FileSearchProvider = {
async provideFileSearchResults(query, options) {