Big refactors and fixes

* Query regen
* Fix anchor completion
* Dependency fixes
* Changelog update
This commit is contained in:
Zef Hemel
2023-07-02 11:25:32 +02:00
committed by GitHub
parent fee2c5928e
commit 7c825348b2
74 changed files with 935 additions and 567 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
import { collectNodesOfType } from "$sb/lib/tree.ts";
import { editor, index } from "$sb/silverbullet-syscall/mod.ts";
import { index } from "$sb/silverbullet-syscall/mod.ts";
import type { CompleteEvent, IndexTreeEvent } from "$sb/app_event.ts";
import { removeQueries } from "$sb/lib/query.ts";
@@ -29,7 +29,7 @@ export async function anchorComplete(completeEvent: CompleteEvent) {
let [pageRef, anchorRef] = match[1].split("@");
if (!pageRef) {
pageRef = await editor.getCurrentPage();
pageRef = completeEvent.pageName;
}
const allAnchors = await index.queryPrefix(
`a:${pageRef}:${anchorRef}`,
+66
View File
@@ -0,0 +1,66 @@
import { traverseTree } from "../../plug-api/lib/tree.ts";
import {
editor,
markdown,
space,
} from "../../plug-api/silverbullet-syscall/mod.ts";
export async function brokenLinksCommand() {
const pageName = "BROKEN LINKS";
await editor.flashNotification("Scanning your space...");
const allPages = await space.listPages();
const allPagesMap = new Map(allPages.map((p) => [p.name, true]));
const brokenLinks: { page: string; link: string; pos: number }[] = [];
for (const pageMeta of allPages) {
const text = await space.readPage(pageMeta.name);
const tree = await markdown.parseMarkdown(text);
traverseTree(tree, (tree) => {
if (tree.type === "WikiLinkPage") {
// Add the prefix in the link text
const [pageName] = tree.children![0].text!.split("@");
if (pageName.startsWith("💭 ")) {
return true;
}
if (
pageName && !pageName.startsWith("{{")
) {
if (!allPagesMap.has(pageName)) {
brokenLinks.push({
page: pageMeta.name,
link: pageName,
pos: tree.from!,
});
}
}
}
if (tree.type === "PageRef") {
const pageName = tree.children![0].text!.slice(2, -2);
if (pageName.startsWith("💭 ")) {
return true;
}
if (!allPagesMap.has(pageName)) {
brokenLinks.push({
page: pageMeta.name,
link: pageName,
pos: tree.from!,
});
}
}
if (tree.type === "DirectiveBody") {
// Don't look inside directive bodies
return true;
}
return false;
});
}
const lines: string[] = [];
for (const brokenLink of brokenLinks) {
lines.push(
`* [[${brokenLink.page}@${brokenLink.pos}]]: ${brokenLink.link}`,
);
}
await space.writePage(pageName, lines.join("\n"));
await editor.navigate(pageName);
}
+2 -6
View File
@@ -1,13 +1,12 @@
import { renderToText, replaceNodesMatching } from "$sb/lib/tree.ts";
import type { FileMeta } from "../../common/types.ts";
import { parseMarkdown } from "$sb/silverbullet-syscall/markdown.ts";
import { base64EncodedDataUrl } from "../../plugos/asset_bundle/base64.ts";
export const cloudPrefix = "💭 ";
export async function readFileCloud(
name: string,
): Promise<{ data: string; meta: FileMeta } | undefined> {
): Promise<{ data: Uint8Array; meta: FileMeta } | undefined> {
const originalUrl = name.substring(
cloudPrefix.length,
name.length - ".md".length,
@@ -38,10 +37,7 @@ export async function readFileCloud(
`${cloudPrefix}${originalUrl.split("/")[0]}/`,
);
return {
data: base64EncodedDataUrl(
"text/markdown",
new TextEncoder().encode(text),
),
data: new TextEncoder().encode(text),
meta: {
name,
contentType: "text/markdown",
+21
View File
@@ -52,6 +52,13 @@ functions:
command:
name: "Page: Copy"
syncSpaceCommand:
path: "./sync.ts:syncSpaceCommand"
command:
name: "Sync: Now"
key: "Alt-Shift-s"
mac: "Cmd-Shift-s"
# Attachments
attachmentQueryProvider:
path: ./attachment.ts:attachmentQueryProvider
@@ -180,6 +187,15 @@ functions:
description: Turn line into h4 header
match: "^#*\\s*"
replace: "#### "
insertCodeBlock:
redirect: insertTemplateText
slashCommand:
name: code
description: Insert code block
value: |
```
|^|
```
newPage:
path: ./page.ts:newPageCommand
@@ -433,3 +449,8 @@ functions:
name: "Editor: Vim: Load VIMRC"
events:
- editor:modeswitch
brokenLinksCommand:
path: ./broken_links.ts:brokenLinksCommand
command:
name: "Broken Links: Show"
+10 -10
View File
@@ -35,6 +35,7 @@ async function actionClickOrActionEnter(
return;
}
}
const currentPage = await editor.getCurrentPage();
switch (mdTree.type) {
case "WikiLink": {
let pageLink = mdTree.children![1]!.children![0].text!;
@@ -46,20 +47,20 @@ async function actionClickOrActionEnter(
}
}
if (!pageLink) {
pageLink = await editor.getCurrentPage();
pageLink = currentPage;
}
await editor.navigate(pageLink, pos, false, inNewWindow);
break;
}
case "PageRef": {
const bracketedPageRef = mdTree.children![0].text!;
await editor.navigate(
// Slicing off the initial [[ and final ]]
bracketedPageRef.substring(2, bracketedPageRef.length - 2),
0,
false,
inNewWindow,
// Slicing off the initial [[ and final ]]
const pageName = bracketedPageRef.substring(
2,
bracketedPageRef.length - 2,
);
await editor.navigate(pageName, 0, false, inNewWindow);
break;
}
case "NakedURL":
@@ -71,13 +72,12 @@ async function actionClickOrActionEnter(
if (!urlNode) {
return;
}
let url = urlNode.children![0].text!;
const url = urlNode.children![0].text!;
if (url.length <= 1) {
return editor.flashNotification("Empty link, ignoring", "error");
}
if (url.indexOf("://") === -1 && !url.startsWith("mailto:")) {
url = decodeURIComponent(url);
return editor.openUrl(`/.fs/${url}`);
return editor.openUrl(`/.fs/${decodeURI(url)}`);
} else {
await editor.openUrl(url);
}
+14 -11
View File
@@ -20,9 +20,9 @@ import {
renderToText,
replaceNodesMatching,
} from "$sb/lib/tree.ts";
import { applyQuery } from "$sb/lib/query.ts";
import { applyQuery, removeQueries } from "$sb/lib/query.ts";
import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
import { invokeFunction } from "../../plug-api/silverbullet-syscall/system.ts";
import { invokeFunction } from "$sb/silverbullet-syscall/system.ts";
// Key space:
// pl:toPage:pos => pageName
@@ -32,6 +32,7 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
const backLinks: { key: string; value: string }[] = [];
// [[Style Links]]
// console.log("Now indexing links for", name);
removeQueries(tree);
const pageMeta = await extractFrontmatter(tree);
if (Object.keys(pageMeta).length > 0) {
// console.log("Extracted page meta data", pageMeta);
@@ -44,8 +45,6 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
await index.set(name, "meta:", pageMeta);
}
// throw new Error("Boom");
collectNodesMatching(tree, (n) => n.type === "WikiLinkPage").forEach((n) => {
let toPage = n.children![0].text!;
if (toPage.includes("@")) {
@@ -106,7 +105,7 @@ export async function copyPage() {
await space.getPageMeta(newName);
// So when we get to this point, we error out
throw new Error(
`Page ${newName} already exists, cannot rename to existing page.`,
`Page ${newName} already exists, cannot rename to existing page.`,
);
} catch (e: any) {
if (e.message === "Not found") {
@@ -165,6 +164,7 @@ export async function renamePage(cmdDef: any) {
console.log("All pages containing backlinks", pagesToUpdate);
const text = await editor.getText();
console.log("Writing new page to space");
const newPageMeta = await space.writePage(newName, text);
console.log("Navigating to new page");
@@ -198,6 +198,7 @@ export async function renamePage(cmdDef: any) {
}
const mdTree = await markdown.parseMarkdown(text);
addParentPointers(mdTree);
// The links in the page are going to be relative pointers to the old name
replaceNodesMatching(mdTree, (n): ParseTree | undefined | null => {
if (n.type === "WikiLinkPage") {
const pageName = n.children![0].text!;
@@ -265,18 +266,20 @@ export async function reindexCommand() {
// Completion
export async function pageComplete(completeEvent: CompleteEvent) {
const match = /\[\[([^\]@:]*)$/.exec(completeEvent.linePrefix);
const match = /\[\[([^\]@:\{}]*)$/.exec(completeEvent.linePrefix);
if (!match) {
return null;
}
const allPages = await space.listPages();
return {
from: completeEvent.pos - match[1].length,
options: allPages.map((pageMeta) => ({
label: pageMeta.name,
boost: pageMeta.lastModified,
type: "page",
})),
options: allPages.map((pageMeta) => {
return {
label: pageMeta.name,
boost: pageMeta.lastModified,
type: "page",
};
}),
};
}
+7
View File
@@ -0,0 +1,7 @@
import { editor } from "$sb/silverbullet-syscall/mod.ts";
export async function syncSpaceCommand() {
await editor.flashNotification("Syncing space...");
await editor.syncSpace();
await editor.flashNotification("Done.");
}
+39 -39
View File
@@ -3,6 +3,10 @@ import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
import { renderToText } from "$sb/lib/tree.ts";
import { niceDate } from "$sb/lib/dates.ts";
import { readSettings } from "$sb/lib/settings_page.ts";
import { PageMeta } from "../../web/types.ts";
import { buildHandebarOptions } from "../directive/util.ts";
import Handlebars from "handlebars";
export async function instantiateTemplateCommand() {
const allPages = await space.listPages();
@@ -36,10 +40,16 @@ export async function instantiateTemplateCommand() {
"$disableDirectives",
]);
const tempPageMeta: PageMeta = {
name: "",
lastModified: 0,
perm: "rw",
};
if (additionalPageMeta.$name) {
additionalPageMeta.$name = replaceTemplateVars(
additionalPageMeta.$name,
"",
tempPageMeta,
);
}
@@ -50,6 +60,7 @@ export async function instantiateTemplateCommand() {
if (!pageName) {
return;
}
tempPageMeta.name = pageName;
try {
// Fails if doesn't exist
@@ -67,7 +78,7 @@ export async function instantiateTemplateCommand() {
// The preferred scenario, let's keep going
}
const pageText = replaceTemplateVars(renderToText(parseTree), pageName);
const pageText = replaceTemplateVars(renderToText(parseTree), tempPageMeta);
await space.writePage(pageName, pageText);
await editor.navigate(pageName);
}
@@ -79,6 +90,7 @@ export async function insertSnippet() {
});
const cursorPos = await editor.getCursor();
const page = await editor.getCurrentPage();
const pageMeta = await space.getPageMeta(page);
const allSnippets = allPages
.filter((pageMeta) => pageMeta.name.startsWith(snippetPrefix))
.map((pageMeta) => ({
@@ -97,10 +109,10 @@ export async function insertSnippet() {
}
const text = await space.readPage(`${snippetPrefix}${selectedSnippet.name}`);
let templateText = replaceTemplateVars(text, page);
let templateText = replaceTemplateVars(text, pageMeta);
const carretPos = templateText.indexOf("|^|");
templateText = templateText.replace("|^|", "");
templateText = replaceTemplateVars(templateText, page);
templateText = replaceTemplateVars(templateText, pageMeta);
await editor.insertAtCursor(templateText);
if (carretPos !== -1) {
await editor.moveCursor(cursorPos + carretPos);
@@ -108,37 +120,9 @@ export async function insertSnippet() {
}
// TODO: This should probably be replaced with handlebards somehow?
export function replaceTemplateVars(s: string, pageName: string): string {
return s.replaceAll(/\{\{([^\}]+)\}\}/g, (match, v) => {
switch (v) {
case "today":
return niceDate(new Date());
case "tomorrow": {
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
return niceDate(tomorrow);
}
case "yesterday": {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
return niceDate(yesterday);
}
case "lastWeek": {
const lastWeek = new Date();
lastWeek.setDate(lastWeek.getDate() - 7);
return niceDate(lastWeek);
}
case "nextWeek": {
const nextWeek = new Date();
nextWeek.setDate(nextWeek.getDate() + 7);
return niceDate(nextWeek);
}
case "page":
return pageName;
}
return match;
});
export function replaceTemplateVars(s: string, pageMeta: PageMeta): string {
const template = Handlebars.compile(s, { noEscape: true });
return template({}, buildHandebarOptions(pageMeta));
}
export async function quickNoteCommand() {
@@ -159,6 +143,7 @@ export async function dailyNoteCommand() {
});
const date = niceDate(new Date());
const pageName = `${dailyNotePrefix}${date}`;
let carretPos = 0;
try {
await space.getPageMeta(pageName);
@@ -167,15 +152,25 @@ export async function dailyNoteCommand() {
let dailyNoteTemplateText = "";
try {
dailyNoteTemplateText = await space.readPage(dailyNoteTemplate);
carretPos = dailyNoteTemplateText.indexOf("|^|");
if (carretPos === -1) {
carretPos = 0;
}
dailyNoteTemplateText = dailyNoteTemplateText.replace("|^|", "");
} catch {
console.warn(`No daily note template found at ${dailyNoteTemplate}`);
}
await space.writePage(
pageName,
replaceTemplateVars(dailyNoteTemplateText, pageName),
replaceTemplateVars(dailyNoteTemplateText, {
name: pageName,
lastModified: 0,
perm: "rw",
}),
);
}
await editor.navigate(pageName);
await editor.navigate(pageName, carretPos);
}
function getWeekStartDate(monday = false) {
@@ -210,7 +205,11 @@ export async function weeklyNoteCommand() {
// Doesn't exist, let's create
await space.writePage(
pageName,
replaceTemplateVars(weeklyNoteTemplateText, pageName),
replaceTemplateVars(weeklyNoteTemplateText, {
name: pageName,
lastModified: 0,
perm: "rw",
}),
);
}
await editor.navigate(pageName);
@@ -222,10 +221,11 @@ export async function weeklyNoteCommand() {
export async function insertTemplateText(cmdDef: any) {
const cursorPos = await editor.getCursor();
const page = await editor.getCurrentPage();
const pageMeta = await space.getPageMeta(page);
let templateText: string = cmdDef.value;
const carretPos = templateText.indexOf("|^|");
templateText = templateText.replace("|^|", "");
templateText = replaceTemplateVars(templateText, page);
templateText = replaceTemplateVars(templateText, pageMeta);
await editor.insertAtCursor(templateText);
if (carretPos !== -1) {
await editor.moveCursor(cursorPos + carretPos);