Skip to content

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

Open
anthhub wants to merge 2 commits into
manaflow-ai:mainfrom
anthhub:fix/sidebar-smart-path-display
Open

anthhub wants to merge 2 commits into
manaflow-ai:mainfrom
anthhub:fix/sidebar-smart-path-display

Conversation

@anthhub

@anthhub anthhub commented Mar 25, 2026 •

Copy link
Copy Markdown

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 and corrected its doc comment example; 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 988aefb. Summary will update on new commits.

Summary by CodeRabbit

  • New Features
    • Enhanced sidebar path display with smarter truncation: home directories show as ~ and long paths abbreviate to an ellipsis plus trailing segments for clearer, more readable location display.
  • Tests
    • Added unit tests covering the new truncation and tilde-handling behaviors to ensure consistent display across path varieties.

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

vercel Bot commented Mar 25, 2026

Copy link
Copy Markdown

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

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Mar 25, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f4b6f888-4872-4542-8038-d5024068726d

📥 Commits

Reviewing files that changed from the base of the PR and between e61fed2 and 988aefb.

📒 Files selected for processing (1)
  • Sources/ContentView.swift
✅ Files skipped from review due to trivial changes (1)
  • Sources/ContentView.swift

📝 Walkthrough

Walkthrough

Updated the sidebar path formatter to replace home-directory prefixes with ~ and perform smart left-side truncation: if a path has more than three display segments it returns …/<last N segments>, otherwise returns the full (or tilde-replaced) path. Added tests covering truncation and non-truncation cases.

Changes

Cohort / File(s) Summary
Path Truncation Logic
Sources/ContentView.swift
Added static let maxDisplaySegments = 3 and updated SidebarPathFormatter.shortenedPath(...) to replace home prefix with ~ and perform ellipsis-based left truncation when segment count exceeds the display limit.
Test Coverage
cmuxTests/GhosttyConfigTests.swift
Added eight XCTest cases validating: exact-segment preservation, short/home/absolute path passthrough, and ellipsis truncation behavior for longer home and absolute paths.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰
Paths once long now hop with glee,
I nibble left and keep the leafy three.
A tiny … marks what I trimmed away,
Tests ensure no crumbs led astray. 🥕

🚥 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 accurately and concisely describes the main change: smart path truncation for deeply-nested working directories in the sidebar.
Description check ✅ Passed The PR description fully covers the summary, implementation, testing approach, and includes detailed context with before/after examples and verification steps.
Linked Issues check ✅ Passed The PR implements the smart path-truncation objective from issue #2061 by keeping the last 3 segments with …/ prefix, directly addressing the primary usability complaint about indistinguishable sidebar entries.
Out of Scope Changes check ✅ Passed All changes are scoped to the smart path truncation feature: the formatter logic update, a named constant, and comprehensive unit tests covering the new behavior.

✏️ 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.

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

Copy link
Copy Markdown

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

greptile-apps Bot commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

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 thread Sources/ContentView.swift
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
Copy Markdown
Contributor

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 pushed 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.
The example showed `…/c/d` (implying 2 segments) but the constant
is 3, so the correct output is `…/b/c/d`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@teamleaderleo teamleaderleo added area: sidebar The workspace sidebar: list, groups, status, reordering S3: minor Wrong behavior with a workaround labels Sep 30, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: sidebar The workspace sidebar: list, groups, status, reordering S3: minor Wrong behavior with a workaround

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

2 participants