From f74bab0acaadd309b5832bf6207f198fc0fb7b96 Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Mon, 7 Oct 2024 19:17:12 +0200 Subject: [PATCH] Lua: inline directives improvements --- plugs/editor/editor.ts | 9 ++- web/cm_plugins/lua_directive.ts | 106 +++++++++--------------------- web/cm_plugins/markdown_widget.ts | 24 +++++-- web/styles/editor.scss | 8 +-- 4 files changed, 61 insertions(+), 86 deletions(-) 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 `
${ - buttons.filter((button) => !button.widgetTarget).map((button, idx) => - ` ` - ).join("") - }
${html}
`; + if (buttons.length === 0) { + return html; + } else { + return `
${ + buttons.filter((button) => !button.widgetTarget).map((button, idx) => + ` ` + ).join("") + }
${html}
`; + } } private attachListeners(div: HTMLElement, buttons?: CodeWidgetButton[]) { diff --git a/web/styles/editor.scss b/web/styles/editor.scss index 123baba4..0a3a0d76 100644 --- a/web/styles/editor.scss +++ b/web/styles/editor.scss @@ -331,13 +331,13 @@ } .sb-lua-directive { - background-color: rgba(151, 151, 151, 0.1); - border: 1px solid #dfdcdc; - border-radius: 5px; + background-color: rgb(233, 232, 232, 35%); + border: 1px #d3d3d373 solid; + /* box-shadow: #d1d1d1 0 0 4px; */ + border-radius: 8px; padding: 2px; } - a.sb-wiki-link-page-missing, .sb-wiki-link-page-missing>.sb-wiki-link-page { border-radius: 5px;