import Ansi from './ansi.ts'; import Buffer from './buffer.ts'; import { ctrl_key, importDefaultForRuntime, ITerminalSize, strlen, truncate, VERSION, } from '../mod.ts'; export class Editor { #buffer: Buffer; #screenRows: number; #screenCols: number; constructor(terminalSize: ITerminalSize) { this.#buffer = new Buffer(); this.#screenRows = terminalSize.rows; this.#screenCols = terminalSize.cols; } /** * Determine what to do based on input * @param input - the decoded chunk of stdin */ public processKeyPress(input: string): boolean { switch (input) { case ctrl_key('q'): this.clearScreen(); return false; default: return true; } } // ------------------------------------------------------------------------------------------------------------------- // Terminal Output / Drawing // ------------------------------------------------------------------------------------------------------------------- /** * Clear the screen and write out the buffer */ public async refreshScreen(): Promise { const { write } = await importDefaultForRuntime('terminal_io'); this.#buffer.append(Ansi.HideCursor); this.#buffer.append(Ansi.ResetCursor); this.drawRows(); this.#buffer.append(Ansi.ShowCursor); await write(this.#buffer.getBuffer()); this.#buffer.clear(); } private clearScreen(): void { importDefaultForRuntime('terminal_io').then(({ write }) => { this.#buffer.append(Ansi.ClearScreen); this.#buffer.append(Ansi.ResetCursor); write(this.#buffer.getBuffer()).then(() => {}); }); } private drawRows(): void { for (let y = 0; y < this.#screenRows; y++) { if (y === this.#screenRows / 3) { const message = `Kilo editor -- version ${VERSION}`; this.#buffer.append(truncate(message, this.#screenCols)); } else { this.#buffer.append('~'); } this.#buffer.append(Ansi.ClearLine); if (y < this.#screenRows - 1) { this.#buffer.append('\r\n'); } } } }