Skip to content

fix(sidebar): smart path truncation for deeply-nested cwds (#2061)#2148

Open
anthhub wants to merge 1 commit intomanaflow-ai:mainfrom
anthhub:fix/sidebar-smart-path-display
Open

fix(sidebar): smart path truncation for deeply-nested cwds (#2061)#2148
anthhub wants to merge 1 commit intomanaflow-ai:mainfrom
anthhub:fix/sidebar-smart-path-display

Conversation

@anthhub
Copy link
Contributor

@anthhub anthhub commented Mar 25, 2026

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

~/Desktop/YOKE/Claude Code/Ad...
~/Desktop/YOKE/Claude Code/Ad...
~/Desktop/YOKE/Claude Code/Ad...

After

…/Athlete Merch/nilclub
…/Cartoon Gen Gating/nilclub
…/Sport Routing Admin/nilclub

Implementation

SidebarPathFormatter.shortenedPath now applies smart left-truncation after the existing ~ substitution:

  • If the resulting path has 3 or fewer segments, it is displayed as-is (e.g. ~/projects/cmux unchanged).
  • If it has more than 3 segments, only the last 3 are kept and a …/ 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 TabItemView share the same formatter and benefit automatically.

Test plan

  • New unit tests in SidebarPathFormatterTests cover: exact 3-segment path (no truncation), 4-segment path (truncated), long home path, short home path, long absolute path, short absolute path.
  • Existing tests (testShortenedPathReplacesExactHomeDirectory, testShortenedPathReplacesHomeDirectoryPrefix, testShortenedPathLeavesExternalPathUnchanged) still pass unchanged.
  • Build succeeds with xcodebuild on 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.

  • Bug Fixes
    • Updated SidebarPathFormatter.shortenedPath to left-truncate after ~ replacement, keeping only the last 3 segments and prefixing …/.
    • Added maxDisplaySegments = 3 for easy tuning; display-only change used by both sidebar layouts.
    • Added unit tests for 3- vs 4-segment paths, home vs absolute, and long vs short paths.

Written for commit e61fed2. Summary will update on new commits.

Summary by CodeRabbit

Release Notes

  • New Features
    • Enhanced sidebar path display with smarter truncation. Long directory paths now abbreviate gracefully, displaying only the final segments with an ellipsis indicator rather than full paths. Home directories are shown as tilde (~), improving readability and interface clarity while preserving essential location information.

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>
@vercel
Copy link

vercel bot commented Mar 25, 2026

@anthhub is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

The 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 maxDisplaySegments constant and adds comprehensive test coverage for both home-directory and absolute paths.

Changes

Cohort / File(s) Summary
Path Truncation Logic
Sources/ContentView.swift
Added maxDisplaySegments constant and updated shortenedPath() to intelligently truncate paths that exceed the segment limit, using ellipsis (…/) prefix while preserving the trailing directory segments.
Test Coverage
cmuxTests/GhosttyConfigTests.swift
Added eight XCTest cases covering smart truncation behavior: exact segment preservation, short path handling, and ellipsis-based truncation for both home-directory and absolute paths exceeding the limit.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Paths were long and all the same,
Till smart truncation came to claim,
Three segments shown with before,
The sidebar's usability soars!
Eight tests ensure the logic's right,
Distinguishing tabs by last-mile sight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: implementing smart path truncation for deeply-nested current working directories in the sidebar.
Description check ✅ Passed The description provides a clear summary of the change with before/after examples, detailed implementation notes, and a comprehensive test plan.
Linked Issues check ✅ Passed The PR successfully implements the smart path truncation objective from issue #2061, keeping the last 3 path segments with a leading ellipsis prefix to distinguish sidebar entries with shared long directory prefixes.
Out of Scope Changes check ✅ Passed All changes are directly in scope: updates to SidebarPathFormatter.shortenedPath for smart truncation and corresponding unit tests; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

@greptile-apps
Copy link

greptile-apps bot commented Mar 25, 2026

Greptile Summary

This PR fixes sidebar path display for workspaces with a long shared directory prefix by adding smart left-truncation in SidebarPathFormatter.shortenedPath — paths with more than 3 segments are trimmed to …/<last-3-segments>, making deeply-nested entries distinguishable at a glance. The change is display-only and the new unit tests thoroughly cover the boundary conditions.

Notable items:

  • The logic and tests are correct; all seven new test cases match the expected behavior.
  • The doc-comment example on maxDisplaySegments references maxSegments == 2 / …/c/d, but the constant is set to 3, which produces …/b/c/d. A one-line correction would remove the mismatch.
  • Per the regression test commit policy in CLAUDE.md, bug-fix regression tests should land in a separate commit (test fails first, then the fix commit turns it green). This PR bundles both in a single commit, so the two-step CI verification is missing.

Confidence Score: 4/5

  • Safe to merge after correcting the misleading doc-comment example; no logic or data bugs.
  • The truncation logic is correct and fully covered by tests. The only actionable fix is a one-line doc-comment correction (the example shows maxSegments == 2 / …/c/d but the constant is 3 / …/b/c/d). A process note about the missing two-commit CI structure is worth addressing in future PRs but does not block this one.
  • Sources/ContentView.swift — doc-comment example for maxDisplaySegments needs updating.

Important Files Changed

Filename Overview
Sources/ContentView.swift Adds smart left-truncation to SidebarPathFormatter.shortenedPath. Logic is correct and verified by tests, but the doc-comment example for maxDisplaySegments references maxSegments == 2 / …/c/d while the constant is 3 (producing …/b/c/d).
cmuxTests/GhosttyConfigTests.swift Adds seven new unit tests covering exact-threshold, over-threshold, home-prefix, and absolute-path cases. All test expectations match the implemented logic.

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"]
Loading

Reviews (1): Last reviewed commit: "fix(sidebar): smart path truncation to d..." | Re-trigger Greptile

Comment on lines +10858 to +10860
/// 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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 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.

Suggested change
/// 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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 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

📥 Commits

Reviewing files that changed from the base of the PR and between 99ca3c9 and e61fed2.

📒 Files selected for processing (2)
  • Sources/ContentView.swift
  • cmuxTests/GhosttyConfigTests.swift

anthhub added a commit to anthhub/cmux that referenced this pull request Mar 25, 2026
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sidebar: show tab title or smart path truncation instead of full cwd

1 participant