diff --git a/src/code_runner.js b/src/code_runner.js index 0051079..d80799c 100644 --- a/src/code_runner.js +++ b/src/code_runner.js @@ -67,7 +67,9 @@ export class CodeRunner { this.console.error(e); if (e instanceof ReferenceError) { - this.console.info("Note: use `export` to allow use of variables within the console"); + this.console.info( + "Note: use `export` to allow use of variables within the console", + ); } } diff --git a/src/console_input.js b/src/console_input.js new file mode 100644 index 0000000..c3b1818 --- /dev/null +++ b/src/console_input.js @@ -0,0 +1,58 @@ +export class ConsoleInput { + constructor(inputElem, console, codeRunner) { + this.inputElem = inputElem; + this.console = console; + this.codeRunner = codeRunner; + this.history = []; + this.historyIndex = 0; + + this.inputElem.onkeydown = (ev) => this.onKeyDown(ev); + } + + onKeyDown(ev) { + switch (ev.key) { + case "Enter": + this.submit(); + break; + case "ArrowUp": + this.moveHistory(-1); + ev.preventDefault(); + break; + case "ArrowDown": + this.moveHistory(1); + ev.preventDefault(); + break; + } + } + + submit() { + const code = this.inputElem.value; + this.inputElem.value = ""; + + this.history.push(code); + this.historyIndex = this.history.length; + + this.codeRunner.evaluateCode(code); + } + + moveHistory(delta) { + this.historyIndex += delta; + + if (this.historyIndex < 0) { + this.historyIndex = 0; + return; + } + + if (this.historyIndex >= this.history.length) { + this.historyIndex = this.history.length; + this.inputElem.value = ""; + return; + } + + this.inputElem.value = this.history[this.historyIndex]; + this.inputElem.setSelectionRange( + this.inputElem.value.length, + this.inputElem.value.length, + ); + } +} diff --git a/src/index.js b/src/index.js index f703e29..85c21e3 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,7 @@ import { Vermiparous } from "./vermiparous.js"; import { promptUpload } from "./prompt_upload.js"; import { GamelibCompleter } from "./gamelib_completer.js"; import { TextCompleter } from "./text_completer.js"; +import { ConsoleInput } from "./console_input.js"; const playgroundConsole = new PlaygroundConsole( document.querySelector("#console-code"), @@ -23,6 +24,8 @@ const spriteProvider = new SpriteProvider(); const codeRunner = new CodeRunner(playgroundConsole, codeStopper); const spriteEditor = new SpriteEditor(document.querySelector("#sprite-editor-container"), []); +new ConsoleInput(document.querySelector("#console-input"), playgroundConsole, codeRunner); + const gamelib = new Gamelib( playgroundConsole, codeStopper, @@ -66,7 +69,6 @@ const saveJsButton = document.querySelector("#save-js"); const saveHtmlButton = document.querySelector("#save-html"); const saveKarlkoderButton = document.querySelector("#save-karlkoder"); const toggleSpriteEditorButton = document.querySelector("#toggle-sprite-editor-button"); -const consoleInput = document.querySelector("#console-input"); const sessionSaveDebounce = new Debounce(1000); editor.addEventListener("change", () => { @@ -218,13 +220,3 @@ saveKarlkoderButton.onclick = () => { }; toggleSpriteEditorButton.addEventListener("click", () => spriteEditor.toggleEditor()); - -consoleInput.onkeydown = (ev) => { - if (ev.key !== "Enter") return; - - const code = ev.target.value; - ev.target.value = ""; - - codeRunner.evaluateCode(code); -}; -