Extracted syscall packages
parent
7f647758c2
commit
3aafa63073
|
@ -1,5 +1,6 @@
|
|||
export type PageMeta = {
|
||||
name: string;
|
||||
lastModified: number;
|
||||
version?: number;
|
||||
lastOpened?: number;
|
||||
created?: boolean;
|
||||
};
|
|
@ -0,0 +1,93 @@
|
|||
import { syscall } from "./syscall";
|
||||
|
||||
export function getCurrentPage(): Promise<string> {
|
||||
return syscall("editor.getCurrentPage");
|
||||
}
|
||||
|
||||
export function getText(): Promise<string> {
|
||||
return syscall("editor.getText");
|
||||
}
|
||||
|
||||
export function getCursor(): Promise<number> {
|
||||
return syscall("editor.getCursor");
|
||||
}
|
||||
|
||||
export function save(): Promise<void> {
|
||||
return syscall("editor.save");
|
||||
}
|
||||
|
||||
export function navigate(name: string, pos?: number): Promise<void> {
|
||||
return syscall("editor.navigate", name, pos);
|
||||
}
|
||||
|
||||
export function reloadPage(): Promise<void> {
|
||||
return syscall("editor.reloadPage");
|
||||
}
|
||||
|
||||
export function openUrl(url: string): Promise<void> {
|
||||
return syscall("editor.openUrl", url);
|
||||
}
|
||||
|
||||
export function flashNotification(message: string): Promise<void> {
|
||||
return syscall("editor.flashNotification", message);
|
||||
}
|
||||
|
||||
export function showRhs(html: string): Promise<void> {
|
||||
return syscall("editor.showRhs", html);
|
||||
}
|
||||
|
||||
export function insertAtPos(text: string, pos: number): Promise<void> {
|
||||
return syscall("editor.insertAtPos", text, pos);
|
||||
}
|
||||
|
||||
export function replaceRange(
|
||||
from: number,
|
||||
to: number,
|
||||
text: string
|
||||
): Promise<void> {
|
||||
return syscall("editor.replaceRange", from, to, text);
|
||||
}
|
||||
|
||||
export function moveCursor(pos: number): Promise<void> {
|
||||
return syscall("editor.moveCursor", pos);
|
||||
}
|
||||
|
||||
export function insertAtCursor(text: string): Promise<void> {
|
||||
return syscall("editor.insertAtCursor", text);
|
||||
}
|
||||
|
||||
export type SyntaxNode = {
|
||||
name: string;
|
||||
text: string;
|
||||
from: number;
|
||||
to: number;
|
||||
};
|
||||
|
||||
export function getSyntaxNodeUnderCursor(): Promise<SyntaxNode> {
|
||||
return syscall("editor.getSyntaxNodeUnderCursor");
|
||||
}
|
||||
|
||||
export function getLineUnderCursor(): Promise<string> {
|
||||
return syscall("editor.getLineUnderCursor");
|
||||
}
|
||||
|
||||
export function matchBefore(
|
||||
re: string
|
||||
): Promise<{ from: number; to: number; text: string } | null> {
|
||||
return syscall("editor.matchBefore", re);
|
||||
}
|
||||
|
||||
export function getSyntaxNodeAtPos(pos: number): Promise<SyntaxNode> {
|
||||
return syscall("editor.getSyntaxNodeAtPos", pos);
|
||||
}
|
||||
|
||||
export function dispatch(change: any): Promise<void> {
|
||||
return syscall("editor.dispatch", change);
|
||||
}
|
||||
|
||||
export function prompt(
|
||||
message: string,
|
||||
defaultValue = ""
|
||||
): Promise<string | undefined> {
|
||||
return syscall("editor.prompt", message, defaultValue);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import { syscall } from "./syscall";
|
||||
|
||||
export type KV = {
|
||||
key: string;
|
||||
value: any;
|
||||
};
|
||||
|
||||
export async function set(
|
||||
page: string,
|
||||
key: string,
|
||||
value: any
|
||||
): Promise<void> {
|
||||
return syscall("index.set", page, key, value);
|
||||
}
|
||||
|
||||
export async function batchSet(page: string, kvs: KV[]): Promise<void> {
|
||||
return syscall("index.batchSet", page, kvs);
|
||||
}
|
||||
|
||||
export async function get(page: string, key: string): Promise<any> {
|
||||
return syscall("index.get", page, key);
|
||||
}
|
||||
|
||||
export async function del(page: string, key: string): Promise<void> {
|
||||
return syscall("index.delete", page, key);
|
||||
}
|
||||
|
||||
export async function scanPrefixForPage(
|
||||
page: string,
|
||||
prefix: string
|
||||
): Promise<{ key: string; page: string; value: any }[]> {
|
||||
return syscall("index.scanPrefixForPage", page, prefix);
|
||||
}
|
||||
|
||||
export async function scanPrefixGlobal(
|
||||
prefix: string
|
||||
): Promise<{ key: string; page: string; value: any }[]> {
|
||||
return syscall("index.scanPrefixGlobal", prefix);
|
||||
}
|
||||
|
||||
export async function clearPageIndexForPage(page: string): Promise<void> {
|
||||
return syscall("index.clearPageIndexForPage", page);
|
||||
}
|
||||
|
||||
export async function deletePrefixForPage(
|
||||
page: string,
|
||||
prefix: string
|
||||
): Promise<void> {
|
||||
return syscall("index.deletePrefixForPage", page, prefix);
|
||||
}
|
||||
|
||||
export async function clearPageIndex(): Promise<void> {
|
||||
return syscall("index.clearPageIndex");
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "plugos-silverbullet-syscall",
|
||||
"version": "1.0.0"
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { syscall } from "./syscall";
|
||||
import { PageMeta } from "../common/types";
|
||||
|
||||
export async function listPages(): Promise<PageMeta[]> {
|
||||
return syscall("space.listPages");
|
||||
}
|
||||
|
||||
export async function readPage(
|
||||
name: string
|
||||
): Promise<{ text: string; meta: PageMeta }> {
|
||||
return syscall("space.readPage", name);
|
||||
}
|
||||
|
||||
export async function writePage(name: string, text: string): Promise<PageMeta> {
|
||||
return syscall("space.writePage", name, text);
|
||||
}
|
||||
|
||||
export async function deletePage(name: string): Promise<PageMeta> {
|
||||
return syscall("space.deletePage", name);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { syscall } from "./syscall";
|
||||
|
||||
export async function invokeFunctionOnServer(
|
||||
name: string,
|
||||
...args: any[]
|
||||
): Promise<any> {
|
||||
return syscall("system.invokeFunctionOnServer", name, ...args);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import { syscall } from "./syscall";
|
||||
|
||||
export async function dispatch(eventName: string, data: any): Promise<void> {
|
||||
return syscall("event.dispatch", eventName, data);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { syscall } from "./syscall";
|
||||
|
||||
export async function json(url: RequestInfo, init: RequestInit): Promise<any> {
|
||||
return syscall("fetch.json", url, init);
|
||||
}
|
||||
|
||||
export async function text(
|
||||
url: RequestInfo,
|
||||
init: RequestInit
|
||||
): Promise<string> {
|
||||
return syscall("fetch.text", url, init);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "plugos-syscall",
|
||||
"version": "1.0.0"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { syscall } from "./syscall";
|
||||
|
||||
export async function run(
|
||||
cmd: string,
|
||||
args: string[]
|
||||
): Promise<{ stdout: string; stderr: string }> {
|
||||
return syscall("shell.run", cmd, args);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import { syscall } from "./syscall";
|
||||
|
||||
export type KV = {
|
||||
key: string;
|
||||
value: any;
|
||||
};
|
||||
|
||||
export async function set(key: string, value: any): Promise<void> {
|
||||
return syscall("store.set", key, value);
|
||||
}
|
||||
|
||||
export async function batchSet(kvs: KV[]): Promise<void> {
|
||||
return syscall("store.batchSet", kvs);
|
||||
}
|
||||
|
||||
export async function get(key: string): Promise<any> {
|
||||
return syscall("store.get", key);
|
||||
}
|
||||
|
||||
export async function del(key: string): Promise<void> {
|
||||
return syscall("store.delete", key);
|
||||
}
|
||||
|
||||
export async function batchDel(keys: string[]): Promise<void> {
|
||||
return syscall("store.batchDelete", keys);
|
||||
}
|
||||
|
||||
export async function queryPrefix(
|
||||
prefix: string
|
||||
): Promise<{ key: string; value: any }[]> {
|
||||
return syscall("store.scanPrefix", prefix);
|
||||
}
|
||||
|
||||
export async function deletePrefix(prefix: string): Promise<void> {
|
||||
return syscall("store.deletePrefix", prefix);
|
||||
}
|
||||
|
||||
export async function deleteAll(): Promise<void> {
|
||||
return syscall("store.deleteAll");
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
declare global {
|
||||
function syscall(name: string, ...args: any[]): Promise<any>;
|
||||
}
|
||||
|
||||
export const syscall = self.syscall;
|
|
@ -1,7 +1,6 @@
|
|||
import { syscall } from "../lib/syscall";
|
||||
import { insertAtCursor } from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
export async function insertToday() {
|
||||
console.log("Inserting date!");
|
||||
let niceDate = new Date().toISOString().split("T")[0];
|
||||
await syscall("editor.insertAtCursor", niceDate);
|
||||
await insertAtCursor(niceDate);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { IndexEvent } from "../../webapp/app_event";
|
||||
import { whiteOutQueries } from "./materialized_queries";
|
||||
import { syscall } from "../lib/syscall";
|
||||
|
||||
import { batchSet } from "plugos-silverbullet-syscall/index";
|
||||
|
||||
type Item = {
|
||||
item: string;
|
||||
|
@ -35,5 +36,5 @@ export async function indexItems({ name, text }: IndexEvent) {
|
|||
});
|
||||
}
|
||||
console.log("Found", items.length, "item(s)");
|
||||
await syscall("index.batchSet", name, items);
|
||||
await batchSet(name, items);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { syscall } from "../lib/syscall";
|
||||
import mdParser from "../../webapp/parser";
|
||||
import { getText } from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
export async function renderMD() {
|
||||
let text = await syscall("editor.getText");
|
||||
let text = await getText();
|
||||
let tree = mdParser.parser.parse(text);
|
||||
let slicesToRemove: [number, number][] = [];
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { syscall } from "../lib/syscall";
|
||||
import {
|
||||
getCursor,
|
||||
getText,
|
||||
insertAtPos,
|
||||
replaceRange,
|
||||
} from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
export async function toggleH1() {
|
||||
await togglePrefix("# ");
|
||||
|
@ -13,15 +18,15 @@ function lookBack(s: string, pos: number, backString: string): boolean {
|
|||
}
|
||||
|
||||
async function togglePrefix(prefix: string) {
|
||||
let text = (await syscall("editor.getText")) as string;
|
||||
let pos = (await syscall("editor.getCursor")) as number;
|
||||
let text = await getText();
|
||||
let pos = await getCursor();
|
||||
if (text[pos] === "\n") {
|
||||
pos--;
|
||||
}
|
||||
while (pos > 0 && text[pos] !== "\n") {
|
||||
if (lookBack(text, pos, prefix)) {
|
||||
// Already has this prefix, let's flip it
|
||||
await syscall("editor.replaceRange", pos - prefix.length, pos, "");
|
||||
await replaceRange(pos - prefix.length, pos, "");
|
||||
return;
|
||||
}
|
||||
pos--;
|
||||
|
@ -29,5 +34,5 @@ async function togglePrefix(prefix: string) {
|
|||
if (pos) {
|
||||
pos++;
|
||||
}
|
||||
await syscall("editor.insertAtPos", prefix, pos);
|
||||
await insertAtPos(prefix, pos);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
import { syscall } from "../lib/syscall";
|
||||
import {
|
||||
flashNotification,
|
||||
getCurrentPage,
|
||||
reloadPage,
|
||||
save,
|
||||
} from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
import { readPage, writePage } from "plugos-silverbullet-syscall/space";
|
||||
import { invokeFunctionOnServer } from "plugos-silverbullet-syscall/system";
|
||||
import { scanPrefixGlobal } from "plugos-silverbullet-syscall";
|
||||
|
||||
export const queryRegex =
|
||||
/(<!--\s*#query\s+(?<table>\w+)\s*(filter\s+["'“”‘’](?<filter>[^"'“”‘’]+)["'“”‘’])?\s*(group by\s+(?<groupBy>\w+))?\s*-->)(.+?)(<!--\s*#end\s*-->)/gs;
|
||||
/(<!--\s*#query\s+(?<table>\w+)\s*(filter\s+["'“”‘’](?<filter>[^"'“”‘’]+)["'“”‘’])?\s*-->)(.+?)(<!--\s*#end\s*-->)/gs;
|
||||
|
||||
export function whiteOutQueries(text: string): string {
|
||||
return text.replaceAll(queryRegex, (match) =>
|
||||
|
@ -25,18 +34,16 @@ async function replaceAsync(
|
|||
}
|
||||
|
||||
export async function updateMaterializedQueriesCommand() {
|
||||
await syscall(
|
||||
"system.invokeFunctionOnServer",
|
||||
"updateMaterializedQueriesOnPage",
|
||||
await syscall("editor.getCurrentPage")
|
||||
);
|
||||
await syscall("editor.reloadPage");
|
||||
await syscall("editor.flashNotification", "Updated materialized queries");
|
||||
const currentPage = await getCurrentPage();
|
||||
await save();
|
||||
await invokeFunctionOnServer("updateMaterializedQueriesOnPage", currentPage);
|
||||
await reloadPage();
|
||||
await flashNotification("Updated materialized queries");
|
||||
}
|
||||
|
||||
// Called from client, running on server
|
||||
export async function updateMaterializedQueriesOnPage(pageName: string) {
|
||||
let { text } = await syscall("space.readPage", pageName);
|
||||
let { text } = await readPage(pageName);
|
||||
text = await replaceAsync(text, queryRegex, async (match, ...args) => {
|
||||
let { table, filter, groupBy } = args[args.length - 1];
|
||||
const startQuery = args[0];
|
||||
|
@ -48,22 +55,19 @@ export async function updateMaterializedQueriesOnPage(pageName: string) {
|
|||
key,
|
||||
page,
|
||||
value: { task, complete, children },
|
||||
} of await syscall("index.scanPrefixGlobal", "task:")) {
|
||||
} of await scanPrefixGlobal("task:")) {
|
||||
let [, pos] = key.split(":");
|
||||
if (!filter || (filter && task.includes(filter))) {
|
||||
results.push(
|
||||
`* [${complete ? "x" : " "}] [[${page}@${pos}]] ${task}`
|
||||
`* [${complete ? "x" : " "}] [[${page}@${pos}]] ${task}` +
|
||||
(children ? "\n" + children.join("\n") : "")
|
||||
);
|
||||
if (children) {
|
||||
results.push(children.join("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return `${startQuery}\n${results.join("\n")}\n${endQuery}`;
|
||||
return `${startQuery}\n${results.sort().join("\n")}\n${endQuery}`;
|
||||
case "link":
|
||||
let uniqueLinks = new Set<string>();
|
||||
for (let {key, page, value: name} of await syscall(
|
||||
"index.scanPrefixGlobal",
|
||||
for (let { key, page, value: name } of await scanPrefixGlobal(
|
||||
`pl:${pageName}:`
|
||||
)) {
|
||||
let [, pos] = key.split(":");
|
||||
|
@ -80,20 +84,20 @@ export async function updateMaterializedQueriesOnPage(pageName: string) {
|
|||
key,
|
||||
page,
|
||||
value: { item, children },
|
||||
}; of await syscall("index.scanPrefixGlobal", "it:")) {
|
||||
} of await scanPrefixGlobal("it:")) {
|
||||
let [, pos] = key.split(":");
|
||||
if (!filter || (filter && item.includes(filter))) {
|
||||
results.push(`* [[${page}@${pos}]] ${item}`);
|
||||
if (children) {
|
||||
results.push(children.join("\n"));
|
||||
results.push(
|
||||
`* [[${page}@${pos}]] ${item}` +
|
||||
(children ? "\n" + children.join("\n") : "")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return `${startQuery}\n${results.join("\n")}\n${endQuery}`;
|
||||
return `${startQuery}\n${results.sort().join("\n")}\n${endQuery}`;
|
||||
default:
|
||||
return match;
|
||||
}
|
||||
});
|
||||
// console.log("New text", text);
|
||||
await syscall("space.writePage", pageName, text);
|
||||
await writePage(pageName, text);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import { ClickEvent } from "../../webapp/app_event";
|
||||
import { syscall } from "../lib/syscall";
|
||||
import { updateMaterializedQueriesCommand } from "./materialized_queries";
|
||||
import {
|
||||
getSyntaxNodeAtPos,
|
||||
getSyntaxNodeUnderCursor,
|
||||
navigate as navigateTo,
|
||||
openUrl,
|
||||
} from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
const materializedQueryPrefix = /<!--\s*#query\s+/;
|
||||
|
||||
|
@ -16,10 +21,10 @@ async function navigate(syntaxNode: any) {
|
|||
if (pageLink.includes("@")) {
|
||||
[pageLink, pos] = syntaxNode.text.split("@");
|
||||
}
|
||||
await syscall("editor.navigate", pageLink, +pos);
|
||||
await navigateTo(pageLink, +pos);
|
||||
break;
|
||||
case "URL":
|
||||
await syscall("editor.openUrl", syntaxNode.text);
|
||||
await openUrl(syntaxNode.text);
|
||||
break;
|
||||
case "CommentBlock":
|
||||
if (syntaxNode.text.match(materializedQueryPrefix)) {
|
||||
|
@ -30,19 +35,19 @@ async function navigate(syntaxNode: any) {
|
|||
// Markdown link: [bla](URLHERE) needs extraction
|
||||
let match = /\[[^\\]+\]\(([^\)]+)\)/.exec(syntaxNode.text);
|
||||
if (match) {
|
||||
await syscall("editor.openUrl", match[1]);
|
||||
await openUrl(match[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export async function linkNavigate() {
|
||||
await navigate(await syscall("editor.getSyntaxNodeUnderCursor"));
|
||||
await navigate(await getSyntaxNodeUnderCursor());
|
||||
}
|
||||
|
||||
export async function clickNavigate(event: ClickEvent) {
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
let syntaxNode = await syscall("editor.getSyntaxNodeAtPos", event.pos);
|
||||
let syntaxNode = await getSyntaxNodeAtPos(event.pos);
|
||||
await navigate(syntaxNode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,27 @@
|
|||
import { IndexEvent } from "../../webapp/app_event";
|
||||
import { pageLinkRegex } from "../../webapp/constant";
|
||||
import { syscall } from "../lib/syscall";
|
||||
import {
|
||||
batchSet,
|
||||
clearPageIndex as clearPageIndexSyscall,
|
||||
clearPageIndexForPage,
|
||||
scanPrefixGlobal,
|
||||
} from "plugos-silverbullet-syscall/index";
|
||||
import {
|
||||
flashNotification,
|
||||
getCurrentPage,
|
||||
getText,
|
||||
matchBefore,
|
||||
navigate,
|
||||
} from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
import { dispatch } from "plugos-syscall/event";
|
||||
import {
|
||||
deletePage as deletePageSyscall,
|
||||
listPages,
|
||||
readPage,
|
||||
writePage,
|
||||
} from "plugos-silverbullet-syscall/space";
|
||||
import { invokeFunctionOnServer } from "plugos-silverbullet-syscall/system";
|
||||
|
||||
const wikilinkRegex = new RegExp(pageLinkRegex, "g");
|
||||
|
||||
|
@ -20,25 +41,21 @@ export async function indexLinks({ name, text }: IndexEvent) {
|
|||
});
|
||||
}
|
||||
console.log("Found", backLinks.length, "wiki link(s)");
|
||||
await syscall("index.batchSet", name, backLinks);
|
||||
await batchSet(name, backLinks);
|
||||
}
|
||||
|
||||
export async function deletePage() {
|
||||
let pageName = await syscall("editor.getCurrentPage");
|
||||
let pageName = await getCurrentPage();
|
||||
console.log("Navigating to start page");
|
||||
await syscall("editor.navigate", "start");
|
||||
await navigate("start");
|
||||
console.log("Deleting page from space");
|
||||
await syscall("space.deletePage", pageName);
|
||||
await deletePageSyscall(pageName);
|
||||
}
|
||||
|
||||
export async function renamePage() {
|
||||
const oldName = await syscall("editor.getCurrentPage");
|
||||
const oldName = await getCurrentPage();
|
||||
console.log("Old name is", oldName);
|
||||
const newName = await syscall(
|
||||
"editor.prompt",
|
||||
`Rename ${oldName} to:`,
|
||||
oldName
|
||||
);
|
||||
const newName = await prompt(`Rename ${oldName} to:`, oldName);
|
||||
if (!newName) {
|
||||
return;
|
||||
}
|
||||
|
@ -47,13 +64,13 @@ export async function renamePage() {
|
|||
let pagesToUpdate = await getBackLinks(oldName);
|
||||
console.log("All pages containing backlinks", pagesToUpdate);
|
||||
|
||||
let text = await syscall("editor.getText");
|
||||
let text = await getText();
|
||||
console.log("Writing new page to space");
|
||||
await syscall("space.writePage", newName, text);
|
||||
await writePage(newName, text);
|
||||
console.log("Navigating to new page");
|
||||
await syscall("editor.navigate", newName);
|
||||
await navigate(newName);
|
||||
console.log("Deleting page from space");
|
||||
await syscall("space.deletePage", oldName);
|
||||
await deletePageSyscall(oldName);
|
||||
|
||||
let pageToUpdateSet = new Set<string>();
|
||||
for (let pageToUpdate of pagesToUpdate) {
|
||||
|
@ -62,7 +79,7 @@ export async function renamePage() {
|
|||
|
||||
for (let pageToUpdate of pageToUpdateSet) {
|
||||
console.log("Now going to update links in", pageToUpdate);
|
||||
let { text } = await syscall("space.readPage", pageToUpdate);
|
||||
let { text } = await readPage(pageToUpdate);
|
||||
console.log("Received text", text);
|
||||
if (!text) {
|
||||
// Page likely does not exist, but at least we can skip it
|
||||
|
@ -71,7 +88,7 @@ export async function renamePage() {
|
|||
let newText = text.replaceAll(`[[${oldName}]]`, `[[${newName}]]`);
|
||||
if (text !== newText) {
|
||||
console.log("Changes made, saving...");
|
||||
await syscall("space.writePage", pageToUpdate, newText);
|
||||
await writePage(pageToUpdate, newText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +99,7 @@ type BackLink = {
|
|||
};
|
||||
|
||||
async function getBackLinks(pageName: string): Promise<BackLink[]> {
|
||||
let allBackLinks = await syscall("index.scanPrefixGlobal", `pl:${pageName}:`);
|
||||
let allBackLinks = await scanPrefixGlobal(`pl:${pageName}:`);
|
||||
let pagesToUpdate: BackLink[] = [];
|
||||
for (let { key, value } of allBackLinks) {
|
||||
let keyParts = key.split(":");
|
||||
|
@ -95,28 +112,28 @@ async function getBackLinks(pageName: string): Promise<BackLink[]> {
|
|||
}
|
||||
|
||||
export async function showBackLinks() {
|
||||
const pageName = await syscall("editor.getCurrentPage");
|
||||
const pageName = await getCurrentPage();
|
||||
let backLinks = await getBackLinks(pageName);
|
||||
|
||||
console.log("Backlinks", backLinks);
|
||||
}
|
||||
|
||||
export async function reindexCommand() {
|
||||
await syscall("editor.flashNotification", "Reindexing...");
|
||||
await syscall("system.invokeFunctionOnServer", "reindexSpace");
|
||||
await syscall("editor.flashNotification", "Reindexing done");
|
||||
await flashNotification("Reindexing...");
|
||||
await invokeFunctionOnServer("reindexSpace");
|
||||
await flashNotification("Reindexing done");
|
||||
}
|
||||
|
||||
// Completion
|
||||
export async function pageComplete() {
|
||||
let prefix = await syscall("editor.matchBefore", "\\[\\[[\\w\\s]*");
|
||||
let prefix = await matchBefore("\\[\\[[\\w\\s]*");
|
||||
if (!prefix) {
|
||||
return null;
|
||||
}
|
||||
let allPages = await syscall("space.listPages");
|
||||
let allPages = await listPages();
|
||||
return {
|
||||
from: prefix.from + 2,
|
||||
options: allPages.map((pageMeta: any) => ({
|
||||
options: allPages.map((pageMeta) => ({
|
||||
label: pageMeta.name,
|
||||
type: "page",
|
||||
})),
|
||||
|
@ -126,13 +143,13 @@ export async function pageComplete() {
|
|||
// Server functions
|
||||
export async function reindexSpace() {
|
||||
console.log("Clearing page index...");
|
||||
await syscall("index.clearPageIndex");
|
||||
await clearPageIndexSyscall();
|
||||
console.log("Listing all pages");
|
||||
let pages = await syscall("space.listPages");
|
||||
let pages = await listPages();
|
||||
for (let { name } of pages) {
|
||||
console.log("Indexing", name);
|
||||
const pageObj = await syscall("space.readPage", name);
|
||||
await syscall("event.dispatch", "page:index", {
|
||||
const pageObj = await readPage(name);
|
||||
await dispatch("page:index", {
|
||||
name,
|
||||
text: pageObj.text,
|
||||
});
|
||||
|
@ -141,5 +158,5 @@ export async function reindexSpace() {
|
|||
|
||||
export async function clearPageIndex(page: string) {
|
||||
console.log("Clearing page index for page", page);
|
||||
await syscall("index.clearPageIndexForPage", page);
|
||||
await clearPageIndexForPage(page);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { syscall } from "../lib/syscall";
|
||||
|
||||
function countWords(str: string): number {
|
||||
const matches = str.match(/[\w\d\'-]+/gi);
|
||||
return matches ? matches.length : 0;
|
||||
|
@ -9,12 +7,3 @@ function readingTime(wordCount: number): number {
|
|||
// 225 is average word reading speed for adults
|
||||
return Math.ceil(wordCount / 225);
|
||||
}
|
||||
|
||||
export async function wordCount({ text }: { text: string }) {
|
||||
let sysCallText = (await syscall("editor.getText")) as string;
|
||||
const count = countWords(sysCallText);
|
||||
console.log("Word count", count);
|
||||
let syntaxNode = await syscall("editor.getSyntaxNodeUnderCursor");
|
||||
console.log("Syntax node", syntaxNode);
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
build:
|
||||
curl https://unicode.org/Public/emoji/14.0/emoji-test.txt > emoji-data.txt
|
||||
node build.js
|
||||
rm emoji-data.txt
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// @ts-ignore
|
||||
import emojis from "./emoji.json";
|
||||
import { syscall } from "../lib/syscall";
|
||||
import { matchBefore } from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
const emojiMatcher = /\(([^\)]+)\)\s+(.+)$/;
|
||||
|
||||
export async function emojiCompleter() {
|
||||
let prefix = await syscall("editor.matchBefore", ":[\\w\\s]*");
|
||||
let prefix = await matchBefore(":[\\w\\s]*");
|
||||
if (!prefix) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { syscall } from "../lib/syscall";
|
||||
import { run } from "plugos-syscall/shell";
|
||||
import { flashNotification, prompt } from "plugos-silverbullet-syscall/editor";
|
||||
import { invokeFunctionOnServer } from "plugos-silverbullet-syscall/system";
|
||||
|
||||
export async function commit(message?: string) {
|
||||
if (!message) {
|
||||
|
@ -8,9 +10,9 @@ export async function commit(message?: string) {
|
|||
"Snapshotting the current space to git with commit message",
|
||||
message
|
||||
);
|
||||
await syscall("shell.run", "git", ["add", "./*.md"]);
|
||||
await run("git", ["add", "./*.md"]);
|
||||
try {
|
||||
await syscall("shell.run", "git", ["commit", "-a", "-m", message]);
|
||||
await run("git", ["commit", "-a", "-m", message]);
|
||||
} catch (e) {
|
||||
// We can ignore, this happens when there's no changes to commit
|
||||
}
|
||||
|
@ -18,26 +20,26 @@ export async function commit(message?: string) {
|
|||
}
|
||||
|
||||
export async function snapshotCommand() {
|
||||
let revName = await syscall("editor.prompt", `Revision name:`);
|
||||
let revName = await prompt(`Revision name:`);
|
||||
if (!revName) {
|
||||
revName = "Snapshot";
|
||||
}
|
||||
console.log("Revision name", revName);
|
||||
await syscall("system.invokeFunctionOnServer", "commit", revName);
|
||||
await invokeFunctionOnServer("commit", revName);
|
||||
}
|
||||
|
||||
export async function syncCommand() {
|
||||
await syscall("editor.flashNotification", "Syncing with git");
|
||||
await syscall("system.invokeFunctionOnServer", "sync");
|
||||
await syscall("editor.flashNotification", "Git sync complete!");
|
||||
await flashNotification("Syncing with git");
|
||||
await invokeFunctionOnServer("sync");
|
||||
await flashNotification("Git sync complete!");
|
||||
}
|
||||
|
||||
export async function sync() {
|
||||
console.log("Going to sync with git");
|
||||
await commit();
|
||||
console.log("Then pulling from remote");
|
||||
await syscall("shell.run", "git", ["pull"]);
|
||||
await run("git", ["pull"]);
|
||||
console.log("And then pushing to remote");
|
||||
await syscall("shell.run", "git", ["push"]);
|
||||
await run("git", ["push"]);
|
||||
console.log("Done!");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import MarkdownIt from "markdown-it";
|
||||
import { syscall } from "../lib/syscall";
|
||||
import { getText, showRhs } from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
var taskLists = require("markdown-it-task-lists");
|
||||
|
||||
|
@ -10,7 +10,7 @@ const md = new MarkdownIt({
|
|||
}).use(taskLists);
|
||||
|
||||
export async function renderMarkdown() {
|
||||
let text = await syscall("editor.getText");
|
||||
let text = await getText();
|
||||
let html = md.render(text);
|
||||
await syscall("editor.showRhs", `<html><body>${html}</body></html>`);
|
||||
await showRhs(`<html><body>${html}</body></html>`);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "plugs",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"plugos-silverbullet-syscall": "file:../plugos-silverbullet-syscall",
|
||||
"plugos-syscall": "file:../plugos-syscall"
|
||||
}
|
||||
}
|
|
@ -1,8 +1,14 @@
|
|||
import type { ClickEvent } from "../../webapp/app_event";
|
||||
import { IndexEvent } from "../../webapp/app_event";
|
||||
import { syscall } from "../lib/syscall";
|
||||
|
||||
import { whiteOutQueries } from "../core/materialized_queries";
|
||||
import { batchSet, scanPrefixGlobal } from "plugos-silverbullet-syscall/index";
|
||||
import { readPage, writePage } from "plugos-silverbullet-syscall/space";
|
||||
import {
|
||||
dispatch,
|
||||
getLineUnderCursor,
|
||||
getSyntaxNodeAtPos,
|
||||
} from "plugos-silverbullet-syscall/editor";
|
||||
|
||||
const allTasksPageName = "ALL TASKS";
|
||||
const taskRe = /[\-\*]\s*\[([ Xx])\]\s*(.*)/g;
|
||||
|
@ -45,11 +51,11 @@ export async function indexTasks({ name, text }: IndexEvent) {
|
|||
});
|
||||
}
|
||||
console.log("Found", tasks.length, "task(s)");
|
||||
await syscall("index.batchSet", name, tasks);
|
||||
await batchSet(name, tasks);
|
||||
}
|
||||
|
||||
export async function updateTaskPage() {
|
||||
let allTasks = await syscall("index.scanPrefixGlobal", "task:");
|
||||
let allTasks = await scanPrefixGlobal("task:");
|
||||
let pageTasks = new Map<string, Task[]>();
|
||||
for (let {
|
||||
key,
|
||||
|
@ -61,7 +67,7 @@ export async function updateTaskPage() {
|
|||
}
|
||||
let [, pos] = key.split(":");
|
||||
let tasks = pageTasks.get(page) || [];
|
||||
tasks.push({ task, complete, pos });
|
||||
tasks.push({ task, complete, pos: +pos });
|
||||
pageTasks.set(page, tasks);
|
||||
}
|
||||
|
||||
|
@ -78,17 +84,17 @@ export async function updateTaskPage() {
|
|||
}
|
||||
|
||||
let taskMd = mdPieces.join("\n");
|
||||
await syscall("space.writePage", allTasksPageName, taskMd);
|
||||
await writePage(allTasksPageName, taskMd);
|
||||
}
|
||||
|
||||
export async function taskToggle(event: ClickEvent) {
|
||||
let syntaxNode = await syscall("editor.getSyntaxNodeAtPos", event.pos);
|
||||
let syntaxNode = await getSyntaxNodeAtPos(event.pos);
|
||||
if (syntaxNode && syntaxNode.name === "TaskMarker") {
|
||||
let changeTo = "[x]";
|
||||
if (syntaxNode.text === "[x]" || syntaxNode.text === "[X]") {
|
||||
changeTo = "[ ]";
|
||||
}
|
||||
await syscall("editor.dispatch", {
|
||||
await dispatch({
|
||||
changes: {
|
||||
from: syntaxNode.from,
|
||||
to: syntaxNode.to,
|
||||
|
@ -100,12 +106,12 @@ export async function taskToggle(event: ClickEvent) {
|
|||
});
|
||||
if (event.page === allTasksPageName) {
|
||||
// Propagate back to the page in question
|
||||
let line = (await syscall("editor.getLineUnderCursor")) as string;
|
||||
let line = await getLineUnderCursor();
|
||||
let match = line.match(extractPageLink);
|
||||
if (match) {
|
||||
let [, page, posS] = match;
|
||||
let pos = +posS;
|
||||
let pageData = await syscall("space.readPage", page);
|
||||
let pageData = await readPage(page);
|
||||
let text = pageData.text;
|
||||
|
||||
// Apply the toggle
|
||||
|
@ -113,7 +119,7 @@ export async function taskToggle(event: ClickEvent) {
|
|||
text.substring(0, pos) +
|
||||
text.substring(pos).replace(/^([\-\*]\s*)\[[ xX]\]/, "$1" + changeTo);
|
||||
|
||||
await syscall("space.writePage", page, text);
|
||||
await writePage(page, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { mkdir, readdir, readFile, stat, unlink, writeFile } from "fs/promises";
|
||||
import * as path from "path";
|
||||
import { PageMeta } from "./types";
|
||||
import { PageMeta } from "../common/types";
|
||||
import { EventHook } from "../plugos/hooks/event";
|
||||
|
||||
export interface Storage {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PageMeta } from "../types";
|
||||
import { PageMeta } from "../../common/types";
|
||||
import { SysCallMapping } from "../../plugos/system";
|
||||
import { Storage } from "../disk_storage";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { PageMeta } from "../types";
|
||||
import { FilterList, Option } from "./filter";
|
||||
import { faFileLines } from "@fortawesome/free-solid-svg-icons";
|
||||
import { PageMeta } from "../../common/types";
|
||||
|
||||
export function PageNavigator({
|
||||
allPages,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { PageMeta } from "./types";
|
||||
import { EventEmitter } from "../common/event";
|
||||
import { Manifest } from "../common/manifest";
|
||||
import { safeRun } from "./util";
|
||||
import { Plug } from "../plugos/plug";
|
||||
import { PageMeta } from "../common/types";
|
||||
|
||||
export type SpaceEvents = {
|
||||
pageCreated: (meta: PageMeta) => void;
|
||||
|
|
|
@ -36,6 +36,9 @@ export default (editor: Editor): SysCallMapping => ({
|
|||
getCursor: (): number => {
|
||||
return editor.editorView!.state.selection.main.from;
|
||||
},
|
||||
save: async () => {
|
||||
return editor.save(true);
|
||||
},
|
||||
navigate: async (ctx, name: string, pos: number) => {
|
||||
await editor.navigate(name, pos);
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Editor } from "../editor";
|
||||
import { PageMeta } from "../types";
|
||||
import { SysCallMapping } from "../../plugos/system";
|
||||
import { PageMeta } from "../../common/types";
|
||||
|
||||
export default (editor: Editor): SysCallMapping => ({
|
||||
listPages: async (): Promise<PageMeta[]> => {
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
import { AppCommand } from "./hooks/command";
|
||||
|
||||
export type PageMeta = {
|
||||
name: string;
|
||||
lastModified: number;
|
||||
version?: number;
|
||||
lastOpened?: number;
|
||||
created?: boolean;
|
||||
};
|
||||
import { PageMeta } from "../common/types";
|
||||
|
||||
export const slashCommandRegexp = /\/[\w\-]*/;
|
||||
|
||||
|
|
Loading…
Reference in New Issue