Syntax highlighting
This commit is contained in:
parent
1fa58961fc
commit
12bc0cb385
169
codetab.ts
169
codetab.ts
@ -4,6 +4,7 @@ import { drawText } from "./builtins.ts";
|
|||||||
import { COLOR } from "./colors.ts";
|
import { COLOR } from "./colors.ts";
|
||||||
import {getSheet, setSheet} from "./sheet.ts";
|
import {getSheet, setSheet} from "./sheet.ts";
|
||||||
import { K, getKeyboardString, keyPressed, shiftKeyDown } from "./keyboard.ts";
|
import { K, getKeyboardString, keyPressed, shiftKeyDown } from "./keyboard.ts";
|
||||||
|
import { tokenize } from "./deps.ts";
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
scrollX: 0,
|
scrollX: 0,
|
||||||
@ -138,6 +139,145 @@ const gridToIndex = (str: string, x: number, y: number) => {
|
|||||||
return lines.slice(0, y).join("\n").length+Math.min(x, lines[y].length)+1;
|
return lines.slice(0, y).join("\n").length+Math.min(x, lines[y].length)+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 keywordColor = COLOR.PURPLE;
|
||||||
|
const operatorColor = COLOR.CYAN;
|
||||||
|
const valueColor = COLOR.ORANGE;
|
||||||
|
const stringColor = COLOR.GREEN;
|
||||||
|
const regexColor = stringColor;
|
||||||
|
const punctuationColor = COLOR.WHITE;
|
||||||
|
const commentColor = COLOR.GRAY;
|
||||||
|
const identifierColor = COLOR.LIGHTGRAY;
|
||||||
|
const invalidColor = COLOR.RED;
|
||||||
|
|
||||||
|
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 drawCodeField = (code: string, x: number, y: number, w: number, h: number) => {
|
||||||
const {
|
const {
|
||||||
scrollX,
|
scrollX,
|
||||||
@ -162,9 +302,34 @@ const drawCodeField = (code: string, x: number, y: number, w: number, h: number)
|
|||||||
fillRect(x+focusX*fontWidth-scrollX, y+focusY*(fontHeight+1)-scrollY, fontWidth+1, fontHeight+1, COLOR.YELLOW);
|
fillRect(x+focusX*fontWidth-scrollX, y+focusY*(fontHeight+1)-scrollY, fontWidth+1, fontHeight+1, COLOR.YELLOW);
|
||||||
}
|
}
|
||||||
// TODO: Add syntax highlighting use "npm:js-tokens" maybe?
|
// TODO: Add syntax highlighting use "npm:js-tokens" maybe?
|
||||||
code.split("\n").forEach((line, i) => {
|
const tokens = [...tokenize(code)];
|
||||||
drawText(x-scrollX, 1+y+i*(fontHeight+1)-scrollY, line);
|
let cx = 0;
|
||||||
|
let cy = 0;
|
||||||
|
tokens.forEach((token) => {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
drawText(x+cx-scrollX, 1+y+cy-scrollY, line, color);
|
||||||
|
if (i === lines.length-1) {
|
||||||
|
cx += fontWidth*line.length;
|
||||||
|
} else {
|
||||||
|
cx=0;
|
||||||
|
cy+=fontHeight+1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
|
@ -8,6 +8,12 @@ const colors = {
|
|||||||
BLUE: [0, 0, 1],
|
BLUE: [0, 0, 1],
|
||||||
DARKBLUE: [0.1, 0.05, 0.4],
|
DARKBLUE: [0.1, 0.05, 0.4],
|
||||||
BROWN: [0.6, 0.5, 0.4],
|
BROWN: [0.6, 0.5, 0.4],
|
||||||
|
GRAY: [0.5, 0.5, 0.5],
|
||||||
|
PURPLE: [0.7, 0.1, 0.85],
|
||||||
|
ORANGE: [0.95, 0.75, 0.25],
|
||||||
|
CYAN: [0, 0.9, 0.9],
|
||||||
|
LIGHTGRAY: [0.75, 0.75, 0.75],
|
||||||
|
REDDISH: [0.7, 1, 0.5],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const palette: Array<[number, number, number, number]> = Object.values(colors).map(val => [...val, 1]);
|
export const palette: Array<[number, number, number, number]> = Object.values(colors).map(val => [...val, 1]);
|
||||||
|
11
deno.lock
generated
11
deno.lock
generated
@ -42,5 +42,16 @@
|
|||||||
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_darwin_aarch64.js": "ae4d795d93830b8a27714ab6c20b69b67f3d4ad3544c50e344558756cf2e92f3",
|
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_darwin_aarch64.js": "ae4d795d93830b8a27714ab6c20b69b67f3d4ad3544c50e344558756cf2e92f3",
|
||||||
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_linux.js": "b064aedb175fee1a977937f07584238f313a1958f9869273e7e672c42f09932d",
|
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_linux.js": "b064aedb175fee1a977937f07584238f313a1958f9869273e7e672c42f09932d",
|
||||||
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_windows.js": "6ac603e03520c8c333e1475cb00f982adb1f8a99de7f4bb0b8953da66f210159"
|
"https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_windows.js": "6ac603e03520c8c333e1475cb00f982adb1f8a99de7f4bb0b8953da66f210159"
|
||||||
|
},
|
||||||
|
"npm": {
|
||||||
|
"specifiers": {
|
||||||
|
"js-tokens": "js-tokens@8.0.1"
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"js-tokens@8.0.1": {
|
||||||
|
"integrity": "sha512-3AGrZT6tuMm1ZWWn9mLXh7XMfi2YtiLNPALCVxBCiUVq0LD1OQMxV/AdS/s7rLJU5o9i/jBZw/N4vXXL5dm29A==",
|
||||||
|
"dependencies": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
deps.ts
24
deps.ts
@ -1,6 +1,30 @@
|
|||||||
|
// dwm
|
||||||
export {
|
export {
|
||||||
createWindow,
|
createWindow,
|
||||||
getProcAddress,
|
getProcAddress,
|
||||||
mainloop,
|
mainloop,
|
||||||
} from "https://deno.land/x/dwm@0.3.3/mod.ts";
|
} from "https://deno.land/x/dwm@0.3.3/mod.ts";
|
||||||
export * as gl from "https://deno.land/x/gluten@0.1.6/api/gles23.2.ts";
|
export * as gl from "https://deno.land/x/gluten@0.1.6/api/gles23.2.ts";
|
||||||
|
|
||||||
|
// jsTokens
|
||||||
|
import jsTokens from "npm:js-tokens";
|
||||||
|
export function tokenize(input: string): Iterable<Token> {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
return (jsTokens as any)(input);
|
||||||
|
};
|
||||||
|
type Token =
|
||||||
|
| { type: "StringLiteral"; value: string; closed: boolean }
|
||||||
|
| { type: "NoSubstitutionTemplate"; value: string; closed: boolean }
|
||||||
|
| { type: "TemplateHead"; value: string }
|
||||||
|
| { type: "TemplateMiddle"; value: string }
|
||||||
|
| { type: "TemplateTail"; value: string; closed: boolean }
|
||||||
|
| { type: "RegularExpressionLiteral"; value: string; closed: boolean }
|
||||||
|
| { type: "MultiLineComment"; value: string; closed: boolean }
|
||||||
|
| { type: "SingleLineComment"; value: string }
|
||||||
|
| { type: "IdentifierName"; value: string }
|
||||||
|
| { type: "PrivateIdentifier"; value: string }
|
||||||
|
| { type: "NumericLiteral"; value: string }
|
||||||
|
| { type: "Punctuator"; value: string }
|
||||||
|
| { type: "WhiteSpace"; value: string }
|
||||||
|
| { type: "LineTerminatorSequence"; value: string }
|
||||||
|
| { type: "Invalid"; value: string };
|
Loading…
x
Reference in New Issue
Block a user