Skip to content

Commit 7ad19a6

Browse files
committed
refactor: replace autocomplete NSTableView with native SwiftUI List
1 parent db3664b commit 7ad19a6

18 files changed

Lines changed: 618 additions & 711 deletions

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Cloudflare D1 database support
13+
- Match highlighting in autocomplete suggestions (matched characters shown in bold)
14+
- Loading spinner in autocomplete popup while fetching column metadata
15+
16+
### Changed
17+
18+
- Refactored autocomplete popup to native SwiftUI (visible selection highlight, native accent color, scroll-to-selection)
19+
- Autocomplete now suppresses noisy empty-prefix suggestions in non-browseable contexts (e.g., after SELECT, WHERE)
20+
- Autocomplete ranking stays consistent as you type (unified fuzzy scoring between initial display and live filtering)
21+
- Increased autocomplete suggestion limit from 20 to 40 for schema-heavy contexts (FROM, SELECT, WHERE)
22+
1023
## [0.20.4] - 2026-03-19
1124

1225
### Fixed

LocalPackages/CodeEditSourceEditor/Sources/CodeEditSourceEditor/CodeSuggestion/Model/CodeSuggestionEntry.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,11 @@ public protocol CodeSuggestionEntry {
2323
var imageColor: Color { get }
2424

2525
var deprecated: Bool { get }
26+
27+
/// Character index ranges in the label that matched the user's typed prefix.
28+
var matchedRanges: [Range<Int>] { get }
29+
}
30+
31+
public extension CodeSuggestionEntry {
32+
var matchedRanges: [Range<Int>] { [] }
2633
}

LocalPackages/CodeEditSourceEditor/Sources/CodeEditSourceEditor/CodeSuggestion/Model/SuggestionViewModel.swift

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import AppKit
1111
final class SuggestionViewModel: ObservableObject {
1212
/// The items to be displayed in the window
1313
@Published var items: [CodeSuggestionEntry] = []
14+
@Published var selectedIndex: Int = 0
15+
@Published var themeBackground: NSColor = .windowBackgroundColor
16+
@Published var themeTextColor: NSColor = .labelColor
17+
1418
var itemsRequestTask: Task<Void, Never>?
1519
weak var activeTextView: TextViewController?
1620

@@ -19,6 +23,51 @@ final class SuggestionViewModel: ObservableObject {
1923
private var cursorPosition: CursorPosition?
2024
private var syntaxHighlightedCache: [Int: NSAttributedString] = [:]
2125

26+
var selectedItem: CodeSuggestionEntry? {
27+
guard selectedIndex >= 0, selectedIndex < items.count else { return nil }
28+
return items[selectedIndex]
29+
}
30+
31+
func moveUp() {
32+
guard selectedIndex > 0 else { return }
33+
selectedIndex -= 1
34+
notifySelection()
35+
}
36+
37+
func moveDown() {
38+
guard selectedIndex < items.count - 1 else { return }
39+
selectedIndex += 1
40+
notifySelection()
41+
}
42+
43+
private func notifySelection() {
44+
if let item = selectedItem {
45+
delegate?.completionWindowDidSelect(item: item)
46+
}
47+
}
48+
49+
func updateTheme(from textView: TextViewController) {
50+
themeTextColor = textView.theme.text.color
51+
switch textView.systemAppearance {
52+
case .aqua:
53+
let color = textView.theme.background
54+
if color != .clear {
55+
themeBackground = NSColor(
56+
red: color.redComponent * 0.95,
57+
green: color.greenComponent * 0.95,
58+
blue: color.blueComponent * 0.95,
59+
alpha: 1.0
60+
)
61+
} else {
62+
themeBackground = .windowBackgroundColor
63+
}
64+
case .darkAqua:
65+
themeBackground = textView.theme.background
66+
default:
67+
break
68+
}
69+
}
70+
2271
func showCompletions(
2372
textView: TextViewController,
2473
delegate: CodeSuggestionDelegate,
@@ -59,6 +108,7 @@ final class SuggestionViewModel: ObservableObject {
59108
}
60109

61110
self.items = completionItems.items
111+
self.selectedIndex = 0
62112
self.syntaxHighlightedCache = [:]
63113
showWindowOnParent(targetParentWindow, cursorRect)
64114
}
@@ -91,6 +141,8 @@ final class SuggestionViewModel: ObservableObject {
91141
}
92142

93143
items = newItems
144+
selectedIndex = 0
145+
syntaxHighlightedCache = [:]
94146
}
95147

96148
func didSelect(item: CodeSuggestionEntry) {
@@ -111,6 +163,7 @@ final class SuggestionViewModel: ObservableObject {
111163

112164
func willClose() {
113165
items.removeAll()
166+
selectedIndex = 0
114167
activeTextView = nil
115168
}
116169

LocalPackages/CodeEditSourceEditor/Sources/CodeEditSourceEditor/CodeSuggestion/TableView/CodeSuggestionLabelView.swift

Lines changed: 0 additions & 53 deletions
This file was deleted.

LocalPackages/CodeEditSourceEditor/Sources/CodeEditSourceEditor/CodeSuggestion/TableView/CodeSuggestionPreviewView.swift

Lines changed: 0 additions & 169 deletions
This file was deleted.

LocalPackages/CodeEditSourceEditor/Sources/CodeEditSourceEditor/CodeSuggestion/TableView/CodeSuggestionRowView.swift

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)