Support slashes in file names

This commit is contained in:
Zef Hemel
2022-02-27 10:17:43 +01:00
parent 158e1cb2ef
commit 89f93963f5
12 changed files with 142 additions and 71 deletions
+5 -1
View File
@@ -1,4 +1,8 @@
export type AppEvent = "app:ready" | "page:save" | "page:load" | "page:click";
export type AppEvent =
| "app:ready"
| "page:save"
| "page:click"
| "editor:complete";
export type ClickEvent = {
pos: number;
+31 -14
View File
@@ -134,10 +134,17 @@ export class Editor {
}
// TODO: Parallelize?
async dispatchAppEvent(name: AppEvent, data?: any) {
async dispatchAppEvent(name: AppEvent, data?: any): Promise<any[]> {
let results: any[] = [];
for (let plugin of this.plugins) {
await plugin.dispatchEvent(name, data);
let pluginResults = await plugin.dispatchEvent(name, data);
if (pluginResults) {
for (let result of pluginResults) {
results.push(result);
}
}
}
return results;
}
get currentPage(): PageMeta | undefined {
@@ -176,7 +183,7 @@ export class Editor {
closeBrackets(),
autocompletion({
override: [
this.pageCompleter.bind(this),
this.pluginCompleter.bind(this),
this.commandCompleter.bind(this),
],
}),
@@ -223,6 +230,14 @@ export class Editor {
return true;
},
},
{
key: "Ctrl-s",
mac: "Cmd-s",
run: (target): boolean => {
this.save();
return true;
},
},
{
key: "Ctrl-.",
mac: "Cmd-.",
@@ -258,18 +273,20 @@ export class Editor {
});
}
pageCompleter(ctx: CompletionContext): CompletionResult | null {
let prefix = ctx.matchBefore(/\[\[[\w\s]*/);
if (!prefix) {
return null;
async pluginCompleter(
ctx: CompletionContext
): Promise<CompletionResult | null> {
let allCompletionResults = await this.dispatchAppEvent("editor:complete");
// console.log("All results", allCompletionResults);
if (allCompletionResults.length === 1) {
return allCompletionResults[0];
} else if (allCompletionResults.length > 1) {
console.error(
"Got completion results from multiple sources, cannot deal with that",
allCompletionResults
);
}
return {
from: prefix.from + 2,
options: this.viewState.allPages.map((pageMeta) => ({
label: pageMeta.name,
type: "page",
})),
};
return null;
}
commandCompleter(ctx: CompletionContext): CompletionResult | null {
+8 -5
View File
@@ -113,14 +113,17 @@ export class Plugin {
return await this.runningFunctions.get(name)!.invoke(args);
}
async dispatchEvent(name: string, data?: any) {
async dispatchEvent(name: string, data?: any): Promise<any[]> {
let functionsToSpawn = this.manifest!.events[name];
if (functionsToSpawn) {
await Promise.all(
functionsToSpawn.map(async (functionToSpawn: string) => {
await this.invoke(functionToSpawn, [data]);
})
return await Promise.all(
functionsToSpawn.map(
async (functionToSpawn: string) =>
await this.invoke(functionToSpawn, [data])
)
);
} else {
return [];
}
}
+2 -4
View File
@@ -1,10 +1,8 @@
import { SyscallContext } from "../plugins/runtime";
export default {
"db.put": (ctx: SyscallContext, key: string, value: any) => {
"db.put": (key: string, value: any) => {
localStorage.setItem(key, value);
},
"db.get": (ctx: SyscallContext, key: string) => {
"db.get": (key: string) => {
return localStorage.getItem(key);
},
};
+34
View File
@@ -9,6 +9,22 @@ type SyntaxNode = {
to: number;
};
function ensureAnchor(expr: any, start: boolean) {
var _a;
let { source } = expr;
let addStart = start && source[0] != "^",
addEnd = source[source.length - 1] != "$";
if (!addStart && !addEnd) return expr;
return new RegExp(
`${addStart ? "^" : ""}(?:${source})${addEnd ? "$" : ""}`,
(_a = expr.flags) !== null && _a !== void 0
? _a
: expr.ignoreCase
? "i"
: ""
);
}
export default (editor: Editor) => ({
"editor.getText": () => {
return editor.editorView?.state.sliceDoc();
@@ -71,6 +87,24 @@ export default (editor: Editor) => ({
}
}
},
"editor.matchBefore": (
regexp: string
): { from: number; to: number; text: string } | null => {
const editorState = editor.editorView!.state;
let selection = editorState.selection.main;
let from = selection.from;
if (selection.empty) {
let line = editorState.doc.lineAt(from);
let start = Math.max(line.from, from - 250);
let str = line.text.slice(start - line.from, from - line.from);
let found = str.search(ensureAnchor(new RegExp(regexp), false));
// console.log("Line", line, start, str, new RegExp(regexp), found);
return found < 0
? null
: { from: start + found, to: from, text: str.slice(found) };
}
return null;
},
"editor.getSyntaxNodeAtPos": (pos: number): SyntaxNode | undefined => {
const editorState = editor.editorView!.state;
let node = syntaxTree(editorState).resolveInner(pos);
+2 -8
View File
@@ -1,22 +1,16 @@
import { Editor } from "../editor";
import { SyscallContext } from "../plugins/runtime";
import { PageMeta } from "../types";
export default (editor: Editor) => ({
"space.listPages": (ctx: SyscallContext): PageMeta[] => {
"space.listPages": (): PageMeta[] => {
return editor.viewState.allPages;
},
"space.readPage": async (
ctx: SyscallContext,
name: string
): Promise<{ text: string; meta: PageMeta }> => {
return await editor.fs.readPage(name);
},
"space.writePage": async (
ctx: SyscallContext,
name: string,
text: string
): Promise<PageMeta> => {
"space.writePage": async (name: string, text: string): Promise<PageMeta> => {
return await editor.fs.writePage(name, text);
},
});
+1 -3
View File
@@ -1,5 +1,3 @@
import { SyscallContext } from "../plugins/runtime";
// @ts-ignore
let frameTest = document.getElementById("main-frame");
@@ -13,7 +11,7 @@ window.addEventListener("message", async (event) => {
});
export default {
"ui.update": function (ctx: SyscallContext, doc: any) {
"ui.update": function (doc: any) {
// frameTest.contentWindow.postMessage({
// type: "loadContent",
// doc: doc,