Syntax highlighting

This commit is contained in:
dylan 2023-05-06 10:00:41 -07:00
parent 1fa58961fc
commit 12bc0cb385
4 changed files with 210 additions and 4 deletions

View File

@ -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 = () => {

View File

@ -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
View File

@ -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
View File

@ -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 };