diff --git a/README.md b/README.md index 975fd77..c05c319 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,15 @@ # Scroll -Making a text editor in Typescript based on Kilo (Script + Kilo = Scroll). -This runs on [Bun](https://bun.sh/) and [Deno](https://deno.com/). +Making a text editor in Typescript based on Kilo (Script + Kilo = Scroll). This +runs on [Bun](https://bun.sh/) and [Deno](https://deno.com/). To simplify running, I'm using [Just](https://github.com/casey/just) -* Bun: `just bun-run` -* Deno: `just deno-run` + +- Bun: `just bun-run` +- Deno: `just deno-run` ## Development Notes -* Runtime differences are adapted into a common interface -* Runtime implementations are in the `src/deno` and `src/bun` folders -* The main implementation is in `src/common` \ No newline at end of file + +- Runtime differences are adapted into a common interface +- Runtime implementations are in the `src/deno` and `src/bun` folders +- The main implementation is in `src/common` diff --git a/src/common/editor/ansi.ts b/src/common/editor/ansi.ts index bb5c20a..aa4d616 100644 --- a/src/common/editor/ansi.ts +++ b/src/common/editor/ansi.ts @@ -14,6 +14,7 @@ export enum KeyCommand { ArrowLeft = ANSI_PREFIX + 'D', PageUp = ANSI_PREFIX + '5~', PageDown = ANSI_PREFIX + '6~', + Delete = ANSI_PREFIX + '3~', // These keys have several possible escape sequences Home = 'LineHome', diff --git a/src/common/editor/document.ts b/src/common/editor/document.ts new file mode 100644 index 0000000..b5cfbd1 --- /dev/null +++ b/src/common/editor/document.ts @@ -0,0 +1,49 @@ +import { chars } from '../utils.ts'; + +export class Row { + chars: string[] = []; + + constructor(s: string = '') { + this.chars = chars(s); + } + + public toString(): string { + return this.chars.join(''); + } +} + +export class Document { + #rows: Row[]; + + private constructor() { + this.#rows = []; + } + + get numrows(): number { + return this.#rows.length; + } + + public static empty(): Document { + return new Document(); + } + + public static open(): Document { + const doc = new Document(); + const line = 'Hello, World!'; + const row = new Row(line); + + doc.#rows.push(row); + + return doc; + } + + public getRow(i: number): Row | null { + if (this.#rows[i] !== undefined) { + return this.#rows[i]; + } + + return null; + } +} + +export default Document; diff --git a/src/common/editor/editor.ts b/src/common/editor/editor.ts index e2288ed..809a401 100644 --- a/src/common/editor/editor.ts +++ b/src/common/editor/editor.ts @@ -1,11 +1,13 @@ import Ansi, { KeyCommand } from './ansi.ts'; import Buffer from './buffer.ts'; +import Document from './document.ts'; import { ctrl_key, IPoint, ITerminalSize, truncate, VERSION } from '../mod.ts'; export class Editor { #buffer: Buffer; #screen: ITerminalSize; #cursor: IPoint; + #document: Document; constructor(terminalSize: ITerminalSize) { this.#buffer = new Buffer(); this.#screen = terminalSize; @@ -13,6 +15,7 @@ export class Editor { x: 0, y: 0, }; + this.#document = Document.open(); } // -------------------------------------------------------------------------- @@ -114,33 +117,47 @@ export class Editor { } private drawRows(): void { - this.drawPlaceholderRows(); - } - - private drawPlaceholderRows(): void { for (let y = 0; y < this.#screen.rows; y++) { - if (y === Math.trunc(this.#screen.rows / 2)) { - const message = `Kilo editor -- version ${VERSION}`; - const messageLen = (message.length > this.#screen.cols) - ? this.#screen.cols - : message.length; - let padding = Math.trunc((this.#screen.cols - messageLen) / 2); - if (padding > 0) { - this.#buffer.append('~'); - padding -= 1; - - this.#buffer.append(' '.repeat(padding)); - } - - this.#buffer.append(truncate(message, messageLen)); + if (y >= this.#document.numrows) { + this.drawPlaceholderRow(y); } else { - this.#buffer.append('~'); - } - - this.#buffer.append(Ansi.ClearLine); - if (y < this.#screen.rows - 1) { - this.#buffer.appendLine(''); + this.drawFileRow(y); } } } + + private drawFileRow(_y: number): void { + const row = this.#document.getRow(0); + let len = row?.chars.length ?? 0; + if (len > this.#screen.cols) { + len = this.#screen.cols; + } + + this.#buffer.appendLine(truncate(row!.toString(), len)); + } + + private drawPlaceholderRow(y: number): void { + if (y === Math.trunc(this.#screen.rows / 2)) { + const message = `Kilo editor -- version ${VERSION}`; + const messageLen = (message.length > this.#screen.cols) + ? this.#screen.cols + : message.length; + let padding = Math.trunc((this.#screen.cols - messageLen) / 2); + if (padding > 0) { + this.#buffer.append('~'); + padding -= 1; + + this.#buffer.append(' '.repeat(padding)); + } + + this.#buffer.append(truncate(message, messageLen)); + } else { + this.#buffer.append('~'); + } + + this.#buffer.append(Ansi.ClearLine); + if (y < this.#screen.rows - 1) { + this.#buffer.appendLine(''); + } + } }