Skip to content

Commit 2ca5b03

Browse files
committed
Highlight Minimap Visible Region
1 parent fa69a42 commit 2ca5b03

File tree

5 files changed

+26
-33
lines changed

5 files changed

+26
-33
lines changed

Sources/CodeEditSourceEditor/Controller/TextViewController+Highlighter.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extension TextViewController {
1717

1818
let highlighter = Highlighter(
1919
textView: textView,
20+
minimapView: minimapView,
2021
providers: highlightProviders,
2122
attributeProvider: self,
2223
language: language

Sources/CodeEditSourceEditor/Highlighting/Highlighter.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class Highlighter: NSObject {
8585

8686
init(
8787
textView: TextView,
88+
minimapView: MinimapView,
8889
providers: [HighlightProviding],
8990
attributeProvider: ThemeAttributesProviding,
9091
language: CodeLanguage
@@ -93,7 +94,7 @@ class Highlighter: NSObject {
9394
self.textView = textView
9495
self.attributeProvider = attributeProvider
9596

96-
self.visibleRangeProvider = VisibleRangeProvider(textView: textView)
97+
self.visibleRangeProvider = VisibleRangeProvider(textView: textView, minimapView: minimapView)
9798

9899
let providerIds = providers.indices.map({ $0 })
99100
self.styleContainer = StyledRangeContainer(documentLength: textView.length, providers: providerIds)
@@ -244,7 +245,7 @@ extension Highlighter: NSTextStorageDelegate {
244245
visibleRangeProvider.visibleSet.insert(range: editedRange)
245246
}
246247

247-
visibleRangeProvider.updateVisibleSet(textView: textView)
248+
visibleRangeProvider.visibleTextChanged()
248249

249250
let providerRange = NSRange(location: editedRange.location, length: editedRange.length - delta)
250251
highlightProviders.forEach { $0.storageDidUpdate(range: providerRange, delta: delta) }

Sources/CodeEditSourceEditor/Highlighting/VisibleRangeProvider.swift

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ protocol VisibleRangeProviderDelegate: AnyObject {
1818
@MainActor
1919
class VisibleRangeProvider {
2020
private weak var textView: TextView?
21+
private weak var minimapView: MinimapView?
2122
weak var delegate: VisibleRangeProviderDelegate?
2223

2324
var documentRange: NSRange {
@@ -29,56 +30,44 @@ class VisibleRangeProvider {
2930
return IndexSet(integersIn: textView?.visibleTextRange ?? NSRange())
3031
}()
3132

32-
init(textView: TextView) {
33+
init(textView: TextView, minimapView: MinimapView) {
3334
self.textView = textView
35+
self.minimapView = minimapView
3436

3537
if let scrollView = textView.enclosingScrollView {
3638
NotificationCenter.default.addObserver(
3739
self,
38-
selector: #selector(visibleTextChanged(_:)),
40+
selector: #selector(visibleTextChanged),
3941
name: NSView.frameDidChangeNotification,
4042
object: scrollView
4143
)
4244

4345
NotificationCenter.default.addObserver(
4446
self,
45-
selector: #selector(visibleTextChanged(_:)),
47+
selector: #selector(visibleTextChanged),
4648
name: NSView.boundsDidChangeNotification,
4749
object: scrollView.contentView
4850
)
49-
} else {
50-
NotificationCenter.default.addObserver(
51-
self,
52-
selector: #selector(visibleTextChanged(_:)),
53-
name: NSView.frameDidChangeNotification,
54-
object: textView
55-
)
5651
}
57-
}
5852

59-
func updateVisibleSet(textView: TextView) {
60-
if let newVisibleRange = textView.visibleTextRange {
61-
visibleSet = IndexSet(integersIn: newVisibleRange)
62-
}
53+
NotificationCenter.default.addObserver(
54+
self,
55+
selector: #selector(visibleTextChanged),
56+
name: NSView.frameDidChangeNotification,
57+
object: textView
58+
)
6359
}
6460

6561
/// Updates the view to highlight newly visible text when the textview is scrolled or bounds change.
66-
@objc func visibleTextChanged(_ notification: Notification) {
67-
let textView: TextView
68-
if let clipView = notification.object as? NSClipView,
69-
let documentView = clipView.enclosingScrollView?.documentView as? TextView {
70-
textView = documentView
71-
} else if let scrollView = notification.object as? NSScrollView,
72-
let documentView = scrollView.documentView as? TextView {
73-
textView = documentView
74-
} else if let documentView = notification.object as? TextView {
75-
textView = documentView
76-
} else {
62+
@objc func visibleTextChanged() {
63+
guard let textViewVisibleRange = textView?.visibleTextRange else {
7764
return
7865
}
79-
80-
updateVisibleSet(textView: textView)
81-
66+
var visibleSet = IndexSet(integersIn: textViewVisibleRange)
67+
if !(minimapView?.isHidden ?? true), let minimapVisibleRange = minimapView?.visibleTextRange {
68+
visibleSet.formUnion(IndexSet(integersIn: minimapVisibleRange))
69+
}
70+
self.visibleSet = visibleSet
8271
delegate?.visibleSetDidUpdate(visibleSet)
8372
}
8473

Sources/CodeEditSourceEditor/Minimap/MinimapView+DocumentVisibleView.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ extension MinimapView {
5858
if minimapHeight > containerHeight {
5959
setScrollViewPosition(scrollPercentage: scrollPercentage)
6060
}
61+
62+
contentView.needsLayout = true
6163
}
6264

6365
private func setScrollViewPosition(scrollPercentage: CGFloat) {

Sources/CodeEditSourceEditor/Minimap/MinimapView+TextSelectionManagerDelegate.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import CodeEditTextView
1010

1111
extension MinimapView: TextSelectionManagerDelegate {
1212
public var visibleTextRange: NSRange? {
13-
let minY = max(visibleRect.minY, 0)
14-
let maxY = min(visibleRect.maxY, layoutManager?.estimatedHeight() ?? 3.0)
13+
let minY = max(visibleRect.minY - 12, 0)
14+
let maxY = min(visibleRect.maxY + 12, layoutManager?.estimatedHeight() ?? 3.0)
1515
guard let minYLine = layoutManager?.textLineForPosition(minY),
1616
let maxYLine = layoutManager?.textLineForPosition(maxY) else {
1717
return nil

0 commit comments

Comments
 (0)