diff --git a/package-lock.json b/package-lock.json index 893657f..4b03476 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,12 +13,14 @@ "@codemirror/autocomplete": "^6.19.1", "@codemirror/lang-rust": "^6.0.2", "@codemirror/language": "^6.11.3", + "@codemirror/lint": "^6.9.5", "@codemirror/state": "^6.5.2", "@codemirror/view": "^6.38.6", "@fontsource/poppins": "^5.2.7", "@lezer/highlight": "^1.2.2", "@lezer/rust": "^1.0.2", "@microsoft/clarity": "^1.0.2", + "@replit/codemirror-vim": "^6.3.0", "@tailwindcss/vite": "^4.1.16", "astro": "^5.15.0", "codemirror": "^6.0.2", @@ -563,9 +565,9 @@ } }, "node_modules/@codemirror/lint": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.2.tgz", - "integrity": "sha512-sv3DylBiIyi+xKwRCJAAsBZZZWo82shJ/RTMymLabAdtbkV5cSKwWDeCgtUq3v8flTaXS2y1kKkICuRYtUswyQ==", + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.5.tgz", + "integrity": "sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", @@ -1686,6 +1688,19 @@ "object-assign": "^4.1.1" } }, + "node_modules/@replit/codemirror-vim": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@replit/codemirror-vim/-/codemirror-vim-6.3.0.tgz", + "integrity": "sha512-aTx931ULAMuJx6xLf7KQDOL7CxD+Sa05FktTDrtLaSy53uj01ll3Zf17JdKsriER248oS55GBzg0CfCTjEneAQ==", + "license": "MIT", + "peerDependencies": { + "@codemirror/commands": "6.x.x", + "@codemirror/language": "6.x.x", + "@codemirror/search": "6.x.x", + "@codemirror/state": "6.x.x", + "@codemirror/view": "6.x.x" + } + }, "node_modules/@rollup/pluginutils": { "version": "5.3.0", "license": "MIT", diff --git a/package.json b/package.json index 027904e..957d71a 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,14 @@ "@codemirror/autocomplete": "^6.19.1", "@codemirror/lang-rust": "^6.0.2", "@codemirror/language": "^6.11.3", + "@codemirror/lint": "^6.9.5", "@codemirror/state": "^6.5.2", "@codemirror/view": "^6.38.6", "@fontsource/poppins": "^5.2.7", "@lezer/highlight": "^1.2.2", "@lezer/rust": "^1.0.2", "@microsoft/clarity": "^1.0.2", + "@replit/codemirror-vim": "^6.3.0", "@tailwindcss/vite": "^4.1.16", "astro": "^5.15.0", "codemirror": "^6.0.2", diff --git a/src/components/editor/CodeEditor.astro b/src/components/editor/CodeEditor.astro index 9dd1f99..7b43778 100644 --- a/src/components/editor/CodeEditor.astro +++ b/src/components/editor/CodeEditor.astro @@ -7,94 +7,320 @@ interface Props { const { slug, initialCode = 'fn main() {\n println!("Hola, mundo!");\n}\n' } = Astro.props --- -
+
+
+
+ +
- diff --git a/src/components/editor/output/Terminal.astro b/src/components/editor/output/Terminal.astro index 00cb371..28d40e1 100644 --- a/src/components/editor/output/Terminal.astro +++ b/src/components/editor/output/Terminal.astro @@ -2,6 +2,7 @@ import IconLoader2 from "~icons/tabler/loader-2" import IconPlayerPlay from "~icons/tabler/player-play" import IconRestore from "~icons/tabler/restore" +import IconSparkles from "~icons/tabler/sparkles" import IconTerminal from "~icons/tabler/terminal" interface Props { @@ -47,6 +48,20 @@ const isTestMode = !!testCode Reiniciar + + +
+ +
+

{t("profile.editor_section")}

+ +
+
+ {t("profile.vim_mode_label")} + {t("profile.vim_mode_desc")} +
+ +
+
@@ -330,6 +353,24 @@ const trackMap = Object.fromEntries(tracks.map((t) => [t.id, t])) } }) + // Vim mode toggle + const vimToggle = document.getElementById("vim-toggle") as HTMLButtonElement + const getPrefs = () => JSON.parse(localStorage.getItem("preferences") ?? "{}") + const savePrefs = (prefs: Record) => localStorage.setItem("preferences", JSON.stringify(prefs)) + + const vimEnabled = !!getPrefs().vimEditor + vimToggle.setAttribute("aria-checked", String(vimEnabled)) + vimToggle.querySelector("span")!.dataset.ariaChecked = String(vimEnabled) + + vimToggle.addEventListener("click", () => { + const prefs = getPrefs() + const next = !prefs.vimEditor + prefs.vimEditor = next + savePrefs(prefs) + vimToggle.setAttribute("aria-checked", String(next)) + window.dispatchEvent(new CustomEvent("preferences:changed", { detail: { vimEditor: next } })) + }) + document.querySelectorAll("[data-copy-link]").forEach((btn) => { btn.addEventListener("click", async () => { const path = btn.dataset.copyLink!