fix(ui): truncate long file paths so +/- stats stay visible - #4
Merged
Merged
Conversation
The file list panel is 20% of terminal width. File paths were rendered at full length with the +N -N change stats appended after. Long paths simply shoved the stats off the right edge into the void, making them invisible. It turns out that rendering a path like "src/some/deeply/nested/module/thing.rs +5 -2" into a 25-column panel without any truncation is... optimistic. Truncate paths with an ellipsis to guarantee the stats suffix fits. Uses char-boundary-safe slicing (not byte indexing, because panicking on non-ASCII paths would be embarrassing), and a digit_count helper to measure stat widths without allocating throwaway format strings every frame.
It turns out the original truncation was keeping the directory prefix and chopping the filename — which is exactly backwards. Nobody cares that a path starts with "src/components/"; they care that it ends with "Button.tsx". Showing "src/components/d…" when you could show "…/deep/Button.tsx" is just not helpful. While at it, fix the edge case where max_name_width saturates to 0 or 1 — the old guard (max_name_width > 1) silently skipped truncation entirely, rendering the full name and defeating the whole point of the feature. Now we just show "…" when there's no room. Add unit tests for digit_count because it's a pure function and there's no excuse not to. Also add .DS_Store to .gitignore because apparently that wasn't done yet. Please don't commit macOS metadata files.
…lication The previous truncation logic used chars().count() to measure path widths, which is *wrong* for East Asian characters — a CJK char takes 2 display columns but counts as 1 char. Narrow your terminal enough with a Japanese directory name and the stats still get pushed off screen. Not great. Switch to unicode-width (already a transitive dep via ratatui, so this costs us exactly zero new crate downloads) for proper display column measurement. While at it, the stats width calculation and the stats span building were encoding the same format in two separate places — a classic "change one, forget the other" bug waiting to happen. Extract both into build_file_stats() which returns the spans *and* their width in one pass. The now-orphaned digit_count() goes away with it. Also replace the magic `4` with a named constant because unnamed magic numbers are how you end up debugging layout issues at 2am.
The previous commit switched truncate_path to unicode-width for correct display column measurement, but build_file_stats was still using s.len() — which is byte length, not display width. For the ASCII-only stats strings we produce today that's technically fine, but it's the kind of inconsistency that bites you later when someone changes the format and doesn't realize half the width math uses one measurement system and half uses another. Use UnicodeWidthStr::width() consistently. While at it, add unit tests for build_file_stats covering the basic cases (adds-only, dels-only, both, neither, large numbers) with a round-trip assertion that the returned width actually matches the rendered span width. The kind of test that makes future divergence impossible to miss.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
+N -Nchange stats off-screen, making them invisible…) to guarantee the stats suffix always fits within the panel widthdigit_counthelper to measure stat widths without per-frame allocationsTest plan
cargo buildpassescargo testpasses (71 tests)