scroll/src/common/document.ts

94 lines
1.6 KiB
JavaScript
Raw Normal View History

2023-11-13 15:33:56 -05:00
import { chars } from './utils.ts';
import { getRuntime } from './runtime.ts';
import { TAB_SIZE } from './mod.ts';
2023-11-13 14:46:04 -05:00
export class Row {
chars: string[] = [];
render: string[] = [];
2023-11-13 14:46:04 -05:00
constructor(s: string = '') {
this.chars = chars(s);
this.render = [];
2023-11-13 14:46:04 -05:00
}
2023-11-20 14:21:42 -05:00
public get size(): number {
return this.chars.length;
}
public get rsize(): number {
return this.render.length;
}
public rstring(offset: number = 0): string {
return this.render.slice(offset).join('');
}
public cxToRx(cx: number): number {
let rx = 0;
let j = 0;
for (; j < cx; j++) {
if (this.chars[j] === '\t') {
rx += (TAB_SIZE - 1) - (rx % TAB_SIZE);
}
rx++;
}
return rx;
}
2023-11-13 14:46:04 -05:00
public toString(): string {
return this.chars.join('');
}
}
export class Document {
#rows: Row[];
private constructor() {
this.#rows = [];
}
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
return this;
2023-11-13 14:46:04 -05:00
}
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]);
}
private updateRow(r: Row): void {
r.render = chars(r.toString().replace('\t', ' '.repeat(TAB_SIZE)));
}
2023-11-13 14:46:04 -05:00
}
export default Document;