lines
Offsets ↔ LSP positions (both count UTF-16 code units, as JS strings do).
import type { Position } from "#codebase/tcmts/cli/lsp"; export function lines(text: string) { const starts = [0]; for (let i = 0; i < text.length; i++) if (text[i] === "\n") starts.push(i + 1); const pos = (offset: number): Position => { let lo = 0; let hi = starts.length - 1; while (lo < hi) { const mid = (lo + hi + 1) >> 1; if (starts[mid]! <= offset) lo = mid; else hi = mid - 1; } return { line: lo, character: offset - starts[lo]! }; }; const offset = (p: Position) => (starts[p.line] ?? text.length) + p.character; const lineEnd = (line: number) => (starts[line + 1] ?? text.length + 1) - 1; return { pos, offset, lineEnd }; }