diff --git a/plugs/editor/editor.ts b/plugs/editor/editor.ts index 78d8cff3..ae80b8de 100644 --- a/plugs/editor/editor.ts +++ b/plugs/editor/editor.ts @@ -1,4 +1,8 @@ -import { clientStore, editor } from "@silverbulletmd/silverbullet/syscalls"; +import { + clientStore, + codeWidget, + editor, +} from "@silverbulletmd/silverbullet/syscalls"; // Run on "editor:init" export async function setEditorMode() { @@ -79,7 +83,8 @@ export async function customFlashMessage(_def: any, message: string) { export async function reloadSystem() { await editor.save(); await editor.reloadConfigAndCommands(); - await editor.flashNotification("Reloaded system"); + await codeWidget.refreshAll(); + await editor.flashNotification("System and widgets reloaded!"); } export async function findInPageCommand() { diff --git a/web/cm_plugins/lua_directive.ts b/web/cm_plugins/lua_directive.ts index 1048cf6f..31279b12 100644 --- a/web/cm_plugins/lua_directive.ts +++ b/web/cm_plugins/lua_directive.ts @@ -1,6 +1,6 @@ import type { EditorState, Range } from "@codemirror/state"; import { syntaxTree } from "@codemirror/language"; -import { Decoration, WidgetType } from "@codemirror/view"; +import { Decoration } from "@codemirror/view"; import { decoratorStateField, invisibleDecoration, @@ -14,79 +14,7 @@ import type { LuaFunctionCallStatement, } from "$common/space_lua/ast.ts"; import { evalExpression } from "$common/space_lua/eval.ts"; -import { luaToString } from "$common/space_lua/runtime.ts"; -import { parse as parseMarkdown } from "$common/markdown_parser/parse_tree.ts"; -import { extendedMarkdownLanguage } from "$common/markdown_parser/parser.ts"; -import { renderMarkdownToHtml } from "../../plugs/markdown/markdown_render.ts"; -import { - isLocalPath, - resolvePath, -} from "@silverbulletmd/silverbullet/lib/resolve"; - -class LuaDirectiveWidget extends WidgetType { - constructor( - readonly code: string, - private client: Client, - ) { - super(); - } - - eq(other: LuaDirectiveWidget) { - return other.code === this.code; - } - - // get estimatedHeight(): number { - // const cachedHeight = this.client.getCachedWidgetHeight( - // `content:${this.url}`, - // ); - // return cachedHeight; - // } - - toDOM() { - const span = document.createElement("span"); - span.className = "sb-lua-directive"; - try { - const parsedLua = parseLua(`_(${this.code})`) as LuaBlock; - const expr = - (parsedLua.statements[0] as LuaFunctionCallStatement).call.args[0]; - - Promise.resolve(evalExpression(expr, client.clientSystem.spaceLuaEnv.env)) - .then((result) => { - const mdTree = parseMarkdown( - extendedMarkdownLanguage, - luaToString(result), - ); - - const html = renderMarkdownToHtml(mdTree, { - // Annotate every element with its position so we can use it to put - // the cursor there when the user clicks on the table. - annotationPositions: true, - translateUrls: (url) => { - if (isLocalPath(url)) { - url = resolvePath( - this.client.currentPage, - decodeURI(url), - ); - } - - return url; - }, - preserveAttributes: true, - }, this.client.ui.viewState.allPages); - span.innerHTML = html; - }).catch((e) => { - console.error("Lua eval error", e); - span.innerText = `Lua error: ${e.message}`; - }); - } catch (e: any) { - console.error("Lua parser error", e); - span.innerText = `Lua error: ${e.message}`; - } - span.innerText = "..."; - - return span; - } -} +import { MarkdownWidget } from "./markdown_widget.ts"; export function luaDirectivePlugin(client: Client) { return decoratorStateField((state: EditorState) => { @@ -110,7 +38,35 @@ export function luaDirectivePlugin(client: Client) { widgets.push( Decoration.widget({ - widget: new LuaDirectiveWidget(text, client), + widget: new MarkdownWidget( + node.from, + client, + `lua:${text}`, + text, + async (bodyText) => { + try { + const parsedLua = parseLua(`_(${bodyText})`) as LuaBlock; + const expr = + (parsedLua.statements[0] as LuaFunctionCallStatement).call + .args[0]; + + const result = await evalExpression( + expr, + client.clientSystem.spaceLuaEnv.env, + ); + return { + markdown: "" + result, + }; + } catch (e: any) { + console.error("Lua eval error", e); + return { + markdown: `**Lua error:** ${e.message}`, + }; + } + }, + "sb-lua-directive", + true, + ), }).range(node.to), ); widgets.push(invisibleDecoration.range(node.from, node.to)); diff --git a/web/cm_plugins/markdown_widget.ts b/web/cm_plugins/markdown_widget.ts index 940eff70..2b6ba7a8 100644 --- a/web/cm_plugins/markdown_widget.ts +++ b/web/cm_plugins/markdown_widget.ts @@ -27,6 +27,7 @@ export class MarkdownWidget extends WidgetType { readonly bodyText: string, readonly codeWidgetCallback: CodeWidgetCallback, readonly className: string, + private tryInline = false, ) { super(); } @@ -91,6 +92,15 @@ export class MarkdownWidget extends WidgetType { return; } + if (this.tryInline) { + if (trimmedMarkdown.includes("\n")) { + // Heuristic that this is going to be a multi-line output and we should render this as a HTML block + div.style.display = "block"; + } else { + div.style.display = "inline"; + } + } + // Parse the markdown again after trimming mdTree = parse( extendedMarkdownLanguage, @@ -152,11 +162,15 @@ export class MarkdownWidget extends WidgetType { if (!html) { return ""; } - return `