-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
167 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import type { SyncStorage } from "@/shared"; | ||
|
||
export interface StorageState<T> { | ||
value: T; | ||
} | ||
|
||
export function reactive<T>(storage: SyncStorage<T>): StorageState<T> { | ||
let value = $state(storage.load()); | ||
return { | ||
get value() { | ||
return value; | ||
}, | ||
set value(newValue) { | ||
value = newValue; | ||
storage.save(newValue); | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,16 @@ | ||
import type { editor } from 'monaco-editor'; | ||
|
||
import { createSyncStorage } from '@/adapters/storage'; | ||
import { reactive } from '@/adapters/storage.svelte' | ||
|
||
export interface SurfaceApi { | ||
editor: editor.IStandaloneCodeEditor | undefined; | ||
width: number; | ||
panelHeight: number; | ||
isPanelCollapsed: boolean; | ||
showPanel(height: number): boolean; | ||
hidePanel(): boolean; | ||
togglePanel(height: number): boolean; | ||
} | ||
|
||
export const vimState = reactive(createSyncStorage(localStorage, 'editor-vim', false)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<script lang="ts"> | ||
import { initVimMode } from "monaco-vim"; | ||
import { vimState, type SurfaceApi } from "./model"; | ||
interface Props { | ||
api: SurfaceApi; | ||
} | ||
const { api }: Props = $props(); | ||
let statusElement: HTMLDivElement; | ||
$effect(() => { | ||
if (!api.editor || !vimState.value) { | ||
return; | ||
} | ||
const mode = initVimMode(api.editor, statusElement); | ||
return () => { | ||
mode.dispose() | ||
} | ||
}); | ||
</script> | ||
|
||
<div bind:this={statusElement}></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Copied from `typehero` project licensed under AGPL-3.0 | ||
// https://github.com/typehero/typehero/blob/main/packages/monaco/monaco-vim.d.ts | ||
|
||
declare module 'monaco-vim' { | ||
import type * as monaco from 'monaco-editor'; | ||
|
||
export function initVimMode( | ||
editor: monaco.editor.IStandaloneCodeEditor, | ||
statusbarNode?: Element | null, | ||
): CMAdapter; | ||
|
||
type VimModes = 'insert' | 'normal' | 'visual'; | ||
|
||
class CMAdapter { | ||
/** removes the attached vim bindings */ | ||
dispose(): void; | ||
|
||
attached: boolean; | ||
|
||
editor: monaco.editor.IStandaloneCodeEditor; | ||
|
||
statusBar: { | ||
clear(): void; | ||
node: HTMLElement; | ||
}; | ||
|
||
/** @see https://codemirror.net/5/doc/manual.html#vimapi */ | ||
static Vim: { | ||
map(lhs: string, rhs: string, ctx: VimModes): void; | ||
unmap(lhs: string, ctx: VimModes | false): boolean; | ||
noremap(lhs: string, rhs: string, ctx: VimModes): void; | ||
|
||
mapCommand( | ||
keys: string, | ||
type: 'action', | ||
name: string, | ||
args?: Record<PropertyKey, unknown>, | ||
extra?: Record<PropertyKey, unknown>, | ||
): void; | ||
|
||
defineAction( | ||
name: string, | ||
fn: ( | ||
ctx: CMAdapter, | ||
// TODO: Document other args | ||
...args: [unknown, unknown] | ||
) => void, | ||
): void; | ||
|
||
defineEx( | ||
name: string, | ||
prefix: string | undefined, | ||
fn: ( | ||
ctx: CMAdapter, | ||
data: { | ||
commandName: string; | ||
input: string; | ||
} & ( | ||
| { | ||
argString: string; | ||
args: [string, ...string[]]; | ||
} | ||
| { argString?: never; args?: never } | ||
) & | ||
({ line: undefined } | { line: number; lineEnd: number }), | ||
) => void, | ||
): void; | ||
|
||
/** clears user created mappings */ | ||
mapclear(ctx?: VimModes): void; | ||
|
||
/** call this before `VimMode.Vim.handleKey` */ | ||
maybeInitVimState_(cma: CMAdapter): void; | ||
|
||
/** | ||
* calls an ex command, equivalent to `:` in vim | ||
* | ||
* *If it fails with `vim is null` call `VimMode.Vim.maybeInitVimState_` first* | ||
*/ | ||
handleEx(cma: CMAdapter, ex: string): void; | ||
}; | ||
} | ||
|
||
export { CMAdapter as VimMode, type CMAdapter }; | ||
} |