added typeaheead and introspetion

This commit is contained in:
Mark Gregory
2026-10-18 16:43:08 +01:00
parent b6123a0043
commit bcd33b3fa5
3 changed files with 34 additions and 9 deletions
+9 -9
View File
@@ -972,10 +972,11 @@ struct MainView: View {
.fill(WB.border)
.frame(width: 1)
SQLTextView(text: $model.sql, selectedSQL: $selectedSQL, focusRequest: sqlFocusRequest, completions: model.schemaColumns[model.selectedDatabase] ?? [],
tables: model.introspection(for: model.selectedDatabase)?.tables ?? model.schemaTables[model.selectedDatabase] ?? [],
views: model.introspection(for: model.selectedDatabase)?.views ?? model.schemaViews[model.selectedDatabase] ?? [],
columnsByTable: model.introspection(for: model.selectedDatabase)?.columnsByTable.mapValues { $0.map(\.name) } ?? [:],
SQLTextView(text: $model.sql, selectedSQL: $selectedSQL, focusRequest: sqlFocusRequest,
completions: model.schemaColumns[model.completionDatabase] ?? [],
tables: model.introspection(for: model.completionDatabase)?.tables ?? model.schemaTables[model.completionDatabase] ?? [],
views: model.introspection(for: model.completionDatabase)?.views ?? model.schemaViews[model.completionDatabase] ?? [],
columnsByTable: model.introspection(for: model.completionDatabase)?.columnsByTable.mapValues { $0.map(\.name) } ?? [:],
databases: model.databases)
}
.background(Color(nsColor: .textBackgroundColor))
@@ -1442,7 +1443,6 @@ struct SQLTextView: NSViewRepresentable {
editor.backgroundColor = .textBackgroundColor
editor.textColor = .textColor
scroll.backgroundColor = .textBackgroundColor
context.coordinator.highlight(editor)
if context.coordinator.lastFocusRequest != focusRequest {
context.coordinator.lastFocusRequest = focusRequest
DispatchQueue.main.async { [weak editor] in
@@ -1513,7 +1513,7 @@ struct SQLTextView: NSViewRepresentable {
}
private func showSuggestions(_ editor: NSTextView) {
guard editor.window?.firstResponder === editor else { dismissSuggestions(); return }
guard editor.window != nil else { dismissSuggestions(); return }
let selection = editor.selectedRange()
guard selection.length == 0, selection.location != NSNotFound else { dismissSuggestions(); return }
let source = editor.string as NSString
@@ -1546,7 +1546,7 @@ struct SQLTextView: NSViewRepresentable {
guard !suggestionItems.isEmpty else { dismissSuggestions(); return }
dismissPopoverOnly()
let popover = NSPopover()
popover.behavior = .semitransient
popover.behavior = .applicationDefined
let items = suggestionItems
let content = NSHostingView(rootView: VStack(alignment: .leading, spacing: 0) {
ForEach(Array(items.enumerated()), id: \.offset) { index, item in
@@ -1580,7 +1580,7 @@ struct SQLTextView: NSViewRepresentable {
if keyMonitor == nil {
keyMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self, weak editor] event in
guard let self, let editor, self.suggestionPopover?.isShown == true,
editor.window?.firstResponder === editor else { return event }
editor.window != nil else { return event }
switch event.keyCode {
case 53: self.dismissSuggestions(); return nil // Escape
case 36, 48: self.acceptSuggestion(editor); return nil // Return / Tab
@@ -1678,7 +1678,7 @@ struct SQLTextView: NSViewRepresentable {
highlight(editor)
// Do not invoke AppKit's completion panel from textDidChange.
// That re-entrant path caused the previous editor freezes/crashes.
// Completion remains available through the standard macOS Complete command.
// Schedule outside the AppKit edit callback to avoid re-entrant completion.
scheduleSuggestions(editor)
}