Skip to content

fix(tabs): name the tab after the SQL file when opening from disk (#1220)#1448

Merged
datlechin merged 1 commit into
mainfrom
fix/1220-sql-file-tab-title
May 28, 2026
Merged

fix(tabs): name the tab after the SQL file when opening from disk (#1220)#1448
datlechin merged 1 commit into
mainfrom
fix/1220-sql-file-tab-title

Conversation

@datlechin

Copy link
Copy Markdown
Member

Fixes the follow-up reported on #1220: opening a .sql script via File > Open (or Finder, or open file.sql) named the tab "SQL Query" instead of the file name.

Root cause

The CLAUDE.md "Window tab titles" invariant calls out two resolution sites that must stay in sync. They were out of sync for the file case:

  • MainSplitViewController.init's title cascade had branches for tabTitle, tableName, and the connection language fallback, but no branch for payload.sourceFileURL. A file-open payload fell through to "{language} Query".
  • updateWindowTitleAndFileState() did have a sourceFileURL branch, but it only runs on onChange(of: selectedTabId) / structure-change. Neither fires on the first frame of a newly opened window whose single tab was populated inside init (SwiftUI sees the value already set; no change to observe). So the wrong title stuck.

Favorites and table tabs worked because they pass tabTitle / tableName explicitly. TabRouter.openSQLFile did not.

Fix

  • Add the missing sourceFileURL branch to the resolution cascade, so all file-open paths get a correct title at first frame, not just TabRouter.openSQLFile.
  • Extract the cascade into a pure static func MainSplitViewController.resolveDefaultTitle(payload:queryLanguageName:) so the invariant is now covered by unit tests, not just careful reading.
  • Unify the three drifting derivations onto a shared QueryTab.fileDisplayTitle(for:) helper that wraps FileManager.default.displayName(atPath:). This is the native API NSDocument / TextEdit / Xcode use; it respects the user's "Show all filename extensions" Finder preference, unlike the hand-rolled url.deletingPathExtension().lastPathComponent it replaces.
  • Localize the language fallback in the init cascade (String(format: String(localized: "%@ Query"), …)), matching what updateWindowTitleAndFileState already does. The init path was the only place still using "\(langName) Query" literal interpolation.

Tests

  • New TableProTests/Services/MainSplitViewControllerTitleTests.swift covers every branch of resolveDefaultTitle, the QueryTab.fileDisplayTitle helper, and QueryTabManager.addTab with sourceFileURL. The key regression test asserts a sourceFileURL payload no longer resolves to "PostgreSQL Query" or "SQL Query".
  • EditorTabPayloadTests.initFromQueryTab now asserts payload.tabTitle == tab.title (the gap that would let a restore-path regression slip through), and a new test covers file-backed tab round-trip.

Considered and rejected

The simpler "remove the intent == .newEmptyTab guard so the init reads the created tab's title for all intents" approach would make table tabs in non-default schemas show auth.users on the first frame and then flip to bare users after a tab switch, because updateWindowTitleAndFileState uses tableContext.tableName, not tab.title. The explicit sourceFileURL branch changes no other tab type's behavior.

@datlechin datlechin force-pushed the fix/1220-sql-file-tab-title branch from 4620715 to 08eb10e Compare May 28, 2026 05:14
@datlechin datlechin merged commit 693c01e into main May 28, 2026
1 check passed
@datlechin datlechin deleted the fix/1220-sql-file-tab-title branch May 28, 2026 05:14
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.

1 participant