πŸ“„ File detail

ink/tabstops.ts

🧩 .tsπŸ“ 47 linesπŸ’Ύ 1,113 bytesπŸ“ text
← Back to All Files

🎯 Use case

This file lives under β€œink/”, which covers Ink terminal UI (layouts, TTY IO, keyboard, renderer components). On the API surface it exposes expandTabs β€” mainly functions, hooks, or classes. It composes internal code from stringWidth and termio (relative imports). What the file header says: Tab expansion, inspired by Ghostty's Tabstops.zig Uses 8-column intervals (POSIX default, hardcoded in terminals like Ghostty).

Generated from folder role, exports, dependency roots, and inline comments β€” not hand-reviewed for every path.

🧠 Inline summary

Tab expansion, inspired by Ghostty's Tabstops.zig Uses 8-column intervals (POSIX default, hardcoded in terminals like Ghostty)

πŸ“€ Exports (heuristic)

  • expandTabs

πŸ–₯️ Source preview

// Tab expansion, inspired by Ghostty's Tabstops.zig
// Uses 8-column intervals (POSIX default, hardcoded in terminals like Ghostty)

import { stringWidth } from './stringWidth.js'
import { createTokenizer } from './termio/tokenize.js'

const DEFAULT_TAB_INTERVAL = 8

export function expandTabs(
  text: string,
  interval = DEFAULT_TAB_INTERVAL,
): string {
  if (!text.includes('\t')) {
    return text
  }

  const tokenizer = createTokenizer()
  const tokens = tokenizer.feed(text)
  tokens.push(...tokenizer.flush())

  let result = ''
  let column = 0

  for (const token of tokens) {
    if (token.type === 'sequence') {
      result += token.value
    } else {
      const parts = token.value.split(/(\t|\n)/)
      for (const part of parts) {
        if (part === '\t') {
          const spaces = interval - (column % interval)
          result += ' '.repeat(spaces)
          column += spaces
        } else if (part === '\n') {
          result += part
          column = 0
        } else {
          result += part
          column += stringWidth(part)
        }
      }
    }
  }

  return result
}