feat: added in monaco setups and hooks

This commit is contained in:
2026-04-27 20:15:55 +02:00
parent 22f625ced0
commit dba10eab24
5 changed files with 66 additions and 6 deletions

View File

@@ -31,7 +31,7 @@
data-monaco-editor-id={@script_editor.id} data-monaco-editor-id={@script_editor.id}
data-monaco-input-id={"script-editor-content-#{@script_editor.id}"} data-monaco-input-id={"script-editor-content-#{@script_editor.id}"}
data-monaco-language="lua" data-monaco-language="lua"
data-monaco-word-wrap="off" data-monaco-word-wrap="on"
> >
<div id={"script-editor-monaco-#{@script_editor.id}"} class="monaco-editor-instance" phx-update="ignore"></div> <div id={"script-editor-monaco-#{@script_editor.id}"} class="monaco-editor-instance" phx-update="ignore"></div>
<textarea id={"script-editor-content-#{@script_editor.id}"} class="monaco-editor-input code-editor-textarea" name="script_editor[content]" spellcheck="false"><%= @script_editor.content %></textarea> <textarea id={"script-editor-content-#{@script_editor.id}"} class="monaco-editor-input code-editor-textarea" name="script_editor[content]" spellcheck="false"><%= @script_editor.content %></textarea>

View File

@@ -29,7 +29,7 @@
data-monaco-editor-id={@template_editor.id} data-monaco-editor-id={@template_editor.id}
data-monaco-input-id={"template-editor-content-#{@template_editor.id}"} data-monaco-input-id={"template-editor-content-#{@template_editor.id}"}
data-monaco-language="liquid" data-monaco-language="liquid"
data-monaco-word-wrap="off" data-monaco-word-wrap="on"
> >
<div id={"template-editor-monaco-#{@template_editor.id}"} class="monaco-editor-instance" phx-update="ignore"></div> <div id={"template-editor-monaco-#{@template_editor.id}"} class="monaco-editor-instance" phx-update="ignore"></div>
<textarea id={"template-editor-content-#{@template_editor.id}"} class="monaco-editor-input code-editor-textarea" name="template_editor[content]" spellcheck="false"><%= @template_editor.content %></textarea> <textarea id={"template-editor-content-#{@template_editor.id}"} class="monaco-editor-input code-editor-textarea" name="template_editor[content]" spellcheck="false"><%= @template_editor.content %></textarea>

View File

@@ -394,7 +394,7 @@
phx-hook="MonacoEditor" phx-hook="MonacoEditor"
data-monaco-editor-id={@post_editor.id} data-monaco-editor-id={@post_editor.id}
data-monaco-input-id={"post-editor-content-#{@post_editor.id}"} data-monaco-input-id={"post-editor-content-#{@post_editor.id}"}
data-monaco-language="markdown" data-monaco-language="markdown-with-macros"
data-monaco-word-wrap="on" data-monaco-word-wrap="on"
data-monaco-insert-event="post-editor-insert-content" data-monaco-insert-event="post-editor-insert-content"
> >

View File

@@ -157,6 +157,7 @@ document.addEventListener("DOMContentLoaded", () => {
let monacoLoaderPromise; let monacoLoaderPromise;
let liquidLanguageRegistered = false; let liquidLanguageRegistered = false;
let markdownWithMacrosRegistered = false;
let monacoThemeSignature = null; let monacoThemeSignature = null;
const cssVar = (name, fallback) => { const cssVar = (name, fallback) => {
@@ -337,6 +338,49 @@ document.addEventListener("DOMContentLoaded", () => {
liquidLanguageRegistered = true; liquidLanguageRegistered = true;
}; };
const registerMarkdownWithMacrosLanguage = (monaco) => {
if (markdownWithMacrosRegistered) {
return;
}
monaco.languages.register({ id: "markdown-with-macros" });
monaco.languages.setMonarchTokensProvider("markdown-with-macros", {
defaultToken: "",
tokenPostfix: ".md",
tokenizer: {
root: [
[/\[\[[a-zA-Z][\w-]*/, { token: "keyword.macro", next: "@macroParams" }],
[/^#{1,6}\s.*$/, "keyword.header"],
[/^\s*>+/, "string.quote"],
[/^\s*[-+*]\s/, "keyword"],
[/^\s*\d+\.\s/, "keyword"],
[/^\s*```\w*/, { token: "string.code", next: "@codeblock" }],
[/\*\*[^*]+\*\*/, "strong"],
[/\*[^*]+\*/, "emphasis"],
[/__[^_]+__/, "strong"],
[/_[^_]+_/, "emphasis"],
[/`[^`]+`/, "variable"],
[/!?\[[^\]]*\]\([^)]*\)/, "string.link"],
[/!?\[[^\]]*\]\[[^\]]*\]/, "string.link"]
],
macroParams: [
[/\]\]/, { token: "keyword.macro", next: "@root" }],
[/[a-zA-Z][\w-]*(?=\s*=)/, "attribute.name"],
[/=/, "delimiter"],
[/"[^"]*"/, "string"],
[/\s+/, "white"],
[/[^\]"=\s]+/, "attribute.value"]
],
codeblock: [
[/^\s*```\s*$/, { token: "string.code", next: "@root" }],
[/.*$/, "variable.source"]
]
}
});
markdownWithMacrosRegistered = true;
};
const ensureMonacoTheme = (monaco) => { const ensureMonacoTheme = (monaco) => {
const background = cssVar("--vscode-editor-background", cssVar("--vscode-input-background", "#1e1e1e")); const background = cssVar("--vscode-editor-background", cssVar("--vscode-input-background", "#1e1e1e"));
const foreground = cssVar("--vscode-editor-foreground", "#d4d4d4"); const foreground = cssVar("--vscode-editor-foreground", "#d4d4d4");
@@ -356,7 +400,11 @@ document.addEventListener("DOMContentLoaded", () => {
monaco.editor.defineTheme("bds-theme", { monaco.editor.defineTheme("bds-theme", {
base: colorIsDark(background) ? "vs-dark" : "vs", base: colorIsDark(background) ? "vs-dark" : "vs",
inherit: true, inherit: true,
rules: [], rules: [
{ token: "keyword.macro", foreground: "C586C0", fontStyle: "bold" },
{ token: "attribute.name", foreground: "9CDCFE" },
{ token: "attribute.value", foreground: "CE9178" }
],
colors: { colors: {
"editor.background": background, "editor.background": background,
"editor.foreground": foreground, "editor.foreground": foreground,
@@ -383,6 +431,7 @@ document.addEventListener("DOMContentLoaded", () => {
if (window.monaco?.editor) { if (window.monaco?.editor) {
ensureMonacoTheme(window.monaco); ensureMonacoTheme(window.monaco);
registerLiquidLanguage(window.monaco); registerLiquidLanguage(window.monaco);
registerMarkdownWithMacrosLanguage(window.monaco);
return Promise.resolve(window.monaco); return Promise.resolve(window.monaco);
} }
@@ -398,6 +447,7 @@ document.addEventListener("DOMContentLoaded", () => {
window.require(["vs/editor/editor.main"], () => { window.require(["vs/editor/editor.main"], () => {
ensureMonacoTheme(window.monaco); ensureMonacoTheme(window.monaco);
registerLiquidLanguage(window.monaco); registerLiquidLanguage(window.monaco);
registerMarkdownWithMacrosLanguage(window.monaco);
resolve(window.monaco); resolve(window.monaco);
}, reject); }, reject);
}) })
@@ -709,9 +759,17 @@ document.addEventListener("DOMContentLoaded", () => {
minimap: { enabled: false }, minimap: { enabled: false },
scrollBeyondLastLine: false, scrollBeyondLastLine: false,
wordWrap: this.wordWrap, wordWrap: this.wordWrap,
lineNumbers: "on",
lineNumbersMinChars: 3, lineNumbersMinChars: 3,
fontSize: 14,
fontFamily: "'Cascadia Code', 'Consolas', 'Courier New', monospace",
padding: { top: 12, bottom: 12 },
roundedSelection: false, roundedSelection: false,
renderLineHighlight: "line", renderLineHighlight: "line",
formatOnPaste: true,
cursorStyle: "line",
cursorBlinking: "smooth",
quickSuggestions: this.language === "markdown-with-macros" ? false : true,
tabSize: 2, tabSize: 2,
insertSpaces: true insertSpaces: true
}); });

View File

@@ -1315,7 +1315,7 @@ defmodule BDS.Desktop.ShellLiveTest do
html = render_click(view, "set_post_editor_mode", %{"id" => post.id, "mode" => "markdown"}) html = render_click(view, "set_post_editor_mode", %{"id" => post.id, "mode" => "markdown"})
assert html =~ ~s(data-testid="post-editor-content") assert html =~ ~s(data-testid="post-editor-content")
assert html =~ ~s(data-monaco-language="markdown") assert html =~ ~s(data-monaco-language="markdown-with-macros")
assert html =~ ~s(phx-hook="MonacoEditor") assert html =~ ~s(phx-hook="MonacoEditor")
refute html =~ "post-editor-markdown-highlight" refute html =~ "post-editor-markdown-highlight"
@@ -1439,7 +1439,7 @@ defmodule BDS.Desktop.ShellLiveTest do
assert html =~ ~s(data-testid="post-editor-content") assert html =~ ~s(data-testid="post-editor-content")
assert Regex.match?(~r/name="post_editor\[content\]"[^>]*># Heading\s+```elixir\s+IO\.puts\(:ok\)\s+```/s, html) assert Regex.match?(~r/name="post_editor\[content\]"[^>]*># Heading\s+```elixir\s+IO\.puts\(:ok\)\s+```/s, html)
assert html =~ ~s(data-monaco-language="markdown") assert html =~ ~s(data-monaco-language="markdown-with-macros")
assert html =~ ~s(phx-hook="MonacoEditor") assert html =~ ~s(phx-hook="MonacoEditor")
refute html =~ "post-editor-markdown-highlight" refute html =~ "post-editor-markdown-highlight"
refute html =~ ~s(phx-value-mode="visual") refute html =~ ~s(phx-value-mode="visual")
@@ -1704,6 +1704,7 @@ defmodule BDS.Desktop.ShellLiveTest do
assert script_html =~ ~s(class="scripts-view-shell") assert script_html =~ ~s(class="scripts-view-shell")
assert script_html =~ "scripts-monaco" assert script_html =~ "scripts-monaco"
assert script_html =~ ~s(data-monaco-language="lua") assert script_html =~ ~s(data-monaco-language="lua")
assert script_html =~ ~s(data-monaco-word-wrap="on")
assert script_html =~ ~s(phx-hook="MonacoEditor") assert script_html =~ ~s(phx-hook="MonacoEditor")
refute script_html =~ "Desktop workbench content routed through the Elixir shell." refute script_html =~ "Desktop workbench content routed through the Elixir shell."
@@ -1718,6 +1719,7 @@ defmodule BDS.Desktop.ShellLiveTest do
assert template_html =~ ~s(class="templates-view-shell") assert template_html =~ ~s(class="templates-view-shell")
assert template_html =~ "templates-monaco" assert template_html =~ "templates-monaco"
assert template_html =~ ~s(data-monaco-language="liquid") assert template_html =~ ~s(data-monaco-language="liquid")
assert template_html =~ ~s(data-monaco-word-wrap="on")
assert template_html =~ ~s(phx-hook="MonacoEditor") assert template_html =~ ~s(phx-hook="MonacoEditor")
refute template_html =~ "Desktop workbench content routed through the Elixir shell." refute template_html =~ "Desktop workbench content routed through the Elixir shell."