diff --git a/src/common/all_test.ts b/src/common/all_test.ts index 4834b0b..61d4e5f 100644 --- a/src/common/all_test.ts +++ b/src/common/all_test.ts @@ -323,10 +323,10 @@ const DocumentTest = { doc.insert(Position.at(9, 0), 'buzz'); assertEquals(doc.numRows, 1); assertTrue(doc.dirty); - const row0 = doc.row(0); - assertEquals(row0?.toString(), 'foobazbarbuzz'); - assertEquals(row0?.rstring(), 'foobazbarbuzz'); - assertEquals(row0?.rsize, 13); + const row0 = doc.row(0).unwrap(); + assertEquals(row0.toString(), 'foobazbarbuzz'); + assertEquals(row0.rstring(), 'foobazbarbuzz'); + assertEquals(row0.rsize, 13); doc.insert(Position.at(0, 1), 'Lorem Ipsum'); assertEquals(doc.numRows, 2); diff --git a/src/common/document.ts b/src/common/document.ts index e45fb82..5da15c7 100644 --- a/src/common/document.ts +++ b/src/common/document.ts @@ -145,7 +145,13 @@ export class Document { return; } - const row = this.row(at.y)!; + const maybeRow = this.row(at.y); + if (maybeRow.isNone()) { + return; + } + + const row = maybeRow.unwrap(); + const mergeNextRow = at.x === row.size && at.y + 1 < len; const mergeIntoPrevRow = at.x === 0 && at.y > 0; @@ -173,8 +179,8 @@ export class Document { this.dirty = true; } - public row(i: number): Row | null { - return this.#rows[i] ?? null; + public row(i: number): Option { + return Option.from(this.#rows[i]); } public insertRow(at: number = this.numRows, s: string = ''): void { diff --git a/src/common/editor.ts b/src/common/editor.ts index c5d6118..e8b7837 100644 --- a/src/common/editor.ts +++ b/src/common/editor.ts @@ -85,7 +85,7 @@ class Editor { return this.#document.numRows; } - private get currentRow(): Row | null { + private get currentRow(): Option { return this.#document.row(this.#cursor.y); } @@ -153,8 +153,8 @@ class Editor { break; case KeyCommand.End: - if (this.currentRow !== null) { - this.#cursor.x = this.currentRow.size; + if (this.currentRow.isSome()) { + this.#cursor.x = this.currentRow.unwrap().size; } break; @@ -360,25 +360,27 @@ class Editor { } private moveCursor(char: string): void { + const rowSize = (this.currentRow.isSome()) + ? this.currentRow.unwrap().size + : 0; + switch (char) { case KeyCommand.ArrowLeft: if (this.#cursor.x > 0) { this.#cursor.x--; } else if (this.#cursor.y > 0) { this.#cursor.y--; - this.#cursor.x = (this.currentRow !== null) - ? this.currentRow.size - : 0; + this.#cursor.x = rowSize; } break; case KeyCommand.ArrowRight: if ( - this.currentRow !== null && this.#cursor.x < this.currentRow.size + this.currentRow.isSome() && this.#cursor.x < rowSize ) { this.#cursor.x++; } else if ( - this.currentRow !== null && - this.#cursor.x === this.currentRow.size + this.currentRow.isSome() && + this.#cursor.x === rowSize ) { this.#cursor.y++; this.#cursor.x = 0; @@ -396,16 +398,15 @@ class Editor { break; } - const rowLen = this.currentRow?.size ?? 0; - if (this.#cursor.x > rowLen) { - this.#cursor.x = rowLen; + if (this.#cursor.x > rowSize) { + this.#cursor.x = rowSize; } } private scroll(): void { this.#renderX = 0; - if (this.currentRow !== null) { - this.#renderX = this.currentRow.cxToRx(this.#cursor.x); + if (this.currentRow.isSome()) { + this.#renderX = this.currentRow.unwrap().cxToRx(this.#cursor.x); } if (this.#cursor.y < this.#offset.y) { @@ -475,12 +476,14 @@ class Editor { } private drawFileRow(y: number): void { - const row = this.#document.row(y); - if (row === null) { + const maybeRow = this.#document.row(y); + if (maybeRow.isNone()) { log(`Trying to draw non-existent row '${y}'`, LogLevel.Warning); return this.drawPlaceholderRow(y); } + const row = maybeRow.unwrap(); + const len = Math.min( posSub(row.rsize, this.#offset.x), this.#screen.cols, diff --git a/src/common/search.ts b/src/common/search.ts index 12ae87a..ee120b1 100644 --- a/src/common/search.ts +++ b/src/common/search.ts @@ -64,11 +64,11 @@ export class Search { const current = this.getNextRow(parent.numRows); const row = parent.row(current); - if (row === null) { + if (row.isNone()) { continue; } - const possible = row.find(q); + const possible = row.unwrap().find(q); if (possible.isSome()) { this.lastMatch = current; return possible.map((p: number) => Position.at(p, current));