lines

tcmts.cli.lsp.lines · #bg5ixkum · term · runs anywhere

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 };
}

uses

used by