diff --git a/plugos/hooks/event.ts b/plugos/hooks/event.ts index 3a4ff42..529072d 100644 --- a/plugos/hooks/event.ts +++ b/plugos/hooks/event.ts @@ -60,9 +60,15 @@ export class EventHook implements Hook { ) { // Only dispatch functions that can run in this environment if (await plug.canInvoke(name)) { - const result = await plug.invoke(name, args); - if (result !== undefined) { - responses.push(result); + try { + const result = await plug.invoke(name, args); + if (result !== undefined) { + responses.push(result); + } + } catch (e: any) { + console.error( + `Error dispatching event ${eventName} to plug ${plug.name}: ${e.message}`, + ); } } } diff --git a/plugs/directive/command.ts b/plugs/directive/command.ts index eba17f7..1e4bb18 100644 --- a/plugs/directive/command.ts +++ b/plugs/directive/command.ts @@ -19,7 +19,13 @@ const directiveUpdateQueueName = "directiveUpdateQueue"; export async function updateDirectivesOnPageCommand() { // If `arg` is a string, it's triggered automatically via an event, not explicitly via a command const currentPage = await editor.getCurrentPage(); - const pageMeta = await space.getPageMeta(currentPage); + let pageMeta: PageMeta | undefined; + try { + pageMeta = await space.getPageMeta(currentPage); + } catch { + console.info("Page not found, not updating directives"); + return; + } const text = await editor.getText(); const tree = await markdown.parseMarkdown(text); const metaData = await extractFrontmatter(tree, ["$disableDirectives"]); diff --git a/plugs/index/api.ts b/plugs/index/api.ts index 07a7932..3233330 100644 --- a/plugs/index/api.ts +++ b/plugs/index/api.ts @@ -77,8 +77,9 @@ export async function indexObjects( value: obj, }); // Index attributes - if (!builtins[tag]) { - // But only for non-builtin tags + const builtinAttributes = builtins[tag]; + if (!builtinAttributes) { + // For non-builtin tags, index all attributes for ( const [attrName, attrValue] of Object.entries( obj as Record, @@ -89,6 +90,20 @@ export async function indexObjects( } allAttributes.set(`${tag}:${attrName}`, determineType(attrValue)); } + } else if (tag !== "attribute") { + // For builtin tags, only index custom ones + for ( + const [attrName, attrValue] of Object.entries( + obj as Record, + ) + ) { + // console.log("Indexing", tag, attrName, attrValue); + // Skip builtins and internal attributes + if (builtinAttributes[attrName] || attrName.startsWith("$")) { + continue; + } + allAttributes.set(`${tag}:${attrName}`, determineType(attrValue)); + } } } } diff --git a/plugs/index/asset/linked_mentions.js b/plugs/index/asset/linked_mentions.js index cf87892..8ef20d1 100644 --- a/plugs/index/asset/linked_mentions.js +++ b/plugs/index/asset/linked_mentions.js @@ -8,10 +8,12 @@ function processClick(e) { } document.getElementById("link-ul").addEventListener("click", processClick); -document.getElementById("hide-button").addEventListener("click", function () { - console.log("HERE") - syscall( - "system.invokeFunction", - "index.toggleMentions", - ).catch(console.error); +document.getElementById("hide-button").addEventListener("click", () => { + syscall("system.invokeFunction", "index.toggleMentions").catch(console.error); +}); + +document.getElementById("reload-button").addEventListener("click", () => { + syscall("system.invokeFunction", "index.renderMentions").catch( + console.error, + ); }); diff --git a/plugs/index/asset/style.css b/plugs/index/asset/style.css index 6a8b1ce..60143ae 100644 --- a/plugs/index/asset/style.css +++ b/plugs/index/asset/style.css @@ -33,12 +33,25 @@ body { background-color: rgba(233, 233, 233, 0.5); } -#hide-button { +#button-bar { position: absolute; - right: 15px; - top: 15px; + right: 10px; + top: 10px; + padding: 0 3px; } +#button-bar button { + border: none; + background: none; + cursor: pointer; + color: var(--root-color); +} + +#edit-button { + margin-left: -10px; +} + + li code { font-size: 80%; color: #a5a4a4; diff --git a/plugs/index/attributes.ts b/plugs/index/attributes.ts index abee087..c298341 100644 --- a/plugs/index/attributes.ts +++ b/plugs/index/attributes.ts @@ -1,6 +1,6 @@ import type { CompleteEvent } from "$sb/app_event.ts"; import { events } from "$sb/syscalls.ts"; -import { queryObjects } from "./api.ts"; +import { getObjectByRef, queryObjects } from "./api.ts"; import { ObjectValue, QueryExpression } from "$sb/types.ts"; import { builtinPseudoPage } from "./builtins.ts"; @@ -85,18 +85,32 @@ export async function attributeComplete(completeEvent: CompleteEvent) { } const attributeMatch = /^(\w+)$/.exec(completeEvent.linePrefix); if (attributeMatch) { - if (completeEvent.parentNodes.includes("FrontMatterCode")) { - const completions = (await events.dispatchEvent( - `attribute:complete:page`, - { - source: "page", - prefix: attributeMatch[1], - } as AttributeCompleteEvent, - )).flat() as AttributeCompletion[]; + if (completeEvent.parentNodes.includes("FrontMatter")) { + const pageMeta = await getObjectByRef( + completeEvent.pageName, + "page", + completeEvent.pageName, + ); + let tags = ["page"]; + if (pageMeta?.tags) { + tags = pageMeta.tags; + } + const completions = (await Promise.all(tags.map((tag) => + events.dispatchEvent( + `attribute:complete:${tag}`, + { + source: tag, + prefix: attributeMatch[1], + } as AttributeCompleteEvent, + ) + ))).flat(2) as AttributeCompletion[]; + // console.log("Completions", completions); return { from: completeEvent.pos - attributeMatch[1].length, options: attributeCompletionsToCMCompletion( - completions.filter((completion) => !completion.builtin), + completions.filter((completion) => + !completion.builtin + ), ), }; } diff --git a/plugs/index/builtins.ts b/plugs/index/builtins.ts index b6b5cf5..49fe15c 100644 --- a/plugs/index/builtins.ts +++ b/plugs/index/builtins.ts @@ -7,6 +7,7 @@ export const builtinPseudoPage = ":builtin:"; export const builtins: Record> = { page: { + ref: "string", name: "string", lastModified: "date", perm: "rw|ro", @@ -15,6 +16,7 @@ export const builtins: Record> = { tags: "array", }, task: { + ref: "string", name: "string", done: "boolean", page: "string", @@ -24,22 +26,26 @@ export const builtins: Record> = { tags: "array", }, tag: { + ref: "string", name: "string", page: "string", context: "string", }, attribute: { + ref: "string", name: "string", attributeType: "string", type: "string", page: "string", }, anchor: { + ref: "string", name: "string", page: "string", pos: "number", }, link: { + ref: "string", name: "string", page: "string", pos: "number", diff --git a/plugs/index/index.plug.yaml b/plugs/index/index.plug.yaml index 5e7b335..488da23 100644 --- a/plugs/index/index.plug.yaml +++ b/plugs/index/index.plug.yaml @@ -102,11 +102,6 @@ functions: events: - attribute:complete:* - # builtinAttributeCompleter: - # path: ./attributes.ts:builtinAttributeCompleter - # events: - # - attribute:complete:* - # Item indexing indexItem: path: "./item.ts:indexItems" @@ -172,3 +167,5 @@ functions: navigateToMention: path: "./mentions_ps.ts:navigate" + renderMentions: + path: "./mentions_ps.ts:renderMentions" diff --git a/plugs/index/mentions_ps.ts b/plugs/index/mentions_ps.ts index 7c4c55e..664a03d 100644 --- a/plugs/index/mentions_ps.ts +++ b/plugs/index/mentions_ps.ts @@ -10,8 +10,7 @@ export async function toggleMentions() { hideMentions = !hideMentions; await clientStore.set(hideMentionsKey, hideMentions); if (!hideMentions) { - const name = await editor.getCurrentPage(); - await renderMentions(name); + await renderMentions(); } else { await editor.hidePanel("ps"); } @@ -22,8 +21,7 @@ export async function updateMentions() { if (await clientStore.get(hideMentionsKey)) { return; } - const name = await editor.getCurrentPage(); - await renderMentions(name); + await renderMentions(); } // use internal navigation via syscall to prevent reloading the full page. @@ -39,7 +37,8 @@ function escapeHtml(unsafe: string) { ); } -async function renderMentions(page: string) { +export async function renderMentions() { + const page = await editor.getCurrentPage(); const linksResult = await queryObjects("link", { // Query all links that point to this page, excluding those that are inside directives and self pointers. filter: ["and", ["!=", ["attr", "page"], ["string", page]], ["and", ["=", [ @@ -60,7 +59,10 @@ async function renderMentions(page: string) { `
- +
+ + +
Linked Mentions