93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
import type { CompleteEvent } from "../../plug-api/types.ts";
|
|
import { datastore, events } from "@silverbulletmd/silverbullet/syscalls";
|
|
|
|
import type {
|
|
AttributeCompleteEvent,
|
|
AttributeCompletion,
|
|
} from "../index/attributes.ts";
|
|
import { attributeCompletionsToCMCompletion } from "./snippet.ts";
|
|
|
|
export async function templateAttributeComplete(completeEvent: CompleteEvent) {
|
|
// Check if we're in a query, block or template context
|
|
const fencedParent = completeEvent.parentNodes.find((node) =>
|
|
node.startsWith("FencedCode:template")
|
|
);
|
|
|
|
if (!fencedParent) {
|
|
return null;
|
|
}
|
|
|
|
const attributeMatch = /(^|[^{])\{\{(\w*)$/.exec(completeEvent.linePrefix);
|
|
if (!attributeMatch) {
|
|
return null;
|
|
}
|
|
|
|
let allCompletions: any[] = [];
|
|
|
|
// Function completions
|
|
const functions = await datastore.listFunctions();
|
|
allCompletions = functions.map((name) => ({
|
|
label: name,
|
|
apply: name,
|
|
detail: "function",
|
|
}));
|
|
|
|
// Attribute completions
|
|
const completions = (await events.dispatchEvent(
|
|
`attribute:complete:_`,
|
|
{
|
|
source: "",
|
|
prefix: attributeMatch[2],
|
|
} as AttributeCompleteEvent,
|
|
)).flat() as AttributeCompletion[];
|
|
|
|
allCompletions = allCompletions.concat(
|
|
attributeCompletionsToCMCompletion(completions),
|
|
);
|
|
|
|
return {
|
|
from: completeEvent.pos - attributeMatch[2].length,
|
|
options: allCompletions,
|
|
};
|
|
}
|
|
|
|
export function templateVariableComplete(completeEvent: CompleteEvent) {
|
|
// Check if we're in a query, block or template context
|
|
const fencedParent = completeEvent.parentNodes.find((node) =>
|
|
node.startsWith("FencedCode:template")
|
|
);
|
|
|
|
if (!fencedParent) {
|
|
return null;
|
|
}
|
|
|
|
// Find a @ inside of a {{
|
|
const variableMatch = /\{\{[^}]*@(\w*)$/.exec(completeEvent.linePrefix);
|
|
if (!variableMatch) {
|
|
return null;
|
|
}
|
|
|
|
let allCompletions: any[] = [];
|
|
const regexp = /\s+@(\w+)\s+(=|in)\s+/g;
|
|
const allVariables = new Set<string>();
|
|
const matches = fencedParent.matchAll(regexp);
|
|
for (const match of matches) {
|
|
allVariables.add(match[1]);
|
|
}
|
|
|
|
allVariables.add("page");
|
|
allVariables.add("config");
|
|
allCompletions = allCompletions.concat(
|
|
[...allVariables].map((key) => ({
|
|
label: `@${key}`,
|
|
apply: key,
|
|
detail: "variable",
|
|
})),
|
|
);
|
|
|
|
return {
|
|
from: completeEvent.pos - variableMatch[1].length,
|
|
options: allCompletions,
|
|
};
|
|
}
|