Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert REPL to Svelte 5 #49

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 34 additions & 20 deletions packages/repl/src/lib/CodeMirror.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
</script>

<script lang="ts">
import { run } from 'svelte/legacy';

import { historyField } from '@codemirror/commands';
import { EditorState, Range, StateEffect, StateEffectType, StateField } from '@codemirror/state';
import { Decoration, EditorView } from '@codemirror/view';
Expand All @@ -20,17 +22,21 @@
import { CompletionContext } from '@codemirror/autocomplete';
import type { Lang } from './types';

export let diagnostics: LintSource | undefined = undefined;
export let readonly = false;
export let tab = true;
export let vim = false;
interface Props {
diagnostics?: LintSource | undefined;
readonly?: boolean;
tab?: boolean;
vim?: boolean;
}

let { diagnostics = undefined, readonly = false, tab = true, vim = false }: Props = $props();

const dispatch: ReturnType<typeof createEventDispatcher<{ change: { value: string } }>> =
createEventDispatcher();

let code = '';
let code = $state('');

let lang: Lang = 'svelte';
let lang: Lang = $state('svelte');

export async function set(options: { code: string; lang: Lang }) {
update(options);
Expand Down Expand Up @@ -155,11 +161,11 @@
let w: number;
let h: number;

let marked = false;
let marked = $state(false);

let updating_externally = false;

let extensions: Extension[] = [];
let extensions: Extension[] = $state([]);

/**
* update the extension if and when vim changes
Expand All @@ -181,22 +187,30 @@
return extensions;
}

$: getExtensions(vim).then((ext) => {
extensions = ext;
run(() => {
getExtensions(vim).then((ext) => {
extensions = ext;
});
});

let cursor_pos = 0;
let cursor_pos = $state(0);

$: if ($cmInstance.view) {
fulfil_module_editor_ready();
}
run(() => {
if ($cmInstance.view) {
fulfil_module_editor_ready();
}
});

$: if ($cmInstance.view && w && h) resize();
run(() => {
if ($cmInstance.view && w && h) resize();
});

$: if (marked) {
unmarkText();
marked = false;
}
run(() => {
if (marked) {
unmarkText();
marked = false;
}
});

const watcher = EditorView.updateListener.of((viewUpdate) => {
if (viewUpdate.selectionSet) {
Expand Down Expand Up @@ -239,7 +253,7 @@
extensions: [svelte_rune_completions, js_rune_completions, watcher],
instanceStore: cmInstance
}}
on:codemirror:textChange={({ detail: value }) => {
oncodemirror:textChange={({ detail: value }) => {
code = value;
dispatch('change', { value: code });
}}
Expand Down
60 changes: 37 additions & 23 deletions packages/repl/src/lib/Input/ComponentSelector.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
import Migrate from './Migrate.svelte';
import type { File } from '$lib/types';

export let show_modified: boolean;
export let runes: boolean;
interface Props {
show_modified: boolean;
runes: boolean;
}

let { show_modified, runes }: Props = $props();

const dispatch: ReturnType<
typeof createEventDispatcher<{
remove: { files: import('$lib/types').File[]; diff: import('$lib/types').File };
add: { files: import('$lib/types').File[]; diff: import('$lib/types').File };
remove: { files: File[]; diff: File };
add: { files: File[]; diff: File };
}>
> = createEventDispatcher();

Expand All @@ -26,8 +30,8 @@
EDITOR_STATE_MAP
} = get_repl_context();

let editing_name: string | null = null;
let input_value = '';
let editing_name: string | null = $state(null);
let input_value = $state('');

function select_file(filename: string) {
if ($selected_name !== filename) {
Expand Down Expand Up @@ -164,7 +168,7 @@

// drag and drop
let from: string | null = null;
let over: string | null = null;
let over: string | null = $state(null);

function dragStart(event: DragEvent & { currentTarget: HTMLDivElement }) {
from = event.currentTarget.id;
Expand Down Expand Up @@ -196,7 +200,7 @@

<div class="component-selector">
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="file-tabs" on:dblclick={add_new}>
<div class="file-tabs" ondblclick={add_new}>
{#each $files as file, index (file.name)}
{@const filename = get_full_filename(file)}
<div
Expand All @@ -207,14 +211,24 @@
class:active={filename === $selected_name}
class:draggable={filename !== editing_name && index !== 0}
class:drag-over={over === file.name}
on:click={() => select_file(filename)}
on:keyup={(e) => e.key === ' ' && select_file(filename)}
on:dblclick|stopPropagation={() => {}}
onclick={() => select_file(filename)}
onkeyup={(e) => e.key === ' ' && select_file(filename)}
ondblclick={(event) => {
event.stopPropagation();
}}
draggable={filename !== editing_name}
on:dragstart={dragStart}
on:dragover|preventDefault={dragOver}
on:dragleave={dragLeave}
on:drop|preventDefault={dragEnd}
ondragstart={dragStart}
ondragover={(event) => {
event.preventDefault();

dragOver?.(event);
}}
ondragleave={dragLeave}
ondrop={(event) => {
event.preventDefault();

dragEnd?.();
}}
>
<i class="drag-handle"></i>
{#if file.name === 'App' && filename !== editing_name}
Expand All @@ -234,9 +248,9 @@
autofocus
spellcheck={false}
bind:value={input_value}
on:focus={select_input}
on:blur={close_edit}
on:keydown={(e) => {
onfocus={select_input}
onblur={close_edit}
onkeydown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
if (!is_file_name_used(editing_file)) {
Expand All @@ -251,16 +265,16 @@
<div
class="editable"
title="edit component name"
on:click={() => edit_tab(file)}
on:keyup={(e) => e.key === ' ' && edit_tab(file)}
onclick={() => edit_tab(file)}
onkeyup={(e) => e.key === ' ' && edit_tab(file)}
>
{file.name}.{file.type}{#if show_modified && file.modified}*{/if}
</div>

<span
class="remove"
on:click={() => remove(filename)}
on:keyup={(e) => e.key === ' ' && remove(filename)}
onclick={() => remove(filename)}
onkeyup={(e) => e.key === ' ' && remove(filename)}
>
<svg width="12" height="12" viewBox="0 0 24 24">
<line stroke="#999" x1="18" y1="6" x2="6" y2="18" />
Expand All @@ -272,7 +286,7 @@
{/each}
</div>

<button class="add-new" on:click={add_new} title="add new component">
<button class="add-new" onclick={add_new} title="add new component">
<svg width="12" height="12" viewBox="0 0 24 24">
<line stroke="#999" x1="12" y1="5" x2="12" y2="19" />
<line stroke="#999" x1="5" y1="12" x2="19" y2="12" />
Expand Down
10 changes: 7 additions & 3 deletions packages/repl/src/lib/Input/ModuleEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
import CodeMirror from '../CodeMirror.svelte';
import type { CompileError, Warning } from 'svelte/compiler';

export let error: CompileError;
export let warnings: Warning[];
export let vim: boolean;
interface Props {
error: CompileError;
warnings: Warning[];
vim: boolean;
}

let { error, warnings, vim }: Props = $props();

export function focus() {
$module_editor?.focus();
Expand Down
25 changes: 18 additions & 7 deletions packages/repl/src/lib/Message.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,21 @@
import { get_repl_context } from './context.js';
import type { MessageDetails } from './types.js';

export let kind: 'info' | 'warning' | 'error' = 'info';
export let details: MessageDetails | undefined = undefined;
export let filename: string | undefined = undefined;
export let truncate = false;
interface Props {
kind?: 'info' | 'warning' | 'error';
details?: MessageDetails | undefined;
filename?: string | undefined;
truncate?: boolean;
children?: import('svelte').Snippet;
}

let {
kind = 'info',
details = undefined,
filename = undefined,
truncate = false,
children
}: Props = $props();

const { go_to_warning_pos } = get_repl_context();

Expand All @@ -27,13 +38,13 @@
{#if details}
<button
class:navigable={details.filename}
on:click={() => go_to_warning_pos(details)}
on:keyup={(e) => e.key === ' ' && go_to_warning_pos(details)}
onclick={() => go_to_warning_pos(details)}
onkeyup={(e) => e.key === ' ' && go_to_warning_pos(details)}
>
{message(details)}
</button>
{:else}
<slot />
{@render children?.()}
{/if}
</div>

Expand Down
Loading
Loading