diff --git a/codetab.ts b/codetab.ts index 04a0456..bec6745 100644 --- a/codetab.ts +++ b/codetab.ts @@ -3,8 +3,8 @@ import { fontWidth, fontHeight } from "./font.ts"; import { drawText } from "./builtins.ts"; import { COLOR } from "./colors.ts"; import {getSheet, setSheet} from "./sheet.ts"; -import { K, getKeyboardString, keyPressed, shiftKeyDown } from "./keyboard.ts"; -import { tokenize } from "./deps.ts"; +import { K, ctrlKeyDown, getKeyboardString, keyPressed, shiftKeyDown } from "./keyboard.ts"; +import { clipboard, tokenize } from "./deps.ts"; const state = { scrollX: 0, @@ -91,6 +91,19 @@ const state = { this.insertText(""); } }, + async copy() { + const {code, anchor, focus} = this; + const selected = code.slice(Math.min(anchor,focus), Math.max(anchor,focus)); + await clipboard.writeText(selected); + }, + async cut() { + await this.copy(); + this.insertText(""); + }, + async paste() { + + this.insertText(await clipboard.readText()); + }, scrollToCursor() { const {focusY, focusX, scrollY, scrollX} = this; const fh = fontHeight + 1; @@ -332,14 +345,14 @@ const drawCodeField = (code: string, x: number, y: number, w: number, h: number) }) } -const update = () => { +const update = async () => { const { focus, focusX, focusY} = state; const keyboardString = getKeyboardString(); if (keyboardString) { state.insertText(keyboardString); state.scrollToCursor(); } - // TODO: Handle ctrl-C, ctrl-V, ctrl-X, ctrl-Z + // TODO: Handle ctrl-Z // TODO: Make ctrl-/ do commenting out (take inspiration from tab) if (keyPressed(K.ENTER)) { @@ -399,6 +412,15 @@ const update = () => { } state.scrollToCursor(); } + if (keyPressed("C") && ctrlKeyDown()) { + await state.copy(); + } + if (keyPressed("X") && ctrlKeyDown()) { + await state.cut(); + } + if (keyPressed("V") && ctrlKeyDown()) { + await state.paste(); + } } const draw = () => { diff --git a/colors.ts b/colors.ts index 11f7905..63c9340 100644 --- a/colors.ts +++ b/colors.ts @@ -14,6 +14,7 @@ const colors = { CYAN: [0, 0.9, 0.9], LIGHTGRAY: [0.75, 0.75, 0.75], REDDISH: [0.7, 1, 0.5], + DARKGREEN: [0, 0.6, 0.2], } as const; export const palette: Array<[number, number, number, number]> = Object.values(colors).map(val => [...val, 1]); diff --git a/deno.lock b/deno.lock index 3747ccf..d00b20e 100644 --- a/deno.lock +++ b/deno.lock @@ -41,7 +41,8 @@ "https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_darwin.js": "48911f26fff723a9c5f2f38e39be42fc65ed8dea6f2ba1f1acb464d3f0aa435b", "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_windows.js": "6ac603e03520c8c333e1475cb00f982adb1f8a99de7f4bb0b8953da66f210159" + "https://glfw-binaries.deno.dev/3.4.0-patch2/glfw3_windows.js": "6ac603e03520c8c333e1475cb00f982adb1f8a99de7f4bb0b8953da66f210159", + "https://raw.githubusercontent.com/Nisgrak/deno-clipboard/fix-deno-1.0.0/mod.ts": "85282325a499c75c6f9ed3603fc5f8baf4bf661a616add43b4e6f033def52680" }, "npm": { "specifiers": { diff --git a/deps.ts b/deps.ts index 34a711e..9d1a626 100644 --- a/deps.ts +++ b/deps.ts @@ -1,17 +1,18 @@ // dwm export { - createWindow, - getProcAddress, - mainloop, + createWindow, + getProcAddress, + mainloop, } 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"; +import { clipboard } from "https://raw.githubusercontent.com/Nisgrak/deno-clipboard/fix-deno-1.0.0/mod.ts"; // jsTokens import jsTokens from "npm:js-tokens"; export function tokenize(input: string): Iterable { - // deno-lint-ignore no-explicit-any - return (jsTokens as any)(input); -}; + // 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 } @@ -27,4 +28,13 @@ type Token = | { type: "Punctuator"; value: string } | { type: "WhiteSpace"; value: string } | { type: "LineTerminatorSequence"; value: string } - | { type: "Invalid"; value: string }; \ No newline at end of file + | { type: "Invalid"; value: string }; + +// clipboard +export { clipboard } from "https://raw.githubusercontent.com/Nisgrak/deno-clipboard/fix-deno-1.0.0/mod.ts"; +try { + await clipboard.readText(); +} catch (err) { + console.log("If you are running this on linux, please make sure you have 'xsel' installed."); + throw err; +} \ No newline at end of file diff --git a/index.ts b/index.ts index eb8084a..acb29f8 100644 --- a/index.ts +++ b/index.ts @@ -23,7 +23,7 @@ addToContext("play", () => { clearScreen(); -await mainloop((_t) => { +await mainloop(async (_t) => { // TODO: use t if (keyPressed(K.ESCAPE)) { const modeTo = ({ @@ -51,11 +51,11 @@ await mainloop((_t) => { repl.draw(); frame(); } else if (mode === "edit") { - editmode.update(); + await editmode.update(); editmode.draw(); frame(); } } refreshKeyboard(); refreshMouse(); -}); +}, false);