Files
claude-code-mirror/claude-code源码-中文注释/src/ink/wrap-text.ts
2026-04-03 13:01:19 +08:00

75 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import sliceAnsi from '../utils/sliceAnsi.js'
import { stringWidth } from './stringWidth.js'
import type { Styles } from './styles.js'
import { wrapAnsi } from './wrapAnsi.js'
const ELLIPSIS = '…'
// sliceAnsi 可能包含跨越边界的多宽字符(例如 CJK 在位置
// end-1 宽度 2 超出 1。重试一次更紧的边界。
function sliceFit(text: string, start: number, end: number): string {
const s = sliceAnsi(text, start, end)
return stringWidth(s) > end - start ? sliceAnsi(text, start, end - 1) : s
}
function truncate(
text: string,
columns: number,
position: 'start' | 'middle' | 'end',
): string {
if (columns < 1) return ''
if (columns === 1) return ELLIPSIS
const length = stringWidth(text)
if (length <= columns) return text
if (position === 'start') {
return ELLIPSIS + sliceFit(text, length - columns + 1, length)
}
if (position === 'middle') {
const half = Math.floor(columns / 2)
return (
sliceFit(text, 0, half) +
ELLIPSIS +
sliceFit(text, length - (columns - half) + 1, length)
)
}
return sliceFit(text, 0, columns - 1) + ELLIPSIS
}
export default function wrapText(
text: string,
maxWidth: number,
wrapType: Styles['textWrap'],
): string {
if (wrapType === 'wrap') {
return wrapAnsi(text, maxWidth, {
trim: false,
hard: true,
})
}
if (wrapType === 'wrap-trim') {
return wrapAnsi(text, maxWidth, {
trim: true,
hard: true,
})
}
if (wrapType!.startsWith('truncate')) {
let position: 'end' | 'middle' | 'start' = 'end'
if (wrapType === 'truncate-middle') {
position = 'middle'
}
if (wrapType === 'truncate-start') {
position = 'start'
}
return truncate(text, maxWidth, position)
}
return text
}