diff --git a/index.html b/index.html index 181e9cb..31695d5 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ Miller code editor + diff --git a/package-lock.json b/package-lock.json index 547d6f3..a175893 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "miller", - "version": "1.0.0", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "miller", - "version": "1.0.0", + "version": "0.1.0", "license": "MIT", "dependencies": { "electron-squirrel-startup": "^1.0.1" @@ -30,6 +30,8 @@ "@types/electron-squirrel-startup": "^1.0.2", "@typescript-eslint/eslint-plugin": "^8.46.3", "@typescript-eslint/parser": "^8.46.3", + "@xterm/addon-fit": "^0.10.0", + "@xterm/xterm": "^5.5.0", "codemirror": "^6.0.2", "electron": "39.1.1", "eslint": "^9.39.1", @@ -3904,6 +3906,23 @@ "node": ">=10.0.0" } }, + "node_modules/@xterm/addon-fit": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz", + "integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@xterm/xterm": "^5.0.0" + } + }, + "node_modules/@xterm/xterm": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", + "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", + "dev": true, + "license": "MIT" + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", diff --git a/package.json b/package.json index 6e2c54f..4b32522 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "@types/electron-squirrel-startup": "^1.0.2", "@typescript-eslint/eslint-plugin": "^8.46.3", "@typescript-eslint/parser": "^8.46.3", + "@xterm/addon-fit": "^0.10.0", + "@xterm/xterm": "^5.5.0", "codemirror": "^6.0.2", "electron": "39.1.1", "eslint": "^9.39.1", diff --git a/src/app/editorgrid.ts b/src/app/editorgrid.ts index 70e37d9..eb0c1b9 100644 --- a/src/app/editorgrid.ts +++ b/src/app/editorgrid.ts @@ -5,6 +5,7 @@ const v = van.tags; import { OpenFile } from "./filestate"; import * as u from "./utils"; import { Editor } from "./editor"; +import { Terminal } from "./terminal"; export interface Displayable { setDeleteFunction(del: () => void): void; @@ -51,6 +52,13 @@ export function addTab(file?: OpenFile) { editors.push(file ? [file] : []); } +export function addTerminal() { + console.log("Adding terminal"); + const term = new Terminal(); + editors[currentTab.val].push(vanX.noreactive(term)); + term.focus(); +} + const TabHeader = (tab: State, del: () => void, k: number) => v.div( { @@ -83,3 +91,10 @@ export const EditorTabs = v.div( vanX.list(TabBar, editors, TabHeader); vanX.list(EditorTabs, editors, EditorGrid); + +document.addEventListener("keyup", (e) => { + if (e.key === "t" && e.altKey) { + console.log("Opening terminal"); + addTerminal(); + } +}); diff --git a/src/app/terminal.ts b/src/app/terminal.ts new file mode 100644 index 0000000..4da9f9a --- /dev/null +++ b/src/app/terminal.ts @@ -0,0 +1,47 @@ +import { Displayable } from "./editorgrid"; +import * as xterm from "@xterm/xterm"; +import { FitAddon } from "@xterm/addon-fit"; +import van from "vanjs-core"; +const v = van.tags; + +export class Terminal implements Displayable { + term: xterm.Terminal; + currentTitle: string = "Terminal"; + del: () => void; + dom: HTMLElement; + + setDeleteFunction(del: () => void): void { + this.del = del; + } + + title(): string { + return this.currentTitle; + } + + constructor() { + this.term = new xterm.Terminal(); + + const fitAddon = new FitAddon(); + this.term.loadAddon(fitAddon); + + this.dom = v.div({ class: "h-full w-full" }); + const loaded = van.state(false); + van.derive(() => { + if (loaded.val) { + this.term.open(this.dom); + fitAddon.fit(); + this.term.writeln("Welcome to the terminal!"); + } + }); + loaded.val = true; + } + + focus() { + this.term.focus(); + } + + close() { + this.term.dispose(); + this.del(); + } +}