diff --git a/CHANGELOG.md b/CHANGELOG.md index 77ddab9c..88b816a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix AI chat hanging the app during streaming, schema fetch, and conversation loading (#735) - SSH Agent auth: fall back to key file from `~/.ssh/config` or default paths when agent has no loaded identities (#729) +- Wire AI Explain (⌘L), Optimize (⌘⌥L), and Toggle Sidebar (⌘0) shortcuts to menu bar commands +- Keyboard shortcuts follow macOS HIG — remap Quick Switcher to ⌘⇧O, Format Query to ⌘⇧L, fix stale tooltip hints - SSH-tunneled connections failing to reconnect after idle/sleep — health monitor now rebuilds the tunnel, OS-level TCP keepalive detects dead NAT mappings, and wake-from-sleep triggers immediate validation (#736) - Composite primary key tables: editing or deleting a row affects all rows sharing the first PK value instead of just the target row - Structure view saves bypass safe mode on read-only connections diff --git a/TablePro/Models/UI/KeyboardShortcutModels.swift b/TablePro/Models/UI/KeyboardShortcutModels.swift index eb554f31..54ef8822 100644 --- a/TablePro/Models/UI/KeyboardShortcutModels.swift +++ b/TablePro/Models/UI/KeyboardShortcutModels.swift @@ -365,6 +365,9 @@ struct KeyCombo: Codable, Equatable, Hashable { KeyCombo(key: "3", command: true, shift: true), // Screenshot full KeyCombo(key: "4", command: true, shift: true), // Screenshot area KeyCombo(key: "5", command: true, shift: true), // Screenshot options + KeyCombo(key: "q", command: true, control: true), // Lock Screen + KeyCombo(key: "f", command: true, control: true), // Full Screen + KeyCombo(key: "d", command: true, option: true), // Toggle Dock ] /// Check if this combo is reserved by the system @@ -461,10 +464,10 @@ struct KeyboardSettings: Codable, Equatable { .closeTab: KeyCombo(key: "w", command: true), .refresh: KeyCombo(key: "r", command: true), .explainQuery: KeyCombo(key: "e", command: true, option: true), - .formatQuery: KeyCombo(key: "f", command: true, option: true), + .formatQuery: KeyCombo(key: "l", command: true, shift: true), .export: KeyCombo(key: "e", command: true, shift: true), .importData: KeyCombo(key: "i", command: true, shift: true), - .quickSwitcher: KeyCombo(key: "p", command: true), + .quickSwitcher: KeyCombo(key: "o", command: true, shift: true), .previousPage: KeyCombo(key: "[", command: true), .nextPage: KeyCombo(key: "]", command: true), diff --git a/TablePro/TableProApp.swift b/TablePro/TableProApp.swift index 99cdc9e2..838e2e34 100644 --- a/TablePro/TableProApp.swift +++ b/TablePro/TableProApp.swift @@ -277,6 +277,20 @@ struct AppMenuCommands: Commands { Divider() + Button(String(localized: "Explain with AI")) { + actions?.aiExplainQuery() + } + .optionalKeyboardShortcut(shortcut(for: .aiExplainQuery)) + .disabled(!(actions?.isConnected ?? false) || !(actions?.hasQueryText ?? false)) + + Button(String(localized: "Optimize with AI")) { + actions?.aiOptimizeQuery() + } + .optionalKeyboardShortcut(shortcut(for: .aiOptimizeQuery)) + .disabled(!(actions?.isConnected ?? false) || !(actions?.hasQueryText ?? false)) + + Divider() + Button(String(localized: "Preview FK Reference")) { actions?.previewFKReference() } @@ -351,6 +365,11 @@ struct AppMenuCommands: Commands { // View menu CommandGroup(after: .sidebar) { + Button(String(localized: "Toggle Sidebar")) { + NSApp.sendAction(#selector(NSSplitViewController.toggleSidebar(_:)), to: nil, from: nil) + } + .optionalKeyboardShortcut(shortcut(for: .toggleTableBrowser)) + Button("Toggle Inspector") { actions?.toggleRightSidebar() } diff --git a/TablePro/Views/Editor/QueryEditorView.swift b/TablePro/Views/Editor/QueryEditorView.swift index 13d4d04d..02f0b44e 100644 --- a/TablePro/Views/Editor/QueryEditorView.swift +++ b/TablePro/Views/Editor/QueryEditorView.swift @@ -92,7 +92,7 @@ struct QueryEditorView: View { .frame(width: 24, height: 24) } .buttonStyle(.borderless) - .help(String(localized: "Format Query (⌥⌘F)")) + .help(String(localized: "Format Query (⇧⌘L)")) .optionalKeyboardShortcut(AppSettingsManager.shared.keyboard.keyboardShortcut(for: .formatQuery)) Divider() diff --git a/TablePro/Views/Main/Child/MainStatusBarView.swift b/TablePro/Views/Main/Child/MainStatusBarView.swift index 5adb8767..ea7362ee 100644 --- a/TablePro/Views/Main/Child/MainStatusBarView.swift +++ b/TablePro/Views/Main/Child/MainStatusBarView.swift @@ -114,7 +114,7 @@ struct MainStatusBarView: View { } .toggleStyle(.button) .controlSize(.small) - .help(String(localized: "Toggle Filters (⌘F)")) + .help(String(localized: "Toggle Filters (⇧⌘F)")) } // Pagination controls for table tabs diff --git a/TablePro/Views/Main/MainContentCommandActions.swift b/TablePro/Views/Main/MainContentCommandActions.swift index c21a4e4d..3254a4fe 100644 --- a/TablePro/Views/Main/MainContentCommandActions.swift +++ b/TablePro/Views/Main/MainContentCommandActions.swift @@ -576,6 +576,18 @@ final class MainContentCommandActions { coordinator?.runExplainQuery() } + func aiExplainQuery() { + guard let query = coordinator?.tabManager.selectedTab?.query, !query.isEmpty else { return } + coordinator?.showAIChatPanel() + coordinator?.aiViewModel?.handleExplainSelection(query) + } + + func aiOptimizeQuery() { + guard let query = coordinator?.tabManager.selectedTab?.query, !query.isEmpty else { return } + coordinator?.showAIChatPanel() + coordinator?.aiViewModel?.handleOptimizeSelection(query) + } + func previewFKReference() { coordinator?.toggleFKPreviewForFocusedCell() } diff --git a/TablePro/Views/Toolbar/TableProToolbarView.swift b/TablePro/Views/Toolbar/TableProToolbarView.swift index 57f522ac..098f3137 100644 --- a/TablePro/Views/Toolbar/TableProToolbarView.swift +++ b/TablePro/Views/Toolbar/TableProToolbarView.swift @@ -125,7 +125,7 @@ struct TableProToolbar: ViewModifier { } label: { Label("Quick Switcher", systemImage: "magnifyingglass") } - .help(String(localized: "Quick Switcher (⌘P)")) + .help(String(localized: "Quick Switcher (⇧⌘O)")) .disabled(state.connectionState != .connected) Button { @@ -142,7 +142,7 @@ struct TableProToolbar: ViewModifier { } label: { Label("Filters", systemImage: "line.3.horizontal.decrease.circle") } - .help(String(localized: "Toggle Filters (⌘F)")) + .help(String(localized: "Toggle Filters (⇧⌘F)")) .disabled(state.connectionState != .connected || !state.isTableTab) } diff --git a/docs/features/keyboard-shortcuts.mdx b/docs/features/keyboard-shortcuts.mdx index 44fb2d1a..d96c2311 100644 --- a/docs/features/keyboard-shortcuts.mdx +++ b/docs/features/keyboard-shortcuts.mdx @@ -17,7 +17,7 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut | New connection | `Cmd+N` | | Open history | `Cmd+Y` | | Settings | `Cmd+,` | -| Quick Switcher | `Cmd+P` | +| Quick Switcher | `Cmd+Shift+O` | | Close window | `Cmd+W` | | Quit | `Cmd+Q` | @@ -37,7 +37,7 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut |--------|----------|-------------| | Execute query | `Cmd+Enter` | Run query at cursor, or all selected statements sequentially | | Explain query | `Option+Cmd+E` | Show execution plan for query at cursor | -| Format SQL | `Option+Cmd+F` | Format SQL query | +| Format SQL | `Cmd+Shift+L` | Format SQL query | ### Text Editing @@ -77,7 +77,7 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut | Action | Shortcut | |--------|----------| -| Select word | `Cmd+D` | +| Duplicate line | `Cmd+D` | | Expand selection | `Cmd+Shift+Right` | | Shrink selection | `Cmd+Shift+Left` | @@ -101,7 +101,7 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut | Action | Shortcut | |--------|----------| -| Edit cell | `Enter` or `F2` | +| Edit cell | `Enter` | | Preview FK reference | `Space` | | Cancel edit | `Escape` | | Add row | `Cmd+Shift+N` | @@ -134,7 +134,7 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut | Action | Shortcut | |--------|----------| | Copy selection | `Cmd+C` | -| Copy as CSV | `Cmd+Shift+C` | +| Copy with Headers | `Cmd+Shift+C` | | Copy as JSON | `Cmd+Option+J` | | Copy as TSV | Available from context menu | @@ -147,10 +147,9 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut | Close window / tab | `Cmd+W` | | New query tab | `Cmd+T` | | Switch to tab 1-9 | `Cmd+1` through `Cmd+9` | -| Next tab | `Cmd+Shift+]` or `Cmd+Option+Right` | -| Previous tab | `Cmd+Shift+[` or `Cmd+Option+Left` | +| Next tab | `Cmd+Shift+]` | +| Previous tab | `Cmd+Shift+[` | | Minimize | `Cmd+M` | -| Zoom | `Cmd+Option+Z` | ### Connections @@ -158,7 +157,6 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut |--------|----------| | New connection | `Cmd+N` | | Switch connection | `Cmd+Control+C` | -| Disconnect | `Cmd+D` | | Refresh connection | `Cmd+R` | | Delete selected connections | `Cmd+Delete` | @@ -178,7 +176,6 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut | Query History | `Cmd+Y` | | Toggle Cell Inspector | `Cmd+Option+I` | | Toggle Results | `Cmd+Opt+R` | -| Toggle AI Chat | `Cmd+Shift+L` | | Settings | `Cmd+,` | ### Results @@ -193,9 +190,8 @@ TablePro is keyboard-driven. Most actions have shortcuts, and most menu shortcut | Action | Shortcut | Description | |--------|----------|-------------| -| Toggle AI Chat | `Cmd+Shift+L` | Open or close the AI chat panel | -| Explain with AI | `Cmd+L` | Send selected SQL (or current query) to AI for explanation | -| Optimize with AI | `Cmd+Option+L` | Send selected SQL (or current query) to AI for optimization | +| Explain with AI | `Cmd+L` | Send current query to AI for explanation | +| Optimize with AI | `Cmd+Option+L` | Send current query to AI for optimization | ## ER Diagram @@ -309,11 +305,11 @@ Vim mode keybindings only apply in the SQL editor. They don't affect the data gr ## Quick switcher -The Quick Switcher (`Cmd+P`) lets you search and jump to any table, view, database, schema, or recent query. It uses fuzzy matching, so typing `usr` finds `users`, `user_settings`, etc. +The Quick Switcher (`Cmd+Shift+O`) lets you search and jump to any table, view, database, schema, or recent query. It uses fuzzy matching, so typing `usr` finds `users`, `user_settings`, etc. | Action | Shortcut | |--------|----------| -| Open Quick Switcher | `Cmd+P` | +| Open Quick Switcher | `Cmd+Shift+O` | | Navigate results | `Up` / `Down` arrows | | Open selected item | `Return` | | Dismiss | `Escape` | @@ -326,7 +322,6 @@ Results are grouped by type (tables, views, system tables, databases, schemas, r |--------|----------| | Quit application | `Cmd+Q` | | Preferences | `Cmd+,` | -| Search documentation | `Cmd+?` | ## Customizing Shortcuts