truncatePath function
Truncate a path in the middle if too long (width-aware).
Implementation
String truncatePath(String path, int maxLength) {
if (path.length <= maxLength) return path;
const separator = '/';
const ellipsis = '\u2026';
const ellipsisWidth = 1;
const separatorWidth = 1;
final parts = path.split(separator);
final first = parts.first;
final last = parts.last;
if (parts.length == 1) {
if (path.length <= maxLength) return path;
return '${path.substring(0, maxLength - 1)}$ellipsis';
}
if (first.isEmpty &&
ellipsisWidth + separatorWidth + last.length >= maxLength) {
final truncLen = math.max(1, maxLength - separatorWidth);
return '$separator${last.length <= truncLen ? last : '${last.substring(0, truncLen - 1)}$ellipsis'}';
}
if (first.isNotEmpty &&
ellipsisWidth * 2 + separatorWidth + last.length >= maxLength) {
final truncLen = math.max(1, maxLength - ellipsisWidth - separatorWidth);
return '$ellipsis$separator${last.length <= truncLen ? last : '${last.substring(0, truncLen - 1)}$ellipsis'}';
}
if (parts.length == 2) {
final availableForFirst =
maxLength - ellipsisWidth - separatorWidth - last.length;
final truncFirst = availableForFirst > 0 && availableForFirst < first.length
? first.substring(0, availableForFirst)
: first;
return '$truncFirst$ellipsis$separator$last';
}
var available =
maxLength -
first.length -
last.length -
ellipsisWidth -
2 * separatorWidth;
if (available <= 0) {
final availableForFirst = math.max(
0,
maxLength - last.length - ellipsisWidth - 2 * separatorWidth,
);
final truncFirst = availableForFirst < first.length && availableForFirst > 0
? first.substring(0, availableForFirst)
: first;
return '$truncFirst$separator$ellipsis$separator$last';
}
final middleParts = <String>[];
for (var i = parts.length - 2; i > 0; i--) {
final part = parts[i];
if (part.length + separatorWidth <= available) {
middleParts.insert(0, part);
available -= part.length + separatorWidth;
} else {
break;
}
}
if (middleParts.isEmpty) {
return '$first$separator$ellipsis$separator$last';
}
return '$first$separator$ellipsis$separator${middleParts.join(separator)}$separator$last';
}