import { BlockFile } from './blockFile'; /** * The visible-screen model for file-backed sessions, ported from * less's position.c + forwback.c: the view is a position INSIDE the * file where the screen starts, and movement walks rows from there — * no global line index exists. */ export interface ViewTop { /** Line-start byte position of the top line. */ pos: number; /** * Where in that line the screen starts, as a display-character * offset — the same space the layout's rowStart indexes. * * less's table[TOP] is a BYTE and forw_line wraps from THERE, so the * top is a PLACE in the line, never an index into a wrapping that * something else may recompute differently. A sub-row index goes * stale the moment an option reshapes how the line breaks (-r, -S, * --wordwrap, a width change); a place cannot. */ offset: number; } /** A line's display text: the normal content transform per line. */ export declare function displayText(raw: string): string; export declare class BigView { readonly bf: BlockFile; /** * Where the screen starts. A jump names its own offset (0, or the * row it means); a scroll walks it. There is no shift to keep or * drop on the side, so the two cannot disagree. */ top: ViewTop; /** True once the view shows the last line's end, like mode.EOF. */ atEof: boolean; constructor(bf: BlockFile); private layoutOf; /** Display-character length of a line, its one past-the-end offset. */ lineLength(text: string): number; /** * Where the row starting at `offset` ends, like forw_line reading * from table[TOP]: whatever fits from THAT place. A result at or * past the line's length means the line is finished. * * Chopped lines are one row however long they are, so the answer is * always the whole line - less's fits_on_screen never gets asked. */ rowEnd(text: string, offset: number): number; /** * The next row's offset, or null when this row ends the line. */ nextRowOffset(text: string, offset: number): number | null; /** less's back_line, on this line's display text (see screenOps). */ rowStartBelow(text: string, offset: number): number; /** The offset of the line's last display row. */ lastRowStart(text: string): number; /** The offset a given wrap sub-row begins at. */ rowOffset(text: string, subRow: number): number; /** The wrap sub-row an offset falls in, for the renderer's index. */ subRowAt(text: string, offset: number): number; /** Display sub-rows a line occupies under the current mode. */ rowsOf(text: string): number; /** * Materializes the visible screen, like less filling the position * table: returns the raw line texts with their positions/offsets, * exactly `count` display rows unless the file ends first. * * Never more than that. sync() used to ask for three windows and * keep the extra as read-ahead, which bought nothing the tests can * see and cost a line read per row nobody would look at - on a file * whose next line was a terabyte away, seventeen minutes of it. less * has no read-ahead: its position table is exactly sc_height. * * @param onSlow - Called with the rows already gathered when the * next one turns out to need an unbounded read, so they can reach * the screen before the wait. */ visible(count: number, onSlow?: (rows: { text: string; }[]) => void): { rows: { text: string; pos: number; subRow: number; offset: number; }[]; endPos: number; }; /** * The position shown at a screen row, like less's position(): row k * counted from the top of the window, the end-of-file position * just past the last line, or null beyond that on a short screen. */ screenPos(k: number): ViewTop | null; /** * The top whose screen bottoms at the last line — less's jump_forw * anchor: plain forward moves never pass it (forward() finds * nothing to read past the eof and rings the bell instead). */ endTop(window: number): ViewTop; /** * less's position(BOTTOM_PLUS_ONE): whether a row exists just past the * screen's bottom. forward() bells when it does not (forwback.c:481) * and forw() stops as soon as a read hits EOF unless the move is * forced (bc798f8 cut that test down to `ABORT_SIGS() || !force`). * * That question is asked on the CURRENT top's own grid. An anchor * walked back from the file's END instead answers on the absolute * grid, and from a top part-way into a row the two disagree by one * row - which is exactly how far past less's eof bell we used to go. */ private hasRowPastBottom; /** Scrolls forward n display rows, like forw(): a plain move * stops once the bottom row ends the file (less's eof bell spot); a * FORCED move (J, ESC-SPACE) passes window as undefined and runs on * until the last line reaches the top, like less's force=TRUE. */ lineForward(n: number, window?: number): number; /** Scrolls backward n display rows, like back(). */ lineBackward(n: number): number; /** Jumps to the first line, like jump_back(1). */ gotoStart(): void; /** * Jumps so the last line sits on the bottom row, like jump_forw: * walk back window-1 display rows from the last line's last row. */ gotoEnd(window: number): void; /** * Jumps to a byte percentage of the file, snapped back to a line * start, like less's jump_percent over find_pos. */ gotoPercent(percent: number): void; /** Jumps to an absolute byte position's line, like jump_line_loc. */ gotoPos(pos: number): void; }