diff --git a/src/renderer/src/assets/main.css b/src/renderer/src/assets/main.css index a0d3a8d6937..082584ee5f2 100644 --- a/src/renderer/src/assets/main.css +++ b/src/renderer/src/assets/main.css @@ -1905,7 +1905,7 @@ html.native-shell .app-layout { inset: 0; z-index: 30; pointer-events: none; - background: color-mix(in srgb, var(--terminal-pane-locate) 12%, transparent); + background: color-mix(in srgb, var(--terminal-pane-locate) 6%, transparent); animation: editor-reveal-flash 1.2s ease-out forwards; } diff --git a/src/renderer/src/components/terminal-pane/terminal-file-link-editor-open.ts b/src/renderer/src/components/terminal-pane/terminal-file-link-editor-open.ts index 628a4fabcac..05d86e562d9 100644 --- a/src/renderer/src/components/terminal-pane/terminal-file-link-editor-open.ts +++ b/src/renderer/src/components/terminal-pane/terminal-file-link-editor-open.ts @@ -44,13 +44,17 @@ export function openLinkedFileInEditor( isCurrentRequest: () => boolean ): EditorOpenResult | null { const language = detectLanguage(file.filePath) + const existingViews = useAppStore.getState().unifiedTabsByWorktree?.[file.worktreeId] ?? [] // Why on shown: a layout-owner build draws a new view only with main's frame. const reveal = (shown: EditorOpenResult | null): void => { if (!shown) { return } // Why: a link to an already-active tab otherwise changes nothing on screen. - if (isCurrentRequest()) { + if ( + isCurrentRequest() && + existingViews.some((tab) => tab.id === shown.viewStateId && tab.entityId === shown.fileId) + ) { flashRevealedEditorView(shown.viewStateId) } if (position.line === null) { diff --git a/src/renderer/src/components/terminal-pane/terminal-link-open-beside-source.test.ts b/src/renderer/src/components/terminal-pane/terminal-link-open-beside-source.test.ts index 39574fa2abb..7634361f063 100644 --- a/src/renderer/src/components/terminal-pane/terminal-link-open-beside-source.test.ts +++ b/src/renderer/src/components/terminal-pane/terminal-link-open-beside-source.test.ts @@ -1,6 +1,7 @@ import { openRoutedHttpLink } from '@/lib/http-link-destinations' import * as browserLinkOpen from './terminal-file-link-browser-open' -import { describe, expect, it, vi } from 'vitest' +import * as editorRevealFlash from '@/components/tab-group/editor-reveal-flash' +import { afterEach, describe, expect, it, vi } from 'vitest' import { activateAndRevealWorkspace } from '@/lib/worktree-activation' import { openDetectedFilePath } from './terminal-link-handlers' import { createTerminalLinkTestDoubles } from './terminal-link-handlers-test-fixtures' @@ -231,6 +232,35 @@ describe('terminal file links carry their source tab', () => { }) describe('terminal file link reveals target the opened view', () => { + afterEach(() => vi.restoreAllMocks()) + + it.each([ + { existingFileId: null, flashes: false, label: 'a newly opened file' }, + { existingFileId: '/tmp/src/a.ts', flashes: true, label: 'an existing document view' }, + { existingFileId: '/tmp/src/b.ts', flashes: false, label: 'a reused preview for another file' } + ])('only flashes existing documents: $label', async ({ existingFileId, flashes }) => { + setPlatform('Macintosh') + const flash = vi + .spyOn(editorRevealFlash, 'flashRevealedEditorView') + .mockImplementation(() => {}) + if (existingFileId) { + storeState.unifiedTabsByWorktree = { + 'wt-1': [{ id: 'view:/tmp/src/a.ts', entityId: existingFileId, groupId: 'group-1' }] + } + } + + openDetectedFilePath('/tmp/src/a.ts', 12, 3, deps) + await flushAsyncWork() + await flushDoubleRaf() + + expect(flash).toHaveBeenCalledTimes(flashes ? 1 : 0) + if (flashes) { + expect(flash).toHaveBeenCalledWith('view:/tmp/src/a.ts') + } + expect(lastReveal()).toMatchObject({ viewStateId: 'view:/tmp/src/a.ts', line: 12, column: 3 }) + expect(lastReveal().canApply?.()).toBe(true) + }) + it('scopes the reveal to the returned view', async () => { setPlatform('Macintosh')