fix undo I think
This commit is contained in:
parent
8c750ac2dc
commit
a7ed7b87f2
410
codetab.ts
410
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 = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user