From a7ed7b87f2d7b6971c6495eed1a30f2f847ed82f Mon Sep 17 00:00:00 2001 From: dylan <> Date: Mon, 8 May 2023 22:13:01 -0700 Subject: [PATCH] fix undo I think --- codetab.ts | 410 +++++++++++++++++++++++++++-------------------------- 1 file changed, 211 insertions(+), 199 deletions(-) diff --git a/codetab.ts b/codetab.ts index 23c5dbe..4d18ea5 100644 --- a/codetab.ts +++ b/codetab.ts @@ -12,6 +12,152 @@ const historyDebounceFrames = 20; const fontHeight = font.height; + +const keywords = [ + "break", + "case", + "catch", + "class", + "const", + "continue", + "debugger", + "default", + "delete", + "do", + "else", + "export", + "extends", + "finally", + "for", + "function", + "if", + "import", + "in", + "instanceof", + "new", + "return", + "super", + "switch", + "this", + "throw", + "try", + "typeof", + "var", + "void", + "while", + "with", + "let", + "static", + "yield", + "await", + "enum", + "implements", + "interface", + "package", + "private", + "protected", + "public", + "=>", +]; +const values = [ + "false", + "null", + "true", + "undefined", +]; +const operator = [ + "&&", + "||", + "??", + "--", + "++", + ".", + "?.", + "<", + "<=", + ">", + ">=", + "!=", + "!==", + "==", + "===", + "+", + "-", + "%", + "&", + "|", + "^", + "/", + "*", + "**", + "<<", + ">>", + ">>>", + "=", + "+=", + "-=", + "%=", + "&=", + "|=", + "^=", + "/=", + "*=", + "**=", + "<<=", + ">>=", + ">>>=", + "!", + "?", + "~", + "...", +]; +const punctuation = [ + "(", + ")", + "[", + "]", + "{", + "}", + ".", + ":", + ";", + ",", +]; + +const builtinColor = COLOR.BLUE; +const keywordColor = COLOR.PURPLE; +const operatorColor = COLOR.CYAN; +const valueColor = COLOR.ORANGE; +const stringColor = COLOR.GREEN; +const regexColor = COLOR.PINK; +const punctuationColor = COLOR.LIGHTGRAY; +const commentColor = COLOR.DARKGREEN; +const identifierColor = COLOR.YELLOW; +const invalidColor = COLOR.RED; + +const caretColor = COLOR.WHITE; +const selectionColor = COLOR.DARKBLUE; + +const backgroundColor = COLOR.DARKERBLUE; + +const tokenColors = { + "StringLiteral": stringColor, + "NoSubstitutionTemplate": stringColor, + "TemplateHead": stringColor, + "TemplateMiddle": stringColor, + "TemplateTail": stringColor, + "RegularExpressionLiteral": regexColor, + "MultiLineComment": commentColor, + "SingleLineComment": commentColor, + "IdentifierName": identifierColor, + "PrivateIdentifier": identifierColor, + "NumericLiteral": valueColor, + "Punctuator": punctuationColor, + "WhiteSpace": punctuationColor, + "LineTerminatorSequence": punctuationColor, + "Invalid": invalidColor, +} + const transformForCopy = (text: string) => { text = text.replaceAll("➡", "➡️"); text = text.replaceAll("⬅", "⬅️"); @@ -31,7 +177,7 @@ const transformForPaste = (text: string) => { } const state = { - history: [{code: getCodeSheet(page.activeSheet), anchor: 0, focus: 0}], + history: [] as Array<{code: string, anchor: number, focus: number}>, historyDebounce: 0, historyIndex: 0, undo() { @@ -68,7 +214,9 @@ const state = { }, startSnapping() { console.log('start snapping', this.historyIndex); - this.historyIndex += 1; + if (this.historyDebounce <= 0) { + this.historyIndex += 1; + } if (this.history.length > this.historyIndex) { this.history.length = this.historyIndex; } @@ -291,204 +439,11 @@ const pixelToIndex = (str: string, x: number, y: number) => { return prefix + j; } -const keywords = [ - "break", - "case", - "catch", - "class", - "const", - "continue", - "debugger", - "default", - "delete", - "do", - "else", - "export", - "extends", - "finally", - "for", - "function", - "if", - "import", - "in", - "instanceof", - "new", - "return", - "super", - "switch", - "this", - "throw", - "try", - "typeof", - "var", - "void", - "while", - "with", - "let", - "static", - "yield", - "await", - "enum", - "implements", - "interface", - "package", - "private", - "protected", - "public", - "=>", -]; -const values = [ - "false", - "null", - "true", - "undefined", -]; -const operator = [ - "&&", - "||", - "??", - "--", - "++", - ".", - "?.", - "<", - "<=", - ">", - ">=", - "!=", - "!==", - "==", - "===", - "+", - "-", - "%", - "&", - "|", - "^", - "/", - "*", - "**", - "<<", - ">>", - ">>>", - "=", - "+=", - "-=", - "%=", - "&=", - "|=", - "^=", - "/=", - "*=", - "**=", - "<<=", - ">>=", - ">>>=", - "!", - "?", - "~", - "...", -]; -const punctuation = [ - "(", - ")", - "[", - "]", - "{", - "}", - ".", - ":", - ";", - ",", -]; - -const builtinColor = COLOR.BLUE; -const keywordColor = COLOR.PURPLE; -const operatorColor = COLOR.CYAN; -const valueColor = COLOR.ORANGE; -const stringColor = COLOR.GREEN; -const regexColor = stringColor; -const punctuationColor = COLOR.LIGHTGRAY; -const commentColor = COLOR.DARKGREEN; -const identifierColor = COLOR.RED; -const invalidColor = COLOR.DARKRED; - -const tokenColors = { - "StringLiteral": stringColor, - "NoSubstitutionTemplate": stringColor, - "TemplateHead": stringColor, - "TemplateMiddle": stringColor, - "TemplateTail": stringColor, - "RegularExpressionLiteral": regexColor, - "MultiLineComment": commentColor, - "SingleLineComment": commentColor, - "IdentifierName": identifierColor, - "PrivateIdentifier": identifierColor, - "NumericLiteral": valueColor, - "Punctuator": punctuationColor, - "WhiteSpace": punctuationColor, - "LineTerminatorSequence": punctuationColor, - "Invalid": invalidColor, -} - -const drawCodeField = (code: string, x: number, y: number, w: number, h: number) => { - const { - scrollX, - scrollY, - anchor, - focus, - } = state; - fillRect(x, y, w, h, COLOR.DARKERBLUE); - if (anchor !== focus) { - for (let i = Math.min(anchor, focus); i < Math.max(anchor, focus); i++) { - const sel = indexToRect(code, i); - fillRect(x+sel.x-scrollX, y+sel.y-scrollY, sel.w+2, sel.h, COLOR.WHITE); - } - } - const rect = indexToRect(code, focus); - fillRect(x+rect.x-scrollX, y+rect.y-scrollY, 1, rect.h, COLOR.YELLOW); - - const builtins = Object.keys(getBuiltins()); - const tokens = [...tokenize(code)]; - let cx = 0; - let cy = 0; - tokens.forEach((token) => { - if (token.type === "LineTerminatorSequence") { - cx=0; - cy+=fontHeight+1; - return; - } - const lines = token.value.split("\n"); - lines.forEach((line, i) => { - let color = tokenColors[token.type]; - if (keywords.includes(token.value)) { - color = keywordColor; - } - if (values.includes(token.value)) { - color = valueColor; - } - if (operator.includes(token.value)) { - color = operatorColor; - } - if (punctuation.includes(token.value)) { - color = punctuationColor; - } - if (builtins.includes(token.value)) { - color = builtinColor; - } - drawText(1+x+cx-scrollX, 1+y+cy-scrollY, line, color); - if (i === lines.length-1) { - cx += measureText(line)+1; - } else { - cx=0; - cy+=fontHeight+1; - } - }); - }) -} - const update = async () => { const { focus } = state; + if (state.history.length === 0) { + state.snapshot(); + } if (state.historyDebounce > 0) { state.historyDebounce -= 1; if (state.historyDebounce <= 0) { @@ -591,7 +546,64 @@ const update = async () => { const draw = () => { clearScreen(); - drawCodeField(state.code, 0, 8, 128, 112); + const { + scrollX, + scrollY, + anchor, + focus, + code, + } = state; + const x = 0; + const y = 8; + const w = 128; + const h = 112; + fillRect(x, y, w, h, backgroundColor); + if (anchor !== focus) { + for (let i = Math.min(anchor, focus); i < Math.max(anchor, focus); i++) { + const sel = indexToRect(code, i); + fillRect(x+sel.x-scrollX, y+sel.y-scrollY, sel.w+2, sel.h, selectionColor); + } + } + const rect = indexToRect(code, focus); + fillRect(x+rect.x-scrollX, y+rect.y-scrollY, 1, rect.h, caretColor); + + const builtins = Object.keys(getBuiltins()); + const tokens = [...tokenize(code)]; + let cx = 0; + let cy = 0; + tokens.forEach((token) => { + if (token.type === "LineTerminatorSequence") { + cx=0; + cy+=fontHeight+1; + return; + } + const lines = token.value.split("\n"); + lines.forEach((line, i) => { + let color = tokenColors[token.type]; + if (keywords.includes(token.value)) { + color = keywordColor; + } + if (values.includes(token.value)) { + color = valueColor; + } + if (operator.includes(token.value)) { + color = operatorColor; + } + if (punctuation.includes(token.value)) { + color = punctuationColor; + } + if (builtins.includes(token.value)) { + color = builtinColor; + } + drawText(1+x+cx-scrollX, 1+y+cy-scrollY, line, color); + if (i === lines.length-1) { + cx += measureText(line)+1; + } else { + cx=0; + cy+=fontHeight+1; + } + }); + }) } export const codetab = {