Lua: inline directives improvements
parent
6c71862641
commit
f74bab0aca
|
@ -1,4 +1,8 @@
|
||||||
import { clientStore, editor } from "@silverbulletmd/silverbullet/syscalls";
|
import {
|
||||||
|
clientStore,
|
||||||
|
codeWidget,
|
||||||
|
editor,
|
||||||
|
} from "@silverbulletmd/silverbullet/syscalls";
|
||||||
|
|
||||||
// Run on "editor:init"
|
// Run on "editor:init"
|
||||||
export async function setEditorMode() {
|
export async function setEditorMode() {
|
||||||
|
@ -79,7 +83,8 @@ export async function customFlashMessage(_def: any, message: string) {
|
||||||
export async function reloadSystem() {
|
export async function reloadSystem() {
|
||||||
await editor.save();
|
await editor.save();
|
||||||
await editor.reloadConfigAndCommands();
|
await editor.reloadConfigAndCommands();
|
||||||
await editor.flashNotification("Reloaded system");
|
await codeWidget.refreshAll();
|
||||||
|
await editor.flashNotification("System and widgets reloaded!");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function findInPageCommand() {
|
export async function findInPageCommand() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { EditorState, Range } from "@codemirror/state";
|
import type { EditorState, Range } from "@codemirror/state";
|
||||||
import { syntaxTree } from "@codemirror/language";
|
import { syntaxTree } from "@codemirror/language";
|
||||||
import { Decoration, WidgetType } from "@codemirror/view";
|
import { Decoration } from "@codemirror/view";
|
||||||
import {
|
import {
|
||||||
decoratorStateField,
|
decoratorStateField,
|
||||||
invisibleDecoration,
|
invisibleDecoration,
|
||||||
|
@ -14,79 +14,7 @@ import type {
|
||||||
LuaFunctionCallStatement,
|
LuaFunctionCallStatement,
|
||||||
} from "$common/space_lua/ast.ts";
|
} from "$common/space_lua/ast.ts";
|
||||||
import { evalExpression } from "$common/space_lua/eval.ts";
|
import { evalExpression } from "$common/space_lua/eval.ts";
|
||||||
import { luaToString } from "$common/space_lua/runtime.ts";
|
import { MarkdownWidget } from "./markdown_widget.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function luaDirectivePlugin(client: Client) {
|
export function luaDirectivePlugin(client: Client) {
|
||||||
return decoratorStateField((state: EditorState) => {
|
return decoratorStateField((state: EditorState) => {
|
||||||
|
@ -110,7 +38,35 @@ export function luaDirectivePlugin(client: Client) {
|
||||||
|
|
||||||
widgets.push(
|
widgets.push(
|
||||||
Decoration.widget({
|
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),
|
}).range(node.to),
|
||||||
);
|
);
|
||||||
widgets.push(invisibleDecoration.range(node.from, node.to));
|
widgets.push(invisibleDecoration.range(node.from, node.to));
|
||||||
|
|
|
@ -27,6 +27,7 @@ export class MarkdownWidget extends WidgetType {
|
||||||
readonly bodyText: string,
|
readonly bodyText: string,
|
||||||
readonly codeWidgetCallback: CodeWidgetCallback,
|
readonly codeWidgetCallback: CodeWidgetCallback,
|
||||||
readonly className: string,
|
readonly className: string,
|
||||||
|
private tryInline = false,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
@ -91,6 +92,15 @@ export class MarkdownWidget extends WidgetType {
|
||||||
return;
|
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
|
// Parse the markdown again after trimming
|
||||||
mdTree = parse(
|
mdTree = parse(
|
||||||
extendedMarkdownLanguage,
|
extendedMarkdownLanguage,
|
||||||
|
@ -152,11 +162,15 @@ export class MarkdownWidget extends WidgetType {
|
||||||
if (!html) {
|
if (!html) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return `<div class="button-bar">${
|
if (buttons.length === 0) {
|
||||||
buttons.filter((button) => !button.widgetTarget).map((button, idx) =>
|
return html;
|
||||||
`<button data-button="${idx}" title="${button.description}">${button.svg}</button> `
|
} else {
|
||||||
).join("")
|
return `<div class="button-bar">${
|
||||||
}</div><div class="content">${html}</div>`;
|
buttons.filter((button) => !button.widgetTarget).map((button, idx) =>
|
||||||
|
`<button data-button="${idx}" title="${button.description}">${button.svg}</button> `
|
||||||
|
).join("")
|
||||||
|
}</div><div class="content">${html}</div>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private attachListeners(div: HTMLElement, buttons?: CodeWidgetButton[]) {
|
private attachListeners(div: HTMLElement, buttons?: CodeWidgetButton[]) {
|
||||||
|
|
|
@ -331,13 +331,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.sb-lua-directive {
|
.sb-lua-directive {
|
||||||
background-color: rgba(151, 151, 151, 0.1);
|
background-color: rgb(233, 232, 232, 35%);
|
||||||
border: 1px solid #dfdcdc;
|
border: 1px #d3d3d373 solid;
|
||||||
border-radius: 5px;
|
/* box-shadow: #d1d1d1 0 0 4px; */
|
||||||
|
border-radius: 8px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
a.sb-wiki-link-page-missing,
|
a.sb-wiki-link-page-missing,
|
||||||
.sb-wiki-link-page-missing>.sb-wiki-link-page {
|
.sb-wiki-link-page-missing>.sb-wiki-link-page {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
Loading…
Reference in New Issue