pull/989/head
Zef Hemel 2024-07-25 15:18:58 +02:00
parent cff343a66b
commit 3ca132e16a
3 changed files with 63 additions and 13 deletions

View File

@ -9,6 +9,7 @@ import { listFilesCached } from "../federation/federation.ts";
import { queryObjects } from "../index/plug_api.ts";
import { folderName } from "$sb/lib/resolve.ts";
import { decoration } from "$sb/syscalls.ts";
import type { LinkObject } from "../index/page_links.ts";
// A meta page is a page tagged with either #template or #meta
const isMetaPageFilter: QueryExpression = ["or", ["=", ["attr", "tags"], [
@ -66,14 +67,34 @@ export async function pageComplete(completeEvent: CompleteEvent) {
// Include both pages and meta in page completion in ```include and ```template blocks
allPages = await queryObjects<PageMeta>("page", {}, 5);
} else {
// Otherwise, just complete non-meta pages
allPages = await queryObjects<PageMeta>("page", {
filter: ["not", isMetaPageFilter],
}, 5);
// and attachments
allPages = allPages.concat(
await queryObjects<AttachmentMeta>("attachment", {}, 5),
);
// This is the most common case, we're combining three types of completions here:
allPages = (await Promise.all([
// All non-meta pages
queryObjects<PageMeta>("page", {
filter: ["not", isMetaPageFilter],
}, 5),
// All attachments
queryObjects<AttachmentMeta>("attachment", {}, 5),
// And all links to non-existing pages (to augment the existing ones)
queryObjects<LinkObject>("link", {
filter: ["and", ["attr", "toPage"], ["not", ["call", "pageExists", [[
"attr",
"toPage",
]]]]],
select: [{ name: "toPage" }],
}, 5).then((brokenLinks) =>
// Rewrite them to PageMeta shaped objects
brokenLinks.map((link): PageMeta => ({
ref: link.toPage!,
tag: "page",
tags: ["non-existing"], // Picked up later in completion
name: link.toPage!,
created: "",
lastModified: "",
perm: "rw",
}))
),
])).flat();
}
// Don't complete hidden pages
@ -143,6 +164,9 @@ export async function pageComplete(completeEvent: CompleteEvent) {
label: pageMeta.name,
displayLabel: decoratedName,
boost: new Date(pageMeta.lastModified).getTime(),
detail: pageMeta.tags?.includes("non-existing")
? "Linked but not created"
: undefined,
type: "page",
});
} else {

View File

@ -62,6 +62,7 @@ import { LimitedMap } from "$lib/limited_map.ts";
import { plugPrefix } from "$common/spaces/constants.ts";
import { lezerToParseTree } from "$common/markdown_parser/parse_tree.ts";
import { findNodeMatching } from "$sb/lib/tree.ts";
import type { LinkObject } from "../plugs/index/page_links.ts";
const frontMatterRegex = /^---\n(([^\n]|\n)*?)---\n/;
@ -787,9 +788,27 @@ export class Client {
return;
}
const allPages = await this.clientSystem.queryObjects<PageMeta>("page", {});
const allBrokenLinkPages = (await this.clientSystem.queryObjects<
LinkObject
>("link", {
filter: ["and", ["attr", "toPage"], ["not", ["call", "pageExists", [[
"attr",
"toPage",
]]]]],
select: [{ name: "toPage" }],
})).map((link): PageMeta => ({
ref: link.toPage!,
tag: "page",
_isBrokenLink: true,
name: link.toPage!,
created: "",
lastModified: "",
perm: "rw",
}));
this.ui.viewDispatch({
type: "update-page-list",
allPages,
allPages: allPages.concat(allBrokenLinkPages),
});
}

View File

@ -65,6 +65,7 @@ export function PageNavigator({
name: (pageMeta.pageDecoration?.prefix ?? "") + pageMeta.name,
description,
orderId: orderId,
hint: pageMeta._isBrokenLink ? "Create page" : undefined,
});
} else if (mode === "meta") {
// Special behavior for #template and #meta pages
@ -99,11 +100,15 @@ export function PageNavigator({
} else if (currentPage && currentPage.includes(" ")) {
completePrefix = currentPage.split(" ")[0] + " ";
}
const pageNoun = mode === "meta" ? mode : "page";
return (
<FilterList
placeholder={mode === "page" ? "Page" : (mode === "meta" ? "#template or #meta page" : "Any page, also hidden")}
placeholder={mode === "page"
? "Page"
: (mode === "meta"
? "#template or #meta page"
: "Any page, also hidden")}
label="Open"
options={options}
vimMode={vimMode}
@ -116,7 +121,7 @@ export function PageNavigator({
onKeyPress={(key, text) => {
// Pages cannot start with ^, as documented in Page Name Rules
if (key === "^" && text === "^") {
switch(mode) {
switch (mode) {
case "page":
onModeSwitch("meta");
break;
@ -159,7 +164,9 @@ export function PageNavigator({
if (mode !== "all") {
// Filter out hidden pages
options = options.filter((page) => !(page.pageDecoration?.hide === true));
options = options.filter((page) =>
!(page.pageDecoration?.hide === true)
);
}
return options;
}}