Added
- Vim keybindings for SQL editor (Normal/Insert/Visual modes, motions, operators, :w/:q commands) with toggle in Editor Settings
^and_motions (first non-blank character) in Vim normal, visual, and operator-pending modes:qcommand to close current tab in Vim command-line mode- PostgreSQL schema switching via ⌘K database switcher (browse and switch between schemas like
public,auth, custom schemas)
Changed
- Convert QueryHistoryStorage and QueryHistoryManager from callback-based async dispatch to native Swift async/await — eliminates double thread hops per history operation
- Consolidate ExportService @published properties into single state struct — reduces objectWillChange events from 7 per batch to 1
- Consolidate ImportService @published properties into single state struct — reduces objectWillChange events during SQL import
- Replace DispatchQueue.main.asyncAfter chains in AppDelegate startup with structured Task-based retry loops
- Merge 3 identical Combine notification subscriptions in SidebarViewModel into Publishers.Merge3
- Make AIChatStorage encoder/decoder static — shared across all instances instead of duplicated
Fixed
- Cell edit showing modified background but displaying original value until save (reloadData during active editing ignored by NSTableView, updateNSView blocked by editedRow guard)
- Undo on inserted row cell edit not syncing insertedRowData (stale values after undo)
- Vim Escape key not exiting Insert/Visual mode when autocomplete popup is visible (popup's event monitor consumed the key)
- Copy (Cmd+C) and Cut (Cmd+X) not working in SQL editor — clipboard retained old value due to CodeEditTextView's copy: silently failing
- Vim yank/delete operations not syncing to system clipboard (register only stored text internally)
- Vim word motions (
w,b,e) using two-class word boundary detection instead of correct three-class (word chars, punctuation, whitespace) - Vim visual mode selection now correctly includes cursor character (inclusive selection matching real Vim behavior)
- Arrow keys now work in Vim visual/normal mode (mapped to h/j/k/l instead of bypassing the Vim engine)
- Vim block cursor now follows the moving end of the selection in visual mode instead of staying at the anchor
- Vim visual mode selection highlight now renders visibly (trigger needsDisplay after programmatic selection)
- Fix event monitor leaks in SQL editor —
deinitnow cleans up NSEvent monitors, notification observers, and work items that leaked when CodeEditSourceEditor never calleddestroy() - Fix unbounded memory growth from NativeTabRegistry holding full QueryTab objects (including RowBuffer references) — registry now stores lightweight TabSnapshot structs
- Fix SortedRowsCache storing full row copies — now stores index permutations only, halving sorted-tab memory
- Fix schema provider memory leak — shared providers are now reference-counted with 5s grace period removal when all windows for a connection close
- Fix duplicate schema fetches in InlineSuggestionManager — now shares the coordinator's SQLSchemaProvider instead of maintaining a separate cache
- Fix background tabs retaining full result data indefinitely — RowBuffer eviction frees memory for inactive tabs (re-fetched on switch back)
- Fix InMemoryRowProvider bulk cache eviction — now uses proximity-based eviction keeping entries near current scroll position
- Fix stale tabRowProviders entries when tab IDs change without count changing
- Fix crash on macOS 14.x caused by
_strchrnulsymbol not found in libpq.5.dylib — switch libpq and OpenSSL from dynamic Homebrew linking to vendored static libraries built with MACOSX_DEPLOYMENT_TARGET=14.0 - Fix duplicate tabs and lag when inserting SQL from AI Chat or History panel with multiple window-tabs open — notification handlers now only fire in the key window
- Fix "Run in New Tab" race condition in History panel — replaced fragile two-notification + 100ms delay pattern with a single atomic notification
- Fix MainContentCoordinator deinit Task that may never execute — added explicit teardown() method with didTeardown guard and orphaned schema provider purge
- Fix SQLEditorCoordinator deinit deferring InlineSuggestionManager cleanup to Task — added explicit destroy() lifecycle and didDestroy guard with warning log
- Fix ExportService while-true batch loops not checking Task.isCancelled — cancelled exports now stop promptly instead of running all remaining batches
- Fix DataGridView full column reconfiguration on every resultVersion bump — narrowed rebuild condition to only trigger when transitioning from empty state
- Fix ConnectionHealthMonitor fixed 30s interval that delays failure detection — added checkNow() with wakeUpContinuation for immediate health checks and exponential backoff
- Fix HistoryPanelView and TableStructureView asyncAfter copy-reset timers not cancellable — replaced with cancellable Task pattern
- Fix MainContentView redundant onChange handler causing cascading re-renders on tab/table changes
- Fix DatabaseManager notification observer creating unnecessary Tasks when self is already deallocated — added guard let self before Task creation