Support slashes in file names
This commit is contained in:
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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 [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
Reference in New Issue
Block a user