From 2babbf5c686e337fed12e843e72d8cc45cc71338 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Wed, 22 Nov 2023 15:11:32 -0500 Subject: [PATCH] Implement merging lines of text from either end of a row --- src/common/document.ts | 37 ++++++++++++++++++++++++++++++++++--- src/common/row.ts | 5 +++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/common/document.ts b/src/common/document.ts index 9b83a16..f1b053a 100644 --- a/src/common/document.ts +++ b/src/common/document.ts @@ -67,12 +67,34 @@ export class Document { } public delete(at: Position): void { - const row = this.row(at.y); - if (row === null) { + const len = this.numRows; + if (at.y >= len) { return; } - row.delete(at.x); + const row = this.row(at.y)!; + const mergeNextRow = at.x === row.size - 1 && at.y < len - 1; + const mergeIntoPrevRow = at.x === 0 && at.y > 0; + + // If we are at the end of a line, and press delete, + // add the contents of the next row, and delete + // the merged row object + if (mergeNextRow) { + // At the end of a line, pressing delete will merge + // the next line into the current on + const rowToAppend = this.#rows.at(at.y + 1)!.toString(); + row.append(rowToAppend); + this.deleteRow(at.y + 1); + } else if (mergeIntoPrevRow) { + // At the beginning of a line, merge the current line + // into the previous Row + const rowToAppend = row.toString(); + this.#rows[at.y - 1].append(rowToAppend); + this.deleteRow(at.y); + } else { + row.delete(at.x); + } + row.updateRender(); this.dirty = true; @@ -90,6 +112,15 @@ export class Document { this.dirty = true; } + /** + * Delete the specified row + * @param at - the index of the row to delete + * @private + */ + private deleteRow(at: number): void { + this.#rows.splice(at, 1); + } + private rowsToString(): string { return this.#rows.map((r) => r.toString()).join('\n'); } diff --git a/src/common/row.ts b/src/common/row.ts index 0d04532..1670ca6 100644 --- a/src/common/row.ts +++ b/src/common/row.ts @@ -33,6 +33,11 @@ export class Row { return this.render.slice(offset).join(''); } + public append(s: string): void { + this.chars = this.chars.concat(chars(s)); + this.updateRender(); + } + public insertChar(at: number, c: string): void { const newSlice = Util.chars(c); if (at >= this.size) {