fix(sidebar): smart path truncation for deeply-nested cwds (#2061)#2148
fix(sidebar): smart path truncation for deeply-nested cwds (#2061)#2148anthhub wants to merge 1 commit intomanaflow-ai:mainfrom
Conversation
Sidebar surfaces sharing a long common directory prefix all truncate to identical strings (e.g. "~/Desktop/YOKE/Claude Code/Ad..."), making it impossible to tell workspaces apart. SidebarPathFormatter.shortenedPath now keeps only the last 3 path segments and prepends "…/" when a path is deeper than that threshold, so /Users/john/Desktop/YOKE/Claude Code/Projects/Athlete Merch/nilclub becomes …/Projects/Athlete Merch/nilclub. Paths with 3 or fewer segments after tilde replacement are left unchanged. Fixes manaflow-ai#2061 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@anthhub is attempting to deploy a commit to the Manaflow Team on Vercel. A member of the Team first needs to authorize it. |
📝 WalkthroughWalkthroughThe pull request implements smart path truncation in the sidebar's path formatter, replacing long directory paths with ellipsis followed by the last three path segments. It introduces a configurable Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR fixes sidebar path display for workspaces with a long shared directory prefix by adding smart left-truncation in Notable items:
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["shortenedPath(path)"] --> B["Trim whitespace"]
B --> C{trimmed == homeDir?}
C -- Yes --> D["return '~'"]
C -- No --> E{hasPrefix homeDir + '/'?}
E -- Yes --> F["tildeReplaced = '~' + suffix"]
E -- No --> G["tildeReplaced = trimmed"]
F --> H["split on '/' (omittingEmptySubsequences: false)"]
G --> H
H --> I{segments.count > maxDisplaySegments + 1?}
I -- No (≤ 4 segments) --> J["return tildeReplaced as-is"]
I -- Yes (> 4 segments) --> K["tail = last 3 segments joined by '/'"]
K --> L["return '…/' + tail"]
Reviews (1): Last reviewed commit: "fix(sidebar): smart path truncation to d..." | Re-trigger Greptile |
| /// Maximum number of path segments shown before adding a leading ellipsis. | ||
| /// e.g. `~/a/b/c/d` → `…/c/d` when maxSegments == 2. | ||
| static let maxDisplaySegments: Int = 3 |
There was a problem hiding this comment.
Doc-comment example contradicts the actual constant value
The example in the doc comment shows …/c/d which implies only 2 tail segments are kept (maxSegments == 2), but the constant below it is set to 3. With maxDisplaySegments = 3, the real output for ~/a/b/c/d is …/b/c/d (three segments), not …/c/d (two segments). The example was apparently written for a different threshold and then not updated when the constant was changed to 3.
| /// Maximum number of path segments shown before adding a leading ellipsis. | |
| /// e.g. `~/a/b/c/d` → `…/c/d` when maxSegments == 2. | |
| static let maxDisplaySegments: Int = 3 | |
| /// Maximum number of path segments shown before adding a leading ellipsis. | |
| /// e.g. `~/a/b/c/d` → `…/b/c/d` when maxDisplaySegments == 3. | |
| static let maxDisplaySegments: Int = 3 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cmuxTests/GhosttyConfigTests.swift (1)
44-119: Optional: extract a tiny assertion helper to reduce repetition.These tests are clear already, but a local helper like
assertShortenedPath(_ input: String, _ expected: String, home: String = "/Users/example")would reduce boilerplate and make future cases easier to add.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmuxTests/GhosttyConfigTests.swift` around lines 44 - 119, Add a small assertion helper to remove repetition in the tests: create a function like assertShortenedPath(_ input: String, _ expected: String, home: String = "/Users/example") that calls SidebarPathFormatter.shortenedPath(input, homeDirectoryPath: home) and XCTAssertEqual against expected, then refactor each test (e.g., testShortenedPathKeepsThreeSegmentsUnchanged, testShortenedPathTruncatesLongHomePath, testShortenedPathTruncatesFourSegmentHomePath, testShortenedPathLeavesShortHomePathUnchanged, testShortenedPathTruncatesLongAbsolutePath, testShortenedPathLeavesShortAbsolutePathUnchanged, testShortenedPathTruncatesLongAbsolutePathBeyondThree) to use this helper to pass input and expected (omit home where default applies) to reduce boilerplate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@cmuxTests/GhosttyConfigTests.swift`:
- Around line 44-119: Add a small assertion helper to remove repetition in the
tests: create a function like assertShortenedPath(_ input: String, _ expected:
String, home: String = "/Users/example") that calls
SidebarPathFormatter.shortenedPath(input, homeDirectoryPath: home) and
XCTAssertEqual against expected, then refactor each test (e.g.,
testShortenedPathKeepsThreeSegmentsUnchanged,
testShortenedPathTruncatesLongHomePath,
testShortenedPathTruncatesFourSegmentHomePath,
testShortenedPathLeavesShortHomePathUnchanged,
testShortenedPathTruncatesLongAbsolutePath,
testShortenedPathLeavesShortAbsolutePathUnchanged,
testShortenedPathTruncatesLongAbsolutePathBeyondThree) to use this helper to
pass input and expected (omit home where default applies) to reduce boilerplate.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 87c87030-0ac7-4d51-98ed-57d22cad1006
📒 Files selected for processing (2)
Sources/ContentView.swiftcmuxTests/GhosttyConfigTests.swift
…ai#2148 PR manaflow-ai#2145 inadvertently included SidebarPathFormatter maxDisplaySegments and shortenedPath truncation logic that belongs to PR manaflow-ai#2148 (sidebar path optimisation). This commit reverts ContentView.swift to origin/main for SidebarPathFormatter while keeping only the mute-related changes: TabItemView == guard, shouldMute/muteLabel vars, mute Button.
Summary
Fixes #2061
Sidebar entries for workspaces with a long shared directory prefix all truncate to identical strings, making it impossible to distinguish them:
Before
After
Implementation
SidebarPathFormatter.shortenedPathnow applies smart left-truncation after the existing~substitution:~/projects/cmuxunchanged).…/prefix is prepended (e.g.~/a/b/c/d→…/b/c/d).The threshold (
maxDisplaySegments = 3) is a named constant so it can be tuned later without a search-and-replace.This is a display-only change. No data model, settings, or socket API is affected. Both the vertical and compact branch/directory rows in
TabItemViewshare the same formatter and benefit automatically.Test plan
SidebarPathFormatterTestscover: exact 3-segment path (no truncation), 4-segment path (truncated), long home path, short home path, long absolute path, short absolute path.testShortenedPathReplacesExactHomeDirectory,testShortenedPathReplacesHomeDirectoryPrefix,testShortenedPathLeavesExternalPathUnchanged) still pass unchanged.xcodebuildon macOS.🤖 Generated with Claude Code
Summary by cubic
Improve sidebar path display by smartly truncating deep directories so similar entries stay distinguishable. Shows only the last 3 segments with a leading …/; shallow paths are unchanged.
SidebarPathFormatter.shortenedPathto left-truncate after~replacement, keeping only the last 3 segments and prefixing…/.maxDisplaySegments = 3for easy tuning; display-only change used by both sidebar layouts.Written for commit e61fed2. Summary will update on new commits.
Summary by CodeRabbit
Release Notes