diff --git a/content/package.json b/content/package.json index fc6cfc8a2..faf84ea0e 100644 --- a/content/package.json +++ b/content/package.json @@ -109,6 +109,7 @@ } }, "dependencies": { + "monaco-vim": "^0.4.2", "neverthrow": "^8.2.0" } } diff --git a/content/pnpm-lock.yaml b/content/pnpm-lock.yaml index 32563c4da..8b3047473 100644 --- a/content/pnpm-lock.yaml +++ b/content/pnpm-lock.yaml @@ -13,6 +13,9 @@ importers: .: dependencies: + monaco-vim: + specifier: ^0.4.2 + version: 0.4.2(monaco-editor@0.54.0) neverthrow: specifier: ^8.2.0 version: 8.2.0 @@ -2877,6 +2880,9 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dompurify@3.1.7: + resolution: {integrity: sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==} + dompurify@3.2.6: resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==} @@ -3532,6 +3538,11 @@ packages: engines: {node: '>= 18'} hasBin: true + marked@14.0.0: + resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==} + engines: {node: '>= 18'} + hasBin: true + marked@15.0.12: resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} engines: {node: '>= 18'} @@ -3781,6 +3792,14 @@ packages: module-details-from-path@1.0.4: resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + monaco-editor@0.54.0: + resolution: {integrity: sha512-hx45SEUoLatgWxHKCmlLJH81xBo0uXP4sRkESUpmDQevfi+e7K1VuiSprK6UpQ8u4zOcKNiH0pMvHvlMWA/4cw==} + + monaco-vim@0.4.2: + resolution: {integrity: sha512-rdbQC3O2rmpwX2Orzig/6gZjZfH7q7TIeB+uEl49sa+QyNm3jCKJOw5mwxBdFzTqbrPD+URfg6A2lEkuL5kymw==} + peerDependencies: + monaco-editor: '*' + motion-dom@11.18.1: resolution: {integrity: sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==} @@ -7898,6 +7917,8 @@ snapshots: dlv@1.1.3: {} + dompurify@3.1.7: {} + dompurify@3.2.6: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -8673,6 +8694,8 @@ snapshots: marked@12.0.2: {} + marked@14.0.0: {} + marked@15.0.12: {} marked@16.1.2: {} @@ -9218,6 +9241,15 @@ snapshots: module-details-from-path@1.0.4: {} + monaco-editor@0.54.0: + dependencies: + dompurify: 3.1.7 + marked: 14.0.0 + + monaco-vim@0.4.2(monaco-editor@0.54.0): + dependencies: + monaco-editor: 0.54.0 + motion-dom@11.18.1: dependencies: motion-utils: 11.18.1 diff --git a/content/src/components/editor/index.tsx b/content/src/components/editor/index.tsx index 00652aee3..0639f3721 100644 --- a/content/src/components/editor/index.tsx +++ b/content/src/components/editor/index.tsx @@ -49,7 +49,14 @@ function CodeEditorPanels() { - +
+
+ +
+
+ +
+
diff --git a/content/src/components/editor/services/monaco.ts b/content/src/components/editor/services/monaco.ts index 6767a2dd2..98a523648 100644 --- a/content/src/components/editor/services/monaco.ts +++ b/content/src/components/editor/services/monaco.ts @@ -3,6 +3,7 @@ import * as Effect from "effect/Effect" import * as Stream from "effect/Stream" import type ts from "typescript" import { ChromeDevTools, Dracula } from "./monaco/themes" +import { initVimMode } from "monaco-vim" type MonacoApi = typeof import("@effect/monaco-editor") @@ -56,6 +57,32 @@ export class Monaco extends Effect.Service()("app/Monaco", { (editor) => Effect.sync(() => editor.dispose()) ) + /** + * Initialize vim mode + */ + const vimAdapter = yield* Effect.acquireRelease( + Effect.sync(() => { + const adapter = initVimMode(editor) + console.log("Vim adapter initialized:", adapter) + + setTimeout(() => { + const statusNode = document.getElementById("vim-status") + console.log("Status node found:", statusNode) + if (statusNode) { + adapter?.dispose?.() + const newAdapter = initVimMode(editor, statusNode as HTMLElement) + console.log("Vim adapter re-initialized with status:", newAdapter) + } + }, 200) + + return adapter + }), + (adapter) => + Effect.sync(() => { + adapter?.dispose?.() + }) + ) + /** * Loads the specified model into the editor. */ @@ -96,7 +123,8 @@ export class Monaco extends Effect.Service()("app/Monaco", { return { editor, loadModel, - content + content, + vimAdapter } as const }) } diff --git a/content/src/types/monaco-vim.d.ts b/content/src/types/monaco-vim.d.ts new file mode 100644 index 000000000..8e8e10c54 --- /dev/null +++ b/content/src/types/monaco-vim.d.ts @@ -0,0 +1,3 @@ +declare module 'monaco-vim' { + export function initVimMode(editor: any, statusNode?: HTMLElement): any; +} \ No newline at end of file