source dump of claude code
at main 46 lines 1.1 kB view raw
1// Tab expansion, inspired by Ghostty's Tabstops.zig 2// Uses 8-column intervals (POSIX default, hardcoded in terminals like Ghostty) 3 4import { stringWidth } from './stringWidth.js' 5import { createTokenizer } from './termio/tokenize.js' 6 7const DEFAULT_TAB_INTERVAL = 8 8 9export function expandTabs( 10 text: string, 11 interval = DEFAULT_TAB_INTERVAL, 12): string { 13 if (!text.includes('\t')) { 14 return text 15 } 16 17 const tokenizer = createTokenizer() 18 const tokens = tokenizer.feed(text) 19 tokens.push(...tokenizer.flush()) 20 21 let result = '' 22 let column = 0 23 24 for (const token of tokens) { 25 if (token.type === 'sequence') { 26 result += token.value 27 } else { 28 const parts = token.value.split(/(\t|\n)/) 29 for (const part of parts) { 30 if (part === '\t') { 31 const spaces = interval - (column % interval) 32 result += ' '.repeat(spaces) 33 column += spaces 34 } else if (part === '\n') { 35 result += part 36 column = 0 37 } else { 38 result += part 39 column += stringWidth(part) 40 } 41 } 42 } 43 } 44 45 return result 46}