106 lines
1.9 KiB
JavaScript
106 lines
1.9 KiB
JavaScript
import { SCROLL_TAB_SIZE } from './config.ts';
|
|
import * as Util from './fns.ts';
|
|
|
|
/**
|
|
* One row of text in the current document
|
|
*/
|
|
export class Row {
|
|
/**
|
|
* The actual characters in the current row
|
|
*/
|
|
chars: string[] = [];
|
|
|
|
/**
|
|
* The characters rendered for the current row
|
|
* (like replacing tabs with spaces)
|
|
*/
|
|
render: string[] = [];
|
|
|
|
private constructor(s: string | string[] = '') {
|
|
this.chars = Array.isArray(s) ? s : Util.chars(s);
|
|
this.render = [];
|
|
}
|
|
|
|
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 static default(): Row {
|
|
return new Row();
|
|
}
|
|
|
|
public static from(s: string | string[] | Row): Row {
|
|
if (s instanceof Row) {
|
|
return s;
|
|
}
|
|
|
|
return new Row(s);
|
|
}
|
|
|
|
public append(s: string): void {
|
|
this.chars = this.chars.concat(Util.chars(s));
|
|
this.updateRender();
|
|
}
|
|
|
|
public insertChar(at: number, c: string): void {
|
|
const newSlice = Util.chars(c);
|
|
if (at >= this.size) {
|
|
this.chars = this.chars.concat(newSlice);
|
|
} else {
|
|
this.chars = Util.arrayInsert(this.chars, at + 1, newSlice);
|
|
}
|
|
}
|
|
|
|
public split(at: number): Row {
|
|
const newRow = new Row(this.chars.slice(at));
|
|
this.chars = this.chars.slice(0, at);
|
|
this.updateRender();
|
|
|
|
return newRow;
|
|
}
|
|
|
|
public delete(at: number): void {
|
|
if (at >= this.size) {
|
|
return;
|
|
}
|
|
|
|
this.chars.splice(at, 1);
|
|
}
|
|
|
|
public cxToRx(cx: number): number {
|
|
let rx = 0;
|
|
let j = 0;
|
|
for (; j < cx; j++) {
|
|
if (this.chars[j] === '\t') {
|
|
rx += (SCROLL_TAB_SIZE - 1) - (rx % SCROLL_TAB_SIZE);
|
|
}
|
|
rx++;
|
|
}
|
|
|
|
return rx;
|
|
}
|
|
|
|
public toString(): string {
|
|
return this.chars.join('');
|
|
}
|
|
|
|
public updateRender(): void {
|
|
const newString = this.chars.join('').replace(
|
|
'\t',
|
|
' '.repeat(SCROLL_TAB_SIZE),
|
|
);
|
|
|
|
this.render = Util.chars(newString);
|
|
}
|
|
}
|
|
|
|
export default Row;
|