scroll/src/common/document.ts

92 lines
1.7 KiB
JavaScript
Raw Normal View History

2023-11-13 15:33:56 -05:00
import { chars } from './utils.ts';
2023-11-21 15:14:08 -05:00
import Row from './row.ts';
import { getRuntime } from './runtime.ts';
2023-11-21 15:14:08 -05:00
import { Position, TAB_SIZE } from './mod.ts';
2023-11-13 14:46:04 -05:00
export class Document {
2023-11-21 15:14:08 -05:00
#filename: string | null;
2023-11-13 14:46:04 -05:00
#rows: Row[];
2023-11-21 15:14:08 -05:00
dirty: boolean;
2023-11-13 14:46:04 -05:00
private constructor() {
this.#rows = [];
2023-11-21 15:14:08 -05:00
this.#filename = null;
this.dirty = false;
2023-11-13 14:46:04 -05:00
}
get numRows(): number {
2023-11-13 14:46:04 -05:00
return this.#rows.length;
}
public static empty(): Document {
return new Document();
}
public isEmpty(): boolean {
return this.#rows.length === 0;
}
public async open(filename: string): Promise<Document> {
const { file } = await getRuntime();
// Clear any existing rows
if (!this.isEmpty()) {
this.#rows = [];
}
2023-11-13 14:46:04 -05:00
const rawFile = await file.openFile(filename);
rawFile.split(/\r?\n/)
.forEach((row) => this.appendRow(row));
2023-11-13 14:46:04 -05:00
2023-11-21 15:14:08 -05:00
this.#filename = filename;
this.dirty = false;
return this;
2023-11-13 14:46:04 -05:00
}
2023-11-21 15:14:08 -05:00
public async save() {
if (this.#filename === null) {
return;
}
const { file } = await getRuntime();
await file.saveFile(this.#filename, this.rowsToString());
this.dirty = false;
}
public insert(at: Position, c: string): void {
if (at.y === this.numRows) {
this.appendRow(c);
} else {
this.#rows[at.y].insertChar(at.x, c);
this.updateRow(this.#rows[at.y]);
}
this.dirty = true;
}
public row(i: number): Row | null {
2023-11-20 14:21:42 -05:00
return this.#rows[i] ?? null;
2023-11-13 14:46:04 -05:00
}
public appendRow(s: string): void {
const at = this.numRows;
this.#rows[at] = new Row(s);
this.updateRow(this.#rows[at]);
2023-11-21 15:14:08 -05:00
this.dirty = true;
}
private updateRow(r: Row): void {
r.render = chars(r.toString().replace('\t', ' '.repeat(TAB_SIZE)));
}
2023-11-21 15:14:08 -05:00
private rowsToString(): string {
return this.#rows.map((r) => r.toString()).join('\n');
}
2023-11-13 14:46:04 -05:00
}
export default Document;