feat: add completions API and scanning logic
Implement a new completions system that scans markdown files for dice notation and headings. The server now exposes a `/__COMPLETIONS.json` endpoint and automatically recomputes the completion index when files are added, updated, or deleted.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Dice completion source — extracts `<md-dice>` text content from markdown files.
|
||||
*/
|
||||
|
||||
import type { CompletionSource, DiceCompletion } from "../types.js";
|
||||
|
||||
function looksLikeDice(raw: string): boolean {
|
||||
if (raw.length > 80) return false;
|
||||
return /^\d*d\d+/i.test(raw) || /^[+-]/.test(raw);
|
||||
}
|
||||
|
||||
export const diceSource: CompletionSource = {
|
||||
key: "dice",
|
||||
|
||||
scan(index) {
|
||||
const items: DiceCompletion[] = [];
|
||||
const tagRegex = /<md-dice[^>]*>\s*([\s\S]*?)\s*<\/md-dice>/gi;
|
||||
|
||||
for (const [path, content] of Object.entries(index)) {
|
||||
if (!path.endsWith(".md")) continue;
|
||||
|
||||
let match: RegExpExecArray | null;
|
||||
tagRegex.lastIndex = 0;
|
||||
while ((match = tagRegex.exec(content)) !== null) {
|
||||
const raw = match[1].trim();
|
||||
if (!raw || !looksLikeDice(raw)) continue;
|
||||
|
||||
items.push({
|
||||
label: raw,
|
||||
notation: raw,
|
||||
source: path,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user