Skip to content

Commit a7cb556

Browse files
committed
Use Constants For Emphasis Groups, Add additionalInsets, Correctly Update Insets, Fix Tests
1 parent 909eabc commit a7cb556

12 files changed

+156
-73
lines changed

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let package = Package(
1717
// A fast, efficient, text view for code.
1818
.package(
1919
url: "https://github.com/CodeEditApp/CodeEditTextView.git",
20-
from: "0.8.1"
20+
from: "0.8.2"
2121
),
2222
// tree-sitter languages
2323
.package(

Sources/CodeEditSourceEditor/CodeEditSourceEditor/CodeEditSourceEditor.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
3535
/// built-in `TreeSitterClient` highlighter.
3636
/// - contentInsets: Insets to use to offset the content in the enclosing scroll view. Leave as `nil` to let the
3737
/// scroll view automatically adjust content insets.
38+
/// - additionalTextInsets: An additional amount to inset the text of the editor by.
3839
/// - isEditable: A Boolean value that controls whether the text view allows the user to edit text.
3940
/// - isSelectable: A Boolean value that controls whether the text view allows the user to select text. If this
4041
/// value is true, and `isEditable` is false, the editor is selectable but not editable.
@@ -59,6 +60,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
5960
useThemeBackground: Bool = true,
6061
highlightProviders: [any HighlightProviding] = [TreeSitterClient()],
6162
contentInsets: NSEdgeInsets? = nil,
63+
additionalTextInsets: NSEdgeInsets? = nil,
6264
isEditable: Bool = true,
6365
isSelectable: Bool = true,
6466
letterSpacing: Double = 1.0,
@@ -80,6 +82,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
8082
self.cursorPositions = cursorPositions
8183
self.highlightProviders = highlightProviders
8284
self.contentInsets = contentInsets
85+
self.additionalTextInsets = additionalTextInsets
8386
self.isEditable = isEditable
8487
self.isSelectable = isSelectable
8588
self.letterSpacing = letterSpacing
@@ -134,6 +137,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
134137
useThemeBackground: Bool = true,
135138
highlightProviders: [any HighlightProviding] = [TreeSitterClient()],
136139
contentInsets: NSEdgeInsets? = nil,
140+
additionalTextInsets: NSEdgeInsets? = nil,
137141
isEditable: Bool = true,
138142
isSelectable: Bool = true,
139143
letterSpacing: Double = 1.0,
@@ -155,6 +159,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
155159
self.cursorPositions = cursorPositions
156160
self.highlightProviders = highlightProviders
157161
self.contentInsets = contentInsets
162+
self.additionalTextInsets = additionalTextInsets
158163
self.isEditable = isEditable
159164
self.isSelectable = isSelectable
160165
self.letterSpacing = letterSpacing
@@ -181,6 +186,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
181186
private var useThemeBackground: Bool
182187
private var highlightProviders: [any HighlightProviding]
183188
private var contentInsets: NSEdgeInsets?
189+
private var additionalTextInsets: NSEdgeInsets?
184190
private var isEditable: Bool
185191
private var isSelectable: Bool
186192
private var letterSpacing: Double
@@ -206,6 +212,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
206212
useThemeBackground: useThemeBackground,
207213
highlightProviders: highlightProviders,
208214
contentInsets: contentInsets,
215+
additionalTextInsets: additionalTextInsets,
209216
isEditable: isEditable,
210217
isSelectable: isSelectable,
211218
letterSpacing: letterSpacing,
@@ -289,6 +296,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
289296
controller.lineHeightMultiple = lineHeight
290297
controller.editorOverscroll = editorOverscroll
291298
controller.contentInsets = contentInsets
299+
controller.additionalTextInsets = additionalTextInsets
292300

293301
if controller.indentOption != indentOption {
294302
controller.indentOption = indentOption
@@ -339,6 +347,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
339347
controller.lineHeightMultiple == lineHeight &&
340348
controller.editorOverscroll == editorOverscroll &&
341349
controller.contentInsets == contentInsets &&
350+
controller.additionalTextInsets == additionalTextInsets &&
342351
controller.language.id == language.id &&
343352
controller.theme == theme &&
344353
controller.indentOption == indentOption &&

Sources/CodeEditSourceEditor/Controller/TextViewController+EmphasizeBracket.swift

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import CodeEditTextView
1111
extension TextViewController {
1212
/// Emphasizes bracket pairs using the current selection.
1313
internal func emphasizeSelectionPairs() {
14-
guard bracketPairEmphasis != nil else { return }
15-
textView.emphasisManager?.removeEmphases(for: "bracketPairs")
14+
guard let bracketPairEmphasis else { return }
15+
textView.emphasisManager?.removeEmphases(for: EmphasisGroup.brackets)
1616
for range in textView.selectionManager.textSelections.map({ $0.range }) {
1717
if range.isEmpty,
1818
range.location > 0, // Range is not the beginning of the document
@@ -22,40 +22,46 @@ extension TextViewController {
2222
for pair in BracketPairs.emphasisValues {
2323
if precedingCharacter == pair.0 {
2424
// Walk forwards
25-
if let characterIndex = findClosingPair(
26-
pair.0,
27-
pair.1,
28-
from: range.location,
29-
limit: min(NSMaxRange(textView.visibleTextRange ?? .zero) + 4096,
30-
NSMaxRange(textView.documentRange)),
31-
reverse: false
32-
) {
33-
emphasizeCharacter(characterIndex)
34-
if bracketPairEmphasis?.emphasizesSourceBracket ?? false {
35-
emphasizeCharacter(range.location - 1)
36-
}
37-
}
25+
emphasizeForwards(pair, range: range, emphasisType: bracketPairEmphasis)
3826
} else if precedingCharacter == pair.1 && range.location - 1 > 0 {
3927
// Walk backwards
40-
if let characterIndex = findClosingPair(
41-
pair.1,
42-
pair.0,
43-
from: range.location - 1,
44-
limit: max((textView.visibleTextRange?.location ?? 0) - 4096,
45-
textView.documentRange.location),
46-
reverse: true
47-
) {
48-
emphasizeCharacter(characterIndex)
49-
if bracketPairEmphasis?.emphasizesSourceBracket ?? false {
50-
emphasizeCharacter(range.location - 1)
51-
}
52-
}
28+
emphasizeBackwards(pair, range: range, emphasisType: bracketPairEmphasis)
5329
}
5430
}
5531
}
5632
}
5733
}
5834

35+
private func emphasizeForwards(_ pair: (String, String), range: NSRange, emphasisType: BracketPairEmphasis) {
36+
if let characterIndex = findClosingPair(
37+
pair.0,
38+
pair.1,
39+
from: range.location,
40+
limit: min((textView.visibleTextRange ?? .zero).max + 4096, textView.documentRange.max),
41+
reverse: false
42+
) {
43+
emphasizeCharacter(characterIndex)
44+
if emphasisType.emphasizesSourceBracket {
45+
emphasizeCharacter(range.location - 1)
46+
}
47+
}
48+
}
49+
50+
private func emphasizeBackwards(_ pair: (String, String), range: NSRange, emphasisType: BracketPairEmphasis) {
51+
if let characterIndex = findClosingPair(
52+
pair.1,
53+
pair.0,
54+
from: range.location - 1,
55+
limit: max((textView.visibleTextRange?.location ?? 0) - 4096, textView.documentRange.location),
56+
reverse: true
57+
) {
58+
emphasizeCharacter(characterIndex)
59+
if emphasisType.emphasizesSourceBracket {
60+
emphasizeCharacter(range.location - 1)
61+
}
62+
}
63+
}
64+
5965
/// # Dev Note
6066
/// It's interesting to note that this problem could trivially be turned into a monoid, and the locations of each
6167
/// pair start/end location determined when the view is loaded. It could then be parallelized for initial speed
@@ -128,7 +134,7 @@ extension TextViewController {
128134
flash: true,
129135
inactive: false
130136
),
131-
for: "bracketPairs"
137+
for: EmphasisGroup.brackets
132138
)
133139
case .bordered(let borderColor):
134140
textView.emphasisManager?.addEmphasis(
@@ -138,7 +144,7 @@ extension TextViewController {
138144
flash: false,
139145
inactive: false
140146
),
141-
for: "bracketPairs"
147+
for: EmphasisGroup.brackets
142148
)
143149
case .underline(let underlineColor):
144150
textView.emphasisManager?.addEmphasis(
@@ -148,7 +154,7 @@ extension TextViewController {
148154
flash: false,
149155
inactive: false
150156
),
151-
for: "bracketPairs"
157+
for: EmphasisGroup.brackets
152158
)
153159
}
154160
}

Sources/CodeEditSourceEditor/Controller/TextViewController+LoadView.swift

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,7 @@ extension TextViewController {
7777
) { [weak self] _ in
7878
self?.textView.updatedViewport(self?.scrollView.documentVisibleRect ?? .zero)
7979
self?.gutterView.needsDisplay = true
80-
if self?.bracketPairEmphasis == .flash {
81-
self?.emphasisManager?.removeEmphases(for: "bracketPairs")
82-
}
80+
self?.emphasisManager?.removeEmphases(for: EmphasisGroup.brackets)
8381
}
8482

8583
NotificationCenter.default.addObserver(
@@ -111,13 +109,8 @@ extension TextViewController {
111109
self.systemAppearance = newValue.name
112110

113111
// Reset content insets and gutter position when appearance changes
114-
if let contentInsets = self.contentInsets {
115-
self.scrollView.contentInsets = contentInsets
116-
if let findViewController = self.findViewController, findViewController.isShowingFindPanel {
117-
self.scrollView.contentInsets.top += FindPanel.height
118-
}
119-
self.gutterView.frame.origin.y = -self.scrollView.contentInsets.top
120-
}
112+
self.styleScrollView()
113+
self.gutterView.frame.origin.y = -self.scrollView.contentInsets.top
121114
}
122115
}
123116
.store(in: &cancellables)

Sources/CodeEditSourceEditor/Controller/TextViewController+StyleViews.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ extension TextViewController {
7474
} else {
7575
scrollView.automaticallyAdjustsContentInsets = true
7676
}
77+
78+
scrollView.contentInsets.top += additionalTextInsets?.top ?? 0
79+
scrollView.contentInsets.bottom += additionalTextInsets?.bottom ?? 0
80+
7781
scrollView.contentInsets.top += (findViewController?.isShowingFindPanel ?? false) ? FindPanel.height : 0
7882
}
7983
}

Sources/CodeEditSourceEditor/Controller/TextViewController.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ public class TextViewController: NSViewController {
3333
var textView: TextView!
3434
var gutterView: GutterView!
3535
internal var _undoManager: CEUndoManager!
36-
/// Internal reference to any injected layers in the text view.
37-
internal var highlightLayers: [CALayer] = []
3836
internal var systemAppearance: NSAppearance.Name?
3937

4038
package var localEvenMonitor: Any?
@@ -127,13 +125,24 @@ public class TextViewController: NSViewController {
127125
/// The provided highlight provider.
128126
public var highlightProviders: [HighlightProviding]
129127

130-
/// Optional insets to offset the text view in the scroll view by.
128+
/// Optional insets to offset the text view and find panel in the scroll view by.
131129
public var contentInsets: NSEdgeInsets? {
132130
didSet {
131+
styleScrollView()
133132
findViewController?.topPadding = contentInsets?.top
134133
}
135134
}
136135

136+
/// An additional amount to inset text by. Horizontal values are ignored.
137+
///
138+
/// This value does not affect decorations like the find panel, but affects things that are relative to text, such
139+
/// as line numbers and of course the text itself.
140+
public var additionalTextInsets: NSEdgeInsets? {
141+
didSet {
142+
styleScrollView()
143+
}
144+
}
145+
137146
/// Whether or not text view is editable by user
138147
public var isEditable: Bool {
139148
didSet {
@@ -232,6 +241,7 @@ public class TextViewController: NSViewController {
232241
useThemeBackground: Bool,
233242
highlightProviders: [HighlightProviding] = [TreeSitterClient()],
234243
contentInsets: NSEdgeInsets?,
244+
additionalTextInsets: NSEdgeInsets? = nil,
235245
isEditable: Bool,
236246
isSelectable: Bool,
237247
letterSpacing: Double,
@@ -252,6 +262,7 @@ public class TextViewController: NSViewController {
252262
self.useThemeBackground = useThemeBackground
253263
self.highlightProviders = highlightProviders
254264
self.contentInsets = contentInsets
265+
self.additionalTextInsets = additionalTextInsets
255266
self.isEditable = isEditable
256267
self.isSelectable = isSelectable
257268
self.letterSpacing = letterSpacing

Sources/CodeEditSourceEditor/Find/FindViewController+FindPanelDelegate.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ extension FindViewController: FindPanelDelegate {
3838
if let textViewController = target as? TextViewController,
3939
textViewController.textView.window?.firstResponder === textViewController.textView {
4040
// If the text view has focus, just clear visual emphases but keep matches in memory
41-
target?.emphasisManager?.removeEmphases(for: "find")
41+
target?.emphasisManager?.removeEmphases(for: EmphasisGroup.find)
4242
// Re-add the current active emphasis without visual emphasis
43-
if let emphases = target?.emphasisManager?.getEmphases(for: "find"),
43+
if let emphases = target?.emphasisManager?.getEmphases(for: EmphasisGroup.find),
4444
let activeEmphasis = emphases.first(where: { !$0.inactive }) {
4545
target?.emphasisManager?.addEmphasis(
4646
Emphasis(
@@ -50,14 +50,14 @@ extension FindViewController: FindPanelDelegate {
5050
inactive: false,
5151
selectInDocument: true
5252
),
53-
for: "find"
53+
for: EmphasisGroup.find
5454
)
5555
}
5656
return
5757
}
5858

5959
// Clear existing emphases before performing new find
60-
target?.emphasisManager?.removeEmphases(for: "find")
60+
target?.emphasisManager?.removeEmphases(for: EmphasisGroup.find)
6161
find(text: text)
6262
}
6363

@@ -87,7 +87,7 @@ extension FindViewController: FindPanelDelegate {
8787
let newActiveRange = findMatches[currentFindMatchIndex]
8888

8989
// Clear existing emphases before adding the flash
90-
emphasisManager.removeEmphases(for: "find")
90+
emphasisManager.removeEmphases(for: EmphasisGroup.find)
9191

9292
emphasisManager.addEmphasis(
9393
Emphasis(
@@ -97,7 +97,7 @@ extension FindViewController: FindPanelDelegate {
9797
inactive: false,
9898
selectInDocument: true
9999
),
100-
for: "find"
100+
for: EmphasisGroup.find
101101
)
102102

103103
return
@@ -115,7 +115,7 @@ extension FindViewController: FindPanelDelegate {
115115
}
116116

117117
// Replace all emphases to update state
118-
emphasisManager.replaceEmphases(updatedEmphases, for: "find")
118+
emphasisManager.replaceEmphases(updatedEmphases, for: EmphasisGroup.find)
119119
}
120120

121121
func findPanelNextButtonClicked() {
@@ -150,7 +150,7 @@ extension FindViewController: FindPanelDelegate {
150150
let newActiveRange = findMatches[currentFindMatchIndex]
151151

152152
// Clear existing emphases before adding the flash
153-
emphasisManager.removeEmphases(for: "find")
153+
emphasisManager.removeEmphases(for: EmphasisGroup.find)
154154

155155
emphasisManager.addEmphasis(
156156
Emphasis(
@@ -160,7 +160,7 @@ extension FindViewController: FindPanelDelegate {
160160
inactive: false,
161161
selectInDocument: true
162162
),
163-
for: "find"
163+
for: EmphasisGroup.find
164164
)
165165

166166
return
@@ -178,14 +178,14 @@ extension FindViewController: FindPanelDelegate {
178178
}
179179

180180
// Replace all emphases to update state
181-
emphasisManager.replaceEmphases(updatedEmphases, for: "find")
181+
emphasisManager.replaceEmphases(updatedEmphases, for: EmphasisGroup.find)
182182
}
183183

184184
func findPanelUpdateMatchCount(_ count: Int) {
185185
findPanel.updateMatchCount(count)
186186
}
187187

188188
func findPanelClearEmphasis() {
189-
target?.emphasisManager?.removeEmphases(for: "find")
189+
target?.emphasisManager?.removeEmphases(for: EmphasisGroup.find)
190190
}
191191
}

0 commit comments

Comments
 (0)