fantasy-console/repl.ts

130 lines
3.3 KiB
TypeScript
Raw Normal View History

2023-05-04 20:14:48 -07:00
import { drawText} from "./builtins.ts";
import { getKeysPressed, shiftKeyDown, shiftMap, K } from "./keyboard.ts";
2023-05-02 18:17:31 -07:00
import { font } from "./font.ts";
2023-05-04 20:14:48 -07:00
import { addToContext, evalCode } from "./runcode.ts";
import { clearScreen, fillRect } from "./window.ts";
2023-05-05 11:52:08 -07:00
import { COLOR } from "./colors.ts";
2023-05-02 18:17:31 -07:00
2023-05-03 15:17:27 -07:00
const lineHeight = 6;
2023-05-03 16:47:09 -07:00
const history: Array<string> = [];
let historyIndex = history.length;
let textLinesAbove: Array<string> = [];
2023-05-03 15:17:27 -07:00
let maxLineLen = 0;
2023-05-03 16:47:09 -07:00
let currentLine = "";
let index = 0;
2023-05-03 16:47:09 -07:00
export const resetRepl = () => {
historyIndex = history.length;
textLinesAbove.length = 0;
maxLineLen = 0;
currentLine = "";
index = 0;
}
2023-05-02 18:17:31 -07:00
2023-05-04 20:14:48 -07:00
const print = (arg: unknown) => {
textLinesAbove.push(...String(arg).split("\n").flatMap((line)=>{
const wrap = [];
while (line.length) {
wrap.push(line.slice(0,32));
line = line.slice(32);
}
return wrap;
}));
textLinesAbove = textLinesAbove.slice(-20);
}
const printVal = (arg: unknown) => {
print(JSON.stringify(arg));
}
addToContext("print", print);
addToContext("printVal", printVal);
2023-05-02 18:17:31 -07:00
const update = () => {
2023-05-05 11:52:08 -07:00
// TODO: model this after the newer editmode.ts version using getKeyboardString
2023-05-02 18:17:31 -07:00
for (const key of getKeysPressed()) {
2023-05-02 18:44:27 -07:00
let char = String.fromCharCode(key).toLowerCase();
if (shiftKeyDown()) {
if (char in shiftMap) {
char = shiftMap[char as keyof typeof shiftMap];
} else {
char = char.toUpperCase();
}
}
2023-05-02 18:17:31 -07:00
if (char in font) {
2023-05-03 16:47:09 -07:00
currentLine = currentLine.slice(0, index)+char+currentLine.slice(index);
index += 1;
} else if (key === K.BACKSPACE) {
2023-05-03 15:17:27 -07:00
if (index > 0) {
2023-05-03 16:47:09 -07:00
currentLine = currentLine.slice(0, index-1)+currentLine.slice(index);
2023-05-03 15:17:27 -07:00
index -= 1;
}
} else if (key === K.ARROW_LEFT) {
index -= 1;
if (index < 0) {
index = 0;
}
} else if (key === K.ARROW_RIGHT) {
index += 1;
2023-05-03 16:47:09 -07:00
if (index > currentLine.length) {
index = currentLine.length;
}
} else if (key === K.ARROW_UP) {
historyIndex -= 1;
if (historyIndex < 0) {
historyIndex = -1;
}
const lineAtHistory = history[historyIndex] ?? "";
currentLine = lineAtHistory;
index = currentLine.length;
} else if (key === K.ARROW_DOWN) {
historyIndex += 1;
if (historyIndex > history.length) {
historyIndex = history.length;
}
2023-05-03 16:47:09 -07:00
const lineAtHistory = history[historyIndex] ?? "";
currentLine = lineAtHistory;
index = currentLine.length;
2023-05-03 15:17:27 -07:00
} else if (key === K.ENTER) {
2023-05-04 20:14:48 -07:00
if (currentLine) {
history.push(currentLine);
historyIndex = history.length;
}
print("> "+currentLine);
2023-05-03 16:47:09 -07:00
try {
2023-05-04 20:14:48 -07:00
const ran = evalCode(currentLine);
if (ran !== undefined) {
printVal(ran);
2023-05-03 16:47:09 -07:00
}
} catch (err) {
2023-05-04 20:14:48 -07:00
print(err.name+":\n"+err.message);
2023-05-03 16:47:09 -07:00
}
2023-05-03 15:17:27 -07:00
maxLineLen = 0;
2023-05-03 16:47:09 -07:00
currentLine = "";
2023-05-03 15:17:27 -07:00
index = 0;
2023-05-02 18:17:31 -07:00
}
}
2023-05-03 16:47:09 -07:00
maxLineLen = Math.max(maxLineLen, currentLine.length);
}
const drawTextAbove = () => {
textLinesAbove.forEach((line, i) => {
2023-05-05 11:52:08 -07:00
fillRect(0, 1+i*lineHeight, 4*(line.length+1)+1, lineHeight+1, COLOR.BLACK);
2023-05-04 20:14:48 -07:00
drawText(-1, 1+i*lineHeight, line);
2023-05-03 16:47:09 -07:00
});
2023-05-02 18:17:31 -07:00
}
const draw = () => {
2023-05-03 21:29:11 -07:00
clearScreen();
2023-05-03 16:47:09 -07:00
drawTextAbove();
2023-05-05 11:52:08 -07:00
fillRect(0, 1+textLinesAbove.length*lineHeight, 4*(2+maxLineLen+1)+1, lineHeight+1, COLOR.BLACK);
fillRect((2+index)*4, textLinesAbove.length*lineHeight+1, 4, lineHeight-1, COLOR.RED);
2023-05-04 20:14:48 -07:00
drawText(-1, 1+textLinesAbove.length*lineHeight, "> "+currentLine);
2023-05-02 18:17:31 -07:00
}
export const repl = {
update, draw
}