Skip to content

Commit f86a6fe

Browse files
(feat) add vim keybindings to REPL component (#501)
* Add vim mode * fix conflicts * add changesets
1 parent 9b897f0 commit f86a6fe

File tree

7 files changed

+343
-850
lines changed

7 files changed

+343
-850
lines changed

.changeset/nine-bottles-scream.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/repl': minor
3+
---
4+
5+
add vim keybindings

packages/repl/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"@lezer/highlight": "^1.1.6",
7676
"@neocodemirror/svelte": "0.0.15",
7777
"@replit/codemirror-lang-svelte": "^6.0.0",
78+
"@replit/codemirror-vim": "^6.0.14",
7879
"@rich_harris/svelte-split-pane": "^1.1.1",
7980
"@rollup/browser": "^3.25.3",
8081
"@sveltejs/site-kit": "5.2.2",

packages/repl/src/lib/CodeMirror.svelte

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
/** @type {boolean} */
2525
export let autocomplete = true;
2626
27+
/** @type {boolean} */
28+
export let vim = false;
29+
2730
/** @type {ReturnType<typeof createEventDispatcher<{ change: { value: string } }>>} */
2831
const dispatch = createEventDispatcher();
2932
@@ -179,6 +182,30 @@
179182
/** @type {import('@codemirror/state').Extension[]} */
180183
let extensions = [];
181184
185+
$: getExtensions(vim).then((resolvedExtensions) => {
186+
extensions = resolvedExtensions;
187+
});
188+
189+
/**
190+
* update the extension if and when vim changes
191+
* @param {boolean} vimEnabled if vim it's included in the set of extensions
192+
*/
193+
async function getExtensions(vimEnabled) {
194+
let extensions = [watcher];
195+
if (vimEnabled) {
196+
const { vim } = await import('@replit/codemirror-vim').then((vimModule) => ({
197+
vim: vimModule.vim
198+
}));
199+
200+
extensions.unshift(
201+
vim({
202+
status: true
203+
})
204+
);
205+
}
206+
return extensions;
207+
}
208+
182209
let cursor_pos = 0;
183210
184211
$: {
@@ -232,7 +259,7 @@
232259
lint: diagnostics,
233260
lintOptions: { delay: 200 },
234261
autocomplete,
235-
extensions: [watcher],
262+
extensions,
236263
instanceStore: cmInstance
237264
}}
238265
on:codemirror:textChange={({ detail: value }) => {

packages/repl/src/lib/Input/ModuleEditor.svelte

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
1010
/** @type {boolean} */
1111
export let autocomplete;
12+
/** @type {boolean} */
13+
export let vim;
1214
1315
export function focus() {
1416
$module_editor?.focus();
@@ -61,6 +63,7 @@
6163
bind:this={$module_editor}
6264
{errorLoc}
6365
{autocomplete}
66+
{vim}
6467
{diagnostics}
6568
on:change={handle_change}
6669
/>

packages/repl/src/lib/Repl.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
export let showModified = false;
2828
export let showAst = false;
2929
export let autocomplete = true;
30+
export let vim = false;
3031
3132
export function toJSON() {
3233
return {
@@ -344,7 +345,7 @@
344345
>
345346
<section slot="a">
346347
<ComponentSelector show_modified={showModified} on:add on:remove />
347-
<ModuleEditor errorLoc={sourceErrorLoc} {autocomplete} />
348+
<ModuleEditor errorLoc={sourceErrorLoc} {autocomplete} {vim} />
348349
</section>
349350
350351
<section slot="b" style="height: 100%;">

packages/repl/src/routes/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
</script>
3737

3838
<main>
39-
<Repl bind:this={repl} showAst autocomplete={true} previewTheme="dark" />
39+
<Repl vim bind:this={repl} showAst autocomplete={true} previewTheme="dark" />
4040
</main>
4141

4242
<style>

0 commit comments

Comments
 (0)