From 844e9df98f50e720ca7c3b54c8065ab780ba69d8 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sat, 19 Sep 2026 15:43:45 -0700 Subject: [PATCH] fix(editor): keep long file paths distinguishable (#21631) * fix(editor): keep filename visible in long paths * fix(review): keep diff filenames visible * fix(review): prevent path metadata overlap --- src/renderer/src/assets/main.css | 23 +++++++++++++--- .../components/editor/DiffSectionHeader.tsx | 27 +++++++++++-------- .../editor/EditorPanelHeaderPath.tsx | 5 +++- .../editor/editor-path-display.test.ts | 12 +++++++++ .../components/editor/editor-path-display.ts | 10 +++++++ 5 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 src/renderer/src/components/editor/editor-path-display.test.ts create mode 100644 src/renderer/src/components/editor/editor-path-display.ts diff --git a/src/renderer/src/assets/main.css b/src/renderer/src/assets/main.css index 17d375fef04..df9c8e73397 100644 --- a/src/renderer/src/assets/main.css +++ b/src/renderer/src/assets/main.css @@ -1094,14 +1094,18 @@ html.native-shell .app-layout { .editor-header-text { min-width: 0; flex: 1; + overflow: hidden; } .editor-header-path { - display: block; + display: flex; + align-items: center; min-width: 0; - flex: 0 1 auto; + flex: 1 1 auto; padding: 0; max-width: 100%; + width: 100%; + overflow: hidden; border: none; background: transparent; color: var(--muted-foreground); @@ -1116,9 +1120,21 @@ html.native-shell .app-layout { Consolas, monospace; white-space: nowrap; + text-align: left; +} + +.path-display-prefix, +.editor-header-path-prefix { + min-width: 0; overflow: hidden; text-overflow: ellipsis; - text-align: left; + white-space: nowrap; +} + +.path-display-file, +.editor-header-path-file { + flex: 0 0 auto; + white-space: nowrap; } .editor-header-path:hover, @@ -1140,6 +1156,7 @@ html.native-shell .app-layout { align-items: center; gap: 8px; min-width: 0; + overflow: hidden; } .editor-header-copy-toast { diff --git a/src/renderer/src/components/editor/DiffSectionHeader.tsx b/src/renderer/src/components/editor/DiffSectionHeader.tsx index 9560ce6fcf3..145a29582f6 100644 --- a/src/renderer/src/components/editor/DiffSectionHeader.tsx +++ b/src/renderer/src/components/editor/DiffSectionHeader.tsx @@ -1,6 +1,7 @@ import { ChevronDown, ChevronRight, ExternalLink, Eye } from 'lucide-react' import type { MouseEvent, ReactElement, ReactNode } from 'react' import { translate } from '@/i18n/i18n' +import { splitPathForDisplay } from './editor-path-display' export function DiffSectionHeader({ path, @@ -25,16 +26,17 @@ export function DiffSectionHeader({ onOpenPreview?: (event: MouseEvent) => void trailingContent?: ReactNode }): ReactElement { + const displayPath = splitPathForDisplay(path) return (
- + { event.preventDefault() event.stopPropagation() @@ -60,16 +62,19 @@ export function DiffSectionHeader({ }} title={translate('auto.components.editor.DiffSectionHeader.8915726e93', 'Copy path')} > - {path} + {displayPath.prefix} + {displayPath.fileName} + + + {dirty && M} + {(added > 0 || removed > 0) && ( + + {added > 0 && +{added}} + {added > 0 && removed > 0 && } + {removed > 0 && -{removed}} + + )} - {dirty && M} - {(added > 0 || removed > 0) && ( - - {added > 0 && +{added}} - {added > 0 && removed > 0 && } - {removed > 0 && -{removed}} - - )}
{trailingContent} diff --git a/src/renderer/src/components/editor/EditorPanelHeaderPath.tsx b/src/renderer/src/components/editor/EditorPanelHeaderPath.tsx index eaa5db71209..0ea9e68a308 100644 --- a/src/renderer/src/components/editor/EditorPanelHeaderPath.tsx +++ b/src/renderer/src/components/editor/EditorPanelHeaderPath.tsx @@ -15,6 +15,7 @@ import type { OpenFile } from '@/store/slices/editor' import { CLOSE_ALL_CONTEXT_MENUS_EVENT } from '../tab-bar/SortableTab' import { useEditorHeaderFileRename } from './editor-header-file-rename' import { getEditorHeaderCopyState } from './editor-header' +import { splitPathForDisplay } from './editor-path-display' const isMac = navigator.userAgent.includes('Mac') const isLinux = navigator.userAgent.includes('Linux') @@ -55,6 +56,7 @@ export function EditorPanelHeaderPath({ const [pathMenuPoint, setPathMenuPoint] = useState({ x: 0, y: 0 }) const skipMenuFocusRestoreRef = useRef(false) const headerCopyState = getEditorHeaderCopyState(activeFile) + const displayPath = splitPathForDisplay(headerCopyState.pathLabel) const canCopyHeaderPath = headerCopyState.copyText !== null const isVirtualEditorTab = activeFile.mode === 'check-details' const markdownPreviewShortcutLabel = useShortcutLabel('editor.markdownPreview') @@ -124,7 +126,8 @@ export function EditorPanelHeaderPath({ disabled={!canCopyHeaderPath} title={headerCopyState.pathTitle} > - {headerCopyState.pathLabel} + {displayPath.prefix} + {displayPath.fileName} )} { + it.each([ + ['/repo/src/file.ts', { prefix: '/repo/src/', fileName: 'file.ts' }], + ['C:\\repo\\src\\file.ts', { prefix: 'C:\\repo\\src\\', fileName: 'file.ts' }], + ['file.ts', { prefix: '', fileName: 'file.ts' }] + ])('keeps the final filename separate for %s', (path, expected) => { + expect(splitPathForDisplay(path)).toEqual(expected) + }) +}) diff --git a/src/renderer/src/components/editor/editor-path-display.ts b/src/renderer/src/components/editor/editor-path-display.ts new file mode 100644 index 00000000000..11ab5b8bda8 --- /dev/null +++ b/src/renderer/src/components/editor/editor-path-display.ts @@ -0,0 +1,10 @@ +export function splitPathForDisplay(path: string): { prefix: string; fileName: string } { + const separatorIndex = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')) + if (separatorIndex < 0) { + return { prefix: '', fileName: path } + } + return { + prefix: path.slice(0, separatorIndex + 1), + fileName: path.slice(separatorIndex + 1) + } +}