π File detail
ink/measure-text.ts
π― Use case
This file lives under βink/β, which covers Ink terminal UI (layouts, TTY IO, keyboard, renderer components). It primarily provides a default export (component, class, or entry function). It composes internal code from line-width-cache (relative imports). What the file header says: Single-pass measurement: computes both width and height in one iteration instead of two (widestLine + countVisualLines). Uses indexOf to avoid array allocation from split('\n').
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
Single-pass measurement: computes both width and height in one iteration instead of two (widestLine + countVisualLines). Uses indexOf to avoid array allocation from split('\n').
π€ Exports (heuristic)
default
π₯οΈ Source preview
import { lineWidth } from './line-width-cache.js'
type Output = {
width: number
height: number
}
// Single-pass measurement: computes both width and height in one
// iteration instead of two (widestLine + countVisualLines).
// Uses indexOf to avoid array allocation from split('\n').
function measureText(text: string, maxWidth: number): Output {
if (text.length === 0) {
return {
width: 0,
height: 0,
}
}
// Infinite or non-positive width means no wrapping β each line is one visual line.
// Must check before the loop since Math.ceil(w / Infinity) = 0.
const noWrap = maxWidth <= 0 || !Number.isFinite(maxWidth)
let height = 0
let width = 0
let start = 0
while (start <= text.length) {
const end = text.indexOf('\n', start)
const line = end === -1 ? text.substring(start) : text.substring(start, end)
const w = lineWidth(line)
width = Math.max(width, w)
if (noWrap) {
height++
} else {
height += w === 0 ? 1 : Math.ceil(w / maxWidth)
}
if (end === -1) break
start = end + 1
}
return { width, height }
}
export default measureText