Skip to content

Commit bc14d96

Browse files
authored
Improve completion panel (#110)
* More chances to cancel completions * Fix typo * Fix the sudden flip of the completion panel
1 parent 29c28ba commit bc14d96

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

MarkEditMac/Modules/Sources/TextCompletion/Internal/TextCompletionPanel.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ final class TextCompletionPanel: NSPanel, TextCompletionPanelProtocol {
3535
self.backgroundColor = .clear
3636
}
3737

38+
override var canBecomeKey: Bool {
39+
// We don't need the completion panel to be the key window,
40+
// keyboard events are handled in the editor and redirected.
41+
false
42+
}
43+
3844
override func layoutIfNeeded() {
3945
super.layoutIfNeeded()
4046

MarkEditMac/Modules/Sources/TextCompletion/TextCompletionContext.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public final class TextCompletionContext {
1919
didSet {
2020
if !isPanelVisible {
2121
panel.orderOut(nil)
22+
wasFlipped = false
2223
}
2324
}
2425
}
@@ -41,7 +42,7 @@ public final class TextCompletionContext {
4142
parentWindow.addChildWindow(panel, ordered: .above)
4243
}
4344

44-
// Don't make the list absurdly wrong
45+
// Don't make the list absurdly long
4546
panel.updateCompletions(Array(completions.prefix(50)))
4647
panel.selectTop()
4748

@@ -60,9 +61,10 @@ public final class TextCompletionContext {
6061
origin.x = parentWindow.frame.size.width - panelPadding - panelSize.width
6162
}
6263

63-
// Too close to the bottom
64-
if origin.y - panelPadding < 0 {
64+
// Too close to the bottom, or was already upside down during one typing session
65+
if (origin.y - panelPadding < 0) || wasFlipped {
6566
origin.y = parentWindow.frame.height - caretRect.minY - safeArea + caretPadding
67+
wasFlipped = true
6668
}
6769

6870
let screenOrigin = parentWindow.convertPoint(toScreen: origin)
@@ -93,6 +95,11 @@ public final class TextCompletionContext {
9395
commitCompletion: commitCompletion
9496
)
9597

98+
// The flag to track whether the panel was flipped during a session,
99+
// as the word gets longer, we will likely see fewer suggestions,
100+
// we don't want the panel to suddenly flip in this case.
101+
private var wasFlipped = false
102+
96103
private let localizable: TextCompletionLocalizable
97104
private let commitCompletion: () -> Void
98105
}

MarkEditMac/Sources/Editor/Models/EditorDocument.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ extension EditorDocument {
104104
await saveAsynchronously {
105105
super.save(sender)
106106
}
107+
108+
if sender != nil {
109+
hostViewController?.cancelCompletion()
110+
}
107111
}
108112
}
109113

MarkEditMac/Sources/Main/Application/AppDelegate.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
7979

8080
private extension AppDelegate {
8181
@objc private func windowDidResignKey(_ notification: Notification) {
82+
// Cancel completion when an editor is no longer the key window
83+
if let editor = (notification.object as? NSWindow)?.contentViewController as? EditorViewController {
84+
editor.cancelCompletion()
85+
}
86+
8287
// To reduce the glitches between switching windows,
8388
// close openPanel once we don't have any key windows.
8489
if NSApp.windows.allSatisfy({ !$0.isKeyWindow }) {

0 commit comments

Comments
 (0)