diff --git a/packages/editor/src/lib/Editor.svelte b/packages/editor/src/lib/Editor.svelte index ed6c11d71..9b7ab09c8 100644 --- a/packages/editor/src/lib/Editor.svelte +++ b/packages/editor/src/lib/Editor.svelte @@ -52,14 +52,25 @@ }} /> +
{ + onpointerdown={() => { + workspace.enable_tab_indent(); + }} + onkeydown={(e) => { + if (e.key !== 'Tab') { + workspace.enable_tab_indent(); + } + }} + onfocusin={(e) => { clearTimeout(remove_focus_timeout); preserve_editor_focus = true; }} onfocusout={() => { + workspace.disable_tab_indent(); + // Heuristic: user did refocus themmselves if iframe_took_focus // doesn't happen in the next few miliseconds. Needed // because else navigations inside the iframe refocus the editor. diff --git a/packages/editor/src/lib/Workspace.svelte.ts b/packages/editor/src/lib/Workspace.svelte.ts index 8d6be150f..3c8cbe1a8 100644 --- a/packages/editor/src/lib/Workspace.svelte.ts +++ b/packages/editor/src/lib/Workspace.svelte.ts @@ -1,5 +1,5 @@ import type { CompileError, CompileOptions, CompileResult } from 'svelte/compiler'; -import { EditorState } from '@codemirror/state'; +import { Compartment, EditorState } from '@codemirror/state'; import { compile_file } from './compile-worker'; import { BROWSER } from 'esm-env'; import { basicSetup, EditorView } from 'codemirror'; @@ -51,10 +51,12 @@ function file_type(file: Item) { return file.name.split('.').pop(); } +const tab_behaviour = new Compartment(); + const default_extensions = [ basicSetup, EditorState.tabSize.of(2), - keymap.of([{ key: 'Tab', run: acceptCompletion }, indentWithTab]), + tab_behaviour.of(keymap.of([{ key: 'Tab', run: acceptCompletion }])), indentUnit.of('\t'), theme ]; @@ -209,6 +211,20 @@ export class Workspace { return item; } + disable_tab_indent() { + this.#view?.dispatch({ + effects: tab_behaviour.reconfigure(keymap.of([{ key: 'Tab', run: acceptCompletion }])) + }); + } + + enable_tab_indent() { + this.#view?.dispatch({ + effects: tab_behaviour.reconfigure( + keymap.of([{ key: 'Tab', run: acceptCompletion }, indentWithTab]) + ) + }); + } + focus() { setTimeout(() => { this.#view?.focus();