forked from CodeEditApp/CodeEditSourceEditor
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTextViewController+LoadView.swift
More file actions
128 lines (112 loc) · 4.4 KB
/
TextViewController+LoadView.swift
File metadata and controls
128 lines (112 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//
// TextViewController+LoadView.swift
// CodeEditSourceEditor
//
// Created by Khan Winter on 10/14/23.
//
import CodeEditTextView
import AppKit
extension TextViewController {
// swiftlint:disable:next function_body_length
override public func loadView() {
scrollView = NSScrollView()
textView.postsFrameChangedNotifications = true
textView.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.contentView.postsFrameChangedNotifications = true
scrollView.hasVerticalScroller = true
scrollView.hasHorizontalScroller = !wrapLines
scrollView.documentView = textView
scrollView.contentView.postsBoundsChangedNotifications = true
gutterView = GutterView(
font: font.rulerFont,
textColor: .secondaryLabelColor,
textView: textView,
delegate: self
)
gutterView.updateWidthIfNeeded()
scrollView.addFloatingSubview(
gutterView,
for: .horizontal
)
self.view = scrollView
if let _undoManager {
textView.setUndoManager(_undoManager)
}
styleTextView()
styleScrollView()
styleGutterView()
setUpHighlighter()
setUpTextFormation()
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
if !cursorPositions.isEmpty {
setCursorPositions(cursorPositions)
}
// Layout on scroll change
NotificationCenter.default.addObserver(
forName: NSView.boundsDidChangeNotification,
object: scrollView.contentView,
queue: .main
) { [weak self] _ in
self?.textView.updatedViewport(self?.scrollView.documentVisibleRect ?? .zero)
self?.gutterView.needsDisplay = true
}
// Layout on frame change
NotificationCenter.default.addObserver(
forName: NSView.frameDidChangeNotification,
object: scrollView.contentView,
queue: .main
) { [weak self] _ in
self?.textView.updatedViewport(self?.scrollView.documentVisibleRect ?? .zero)
self?.gutterView.needsDisplay = true
if self?.bracketPairHighlight == .flash {
self?.removeHighlightLayers()
}
}
NotificationCenter.default.addObserver(
forName: NSView.frameDidChangeNotification,
object: textView,
queue: .main
) { [weak self] _ in
self?.gutterView.frame.size.height = (self?.textView.frame.height ?? 0) + 10
self?.gutterView.needsDisplay = true
}
NotificationCenter.default.addObserver(
forName: TextSelectionManager.selectionChangedNotification,
object: textView.selectionManager,
queue: .main
) { [weak self] _ in
self?.updateCursorPosition()
self?.highlightSelectionPairs()
}
textView.updateFrameIfNeeded()
NSApp.publisher(for: \.effectiveAppearance)
.receive(on: RunLoop.main)
.sink { [weak self] newValue in
guard let self = self else { return }
if self.systemAppearance != newValue.name {
self.systemAppearance = newValue.name
}
}
.store(in: &cancellables)
if let localEventMonitor = self.localEvenMonitor {
NSEvent.removeMonitor(localEventMonitor)
}
self.localEvenMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { [weak self] event in
guard self?.view.window?.firstResponder == self?.textView else { return event }
let commandKey = NSEvent.ModifierFlags.command.rawValue
let modifierFlags = event.modifierFlags.intersection(.deviceIndependentFlagsMask).rawValue
if modifierFlags == commandKey && event.charactersIgnoringModifiers == "/" {
self?.commandSlashCalled()
return nil
} else {
return event
}
}
}
}