Skip to content

feat(editor): recover last closed query tab draft in the next blank tab#1687

Merged
datlechin merged 2 commits into
mainfrom
worktree-recover-closed-query-draft
Jun 15, 2026
Merged

feat(editor): recover last closed query tab draft in the next blank tab#1687
datlechin merged 2 commits into
mainfrom
worktree-recover-closed-query-draft

Conversation

@datlechin

Copy link
Copy Markdown
Member

Closes #1686

Problem

Closing a query tab (Cmd+W or the close button) dropped its unsaved SQL with no way to get it back.

Root cause

Three compounding gaps:

  1. performClose cleared the window's tabs with no prior persist.
  2. The resulting structure change made saveOrClearAggregated see 0 tabs and delete the session JSON.
  3. A new query tab never read any persisted SQL, so it always started blank.

The existing TabPersistence pipeline can't hold the draft because it clears on 0 tabs, so this adds a separate per-connection store (same pattern as DatabaseTreeFilterStorage, and the iOS lastQuery.{connectionId} precedent).

Fix

ClosedTabDraftStorage persists the SQL of a closed query tab and hands it back to the next blank tab for the same connection. Silent recovery, no dialog, which matches the macOS state-restoration model for a non-document editor (and VS Code hot-exit / Postico autosave).

  • Save the draft in performClose (last-tab close) and in handleWindowWillClose (X button, closing one of several tabs), guarded by !isAppTerminating so app-quit doesn't pollute it.
  • newTab consumes the draft (read-once) into the new tab.
  • draftCandidate ignores blank, file-backed, and table tabs and prefers the selected tab. 500k cap mirrored from TabQueryContent.
  • Single last-closed slot per connection; recovered once, then cleared.

Invariants

  • The recovered non-empty query makes the tab non-reusable, so the tab-replacement guard protects it.
  • saveOrClearAggregated only touches the session JSON, never the new UserDefaults store.
  • File-backed tabs are never silently re-inserted.

Tests

ClosedTabDraftStorageTests (11 tests): round-trip, consume-once, per-connection isolation, blank/file-backed/table exclusion, selected-vs-first preference, 500k cap, clear.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f07666d21

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

from: tabManager.tabs,
selectedTabId: tabManager.selectedTabId
) {
ClosedTabDraftStorage.shared.saveQuery(draft, connectionId: connectionId)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid saving drafts during database-switch cleanup

When switching databases, switchDatabase(to:) calls closeSiblingNativeWindows(), which closes sibling native tabs via sibling.close() before clearing the current tab (MainContentCoordinator+Navigation.swift lines 373-397). Those programmatic closes now run this same windowWillClose path and save a draft keyed only by connection id, so after the switch the next blank tab for that connection can be prefilled with SQL from the previous database instead of starting blank. This defeats the database-switch cleanup and can lead users to run stale SQL in the newly selected database; suppress draft capture for those programmatic closes or include the active database in the draft scope.

Useful? React with 👍 / 👎.

@datlechin datlechin merged commit 13dbc64 into main Jun 15, 2026
4 checks passed
@datlechin datlechin deleted the worktree-recover-closed-query-draft branch June 15, 2026 15:46
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.

Warn Before Closing Query Tab with Unsaved SQL

1 participant