diff --git a/src/components/ui/SqlEditorWrapper.tsx b/src/components/ui/SqlEditorWrapper.tsx index b2e4fc88..50eb9b28 100644 --- a/src/components/ui/SqlEditorWrapper.tsx +++ b/src/components/ui/SqlEditorWrapper.tsx @@ -5,6 +5,7 @@ import { useEditorTheme } from "../../hooks/useEditorTheme"; import { loadMonacoTheme } from "../../themes/themeUtils"; import { readText } from "@tauri-apps/plugin-clipboard-manager"; import { useSettings } from "../../hooks/useSettings"; +import { useKeybindings } from "../../hooks/useKeybindings"; import { getFontCSS } from "../../utils/settings"; interface SqlEditorWrapperProps { @@ -33,6 +34,9 @@ const SqlEditorInternal = ({ onRunRef.current = onRun; const editorTheme = useEditorTheme(); const { settings } = useSettings(); + const { matchesShortcut } = useKeybindings(); + const matchesShortcutRef = useRef(matchesShortcut); + matchesShortcutRef.current = matchesShortcut; // Dispose editor on unmount to prevent "domNode" errors from ResizeObserver // firing after the DOM container is removed (e.g., cell deletion/movement) @@ -141,6 +145,15 @@ const SqlEditorInternal = ({ } ); + // Force the suggestion widget via the user-configurable shortcut + editor.onKeyDown((e) => { + if (matchesShortcutRef.current(e.browserEvent, "trigger_suggestions")) { + e.preventDefault(); + e.stopPropagation(); + editor.trigger("keyboard", "editor.action.triggerSuggest", {}); + } + }); + if (onMount) onMount(editor, monaco); }; diff --git a/src/config/shortcuts.json b/src/config/shortcuts.json index 13f59f3b..bfc3c40b 100644 --- a/src/config/shortcuts.json +++ b/src/config/shortcuts.json @@ -69,6 +69,16 @@ "i18nKey": "settings.shortcuts.saveGridChanges", "overridable": true }, + { + "id": "refresh_table", + "category": "data_grid", + "defaultMac": "⌘+R", + "defaultWin": "Ctrl+R", + "macMatch": { "metaKey": true, "key": "r" }, + "winMatch": { "ctrlKey": true, "key": "r" }, + "i18nKey": "settings.shortcuts.refreshTable", + "overridable": true + }, { "id": "tab_switcher", "category": "editor", @@ -158,5 +168,15 @@ "winMatch": { "ctrlKey": true, "key": "p" }, "i18nKey": "settings.shortcuts.quickNavigator", "overridable": true + }, + { + "id": "trigger_suggestions", + "category": "editor", + "defaultMac": "⌘+I", + "defaultWin": "Ctrl+Space", + "macMatch": { "metaKey": true, "key": "i" }, + "winMatch": { "ctrlKey": true, "key": " " }, + "i18nKey": "settings.shortcuts.triggerSuggestions", + "overridable": true } ] diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index 9a6a43df..3eac7778 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -582,7 +582,9 @@ "notebookRunAll": "Alle Zellen ausführen", "categories_notebook": "Notebook", "pasteImportClipboard": "Aus Zwischenablage importieren", - "quickNavigator": "Schnellnavigation" + "quickNavigator": "Schnellnavigation", + "triggerSuggestions": "Vorschläge anzeigen", + "refreshTable": "Tabelle aktualisieren" }, "aiActivity": "KI-Aktivität" }, diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 6ca3ce8a..67db4a11 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -616,7 +616,9 @@ "notebookRunAll": "Run All Cells", "categories_notebook": "Notebook", "pasteImportClipboard": "Import from Clipboard", - "quickNavigator": "Quick Navigator" + "quickNavigator": "Quick Navigator", + "triggerSuggestions": "Trigger suggestions", + "refreshTable": "Refresh table" }, "aiActivity": "AI Activity" }, diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index e7a83378..8b463833 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -587,7 +587,9 @@ "notebookRunAll": "Ejecutar Todas las Celdas", "categories_notebook": "Notebook", "pasteImportClipboard": "Importar desde Portapapeles", - "quickNavigator": "Navegador rápido" + "quickNavigator": "Navegador rápido", + "triggerSuggestions": "Mostrar sugerencias", + "refreshTable": "Actualizar tabla" }, "aiActivity": "Actividad IA" }, diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index daa1d557..1ea9a3ec 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -582,7 +582,9 @@ "notebookRunAll": "Exécuter toutes les cellules", "categories_notebook": "Notebook", "pasteImportClipboard": "Importer depuis le Presse-papiers", - "quickNavigator": "Navigateur rapide" + "quickNavigator": "Navigateur rapide", + "triggerSuggestions": "Afficher les suggestions", + "refreshTable": "Actualiser la table" }, "aiActivity": "Activité IA" }, diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json index a244887b..519fe4a9 100644 --- a/src/i18n/locales/it.json +++ b/src/i18n/locales/it.json @@ -587,7 +587,9 @@ "notebookRunAll": "Esegui Tutte le Celle", "categories_notebook": "Notebook", "pasteImportClipboard": "Importa dagli Appunti", - "quickNavigator": "Navigatore rapido" + "quickNavigator": "Navigatore rapido", + "triggerSuggestions": "Mostra suggerimenti", + "refreshTable": "Aggiorna tabella" }, "aiActivity": "Attività AI" }, diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index 541ce3e2..f9889cda 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json @@ -596,7 +596,9 @@ "notebookRunAll": "すべてのセルを実行", "categories_notebook": "ノートブック", "pasteImportClipboard": "クリップボードからインポート", - "quickNavigator": "クイックナビゲーター" + "quickNavigator": "クイックナビゲーター", + "triggerSuggestions": "候補を表示", + "refreshTable": "テーブルを更新" }, "aiActivity": "AI アクティビティ" }, diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index 8483a021..e01d85a6 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -577,7 +577,9 @@ "notebookRunAll": "Выполнить все ячейки", "categories_notebook": "Ноутбук", "pasteImportClipboard": "Импортировать из буфера обмена", - "quickNavigator": "Быстрый навигатор" + "quickNavigator": "Быстрый навигатор", + "triggerSuggestions": "Показать подсказки", + "refreshTable": "Обновить таблицу" }, "aiActivity": "Активность AI" }, diff --git a/src/i18n/locales/zh.json b/src/i18n/locales/zh.json index cac50fd9..278d3aee 100644 --- a/src/i18n/locales/zh.json +++ b/src/i18n/locales/zh.json @@ -550,7 +550,9 @@ "pressKeys": "按下组合键...", "notebookRunAll": "运行所有单元格", "categories_notebook": "笔记本", - "quickNavigator": "快速导航" + "quickNavigator": "快速导航", + "triggerSuggestions": "触发建议", + "refreshTable": "刷新表格" }, "aiActivity": "AI 活动" }, diff --git a/src/pages/Editor.tsx b/src/pages/Editor.tsx index 26cfc6e2..058995d8 100644 --- a/src/pages/Editor.tsx +++ b/src/pages/Editor.tsx @@ -1518,6 +1518,17 @@ export const Editor = () => { } return; } + + if (matchesShortcut(e, "refresh_table")) { + const tab = tabsRef.current.find( + (t) => t.id === activeTabIdRef.current, + ); + if (tab?.activeTable) { + e.preventDefault(); + runQuery(tab.query, tab.page); + } + return; + } }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); diff --git a/tests/components/ui/SqlEditorWrapper.test.tsx b/tests/components/ui/SqlEditorWrapper.test.tsx index e54e4478..69385454 100644 --- a/tests/components/ui/SqlEditorWrapper.test.tsx +++ b/tests/components/ui/SqlEditorWrapper.test.tsx @@ -27,6 +27,13 @@ vi.mock('../../../src/hooks/useTheme', () => ({ })), })); +// Mock useKeybindings hook +vi.mock('../../../src/hooks/useKeybindings', () => ({ + useKeybindings: vi.fn(() => ({ + matchesShortcut: vi.fn(() => false), + })), +})); + // Mock themeUtils vi.mock('../../../src/themes/themeUtils', () => ({ loadMonacoTheme: vi.fn(),