/** * A span of source text, half-open. * * `end` is one past the last character, so `text.slice(start, end)` is exactly the text the * region selects, an empty region is `start === end`, and two adjacent regions share a number * rather than straddling one. An empty region is what a cursor between two characters is. * * Offsets are indices into the JavaScript string, which are UTF-16 code units. Nothing converts * them, because no consumer wants them converted: the Language Server Protocol's default * `positionEncoding` is UTF-16, Monaco measures columns in UTF-16 code units, and CodeMirror * addresses its document by the same offsets. The Python library counts code points instead, * because Python string indices are code points; the two agree for every character below the * astral planes and differ for anything above them, which in practice means an emoji in a * comment. That divergence is registered rather than papered over. */ export interface Region { /** Offset of the first character, into the source string. */ readonly start: number; /** Offset one past the last character. */ readonly end: number; } /** * A position as a human reads it, derived from an offset rather than stored. * * Storing line and column on every region would double its size to hold two numbers that are a * function of one. Both count from one, which is what the existing findings already report; a * consumer whose own convention counts a column from zero subtracts one, and that subtraction is * the consumer's, because a service that guessed which convention its caller wanted would be * modelling a protocol. */ export interface LineColumn { /** 1-based, counting from the start of the text. */ readonly line: number; /** 1-based, in UTF-16 code units, from the start of the line. */ readonly column: number; } /** * The minimum a position query needs: the text its offsets index into. * * Declared structurally rather than by importing `SyntaxLayer`, so that positions stay usable * without one and this module depends on nothing. A `SyntaxLayer` holds its text and therefore * satisfies this, which is what lets `lineColumnAt(layer, offset)` read as the contract writes it. */ export interface TextSource { /** The text offsets are measured into. */ readonly text: string; } /** * The line and column an offset falls on. * * Binary search over the line index, so a query costs the logarithm of the line count rather than * a scan of the text. An offset outside `[0, text.length]` is clamped into range rather than * throwing: a cursor arrives from an editor that may be a keystroke ahead of the text this layer * was built from, and refusing to answer is worse than answering about the nearest character. * * The column of a *statement* is the column of its first non-blank character, not of the * whitespace indenting it. This function does not enforce that rule, because a statement's region * already starts at that character; it is stated here because every column this feature reports * obeys it, and because the conformance corpus compares findings on their line and type name and * would notice the number moving. */ export declare function lineColumnAt(source: TextSource, offset: number): LineColumn; /** * The offset a line and column names. * * The inverse of {@link lineColumnAt} for every position that exists, and clamped for every one * that does not: a line past the end resolves on the last line, a column past the end of its line * resolves at the line's last position, which is the offset of the break that ends it. Round * tripping an out-of-range position therefore returns the clamped position rather than the one * asked for, which is the only honest answer available. */ export declare function offsetAt(source: TextSource, position: LineColumn): number; //# sourceMappingURL=region.d.ts.map