Skip to content

Commit dba645d

Browse files
[chore]: Update STTextView to 0.5.3 (CodeEditApp#178)
### Description Updates STTextView to 0.5.3, accounting for a couple API changes & depreciations. Known issues: - [Editing with multiple cursors loses focus of all but the top-left cursor after applying the edit.](krzyzanowskim/STTextView#17) Also includes a tiny fix for a runtime error when publishing cursor position, and a fix for a rare crash to do with string indexes. (`STTextViewController+Cursor.swift`). ### Related Issues > N/A ### Checklist - [x] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md) - [x] The issues this PR addresses are related to each other - [x] My changes generate no new warnings - [x] My code builds and runs on my machine - [x] My changes are all related to the related issue above - [x] I documented my code ### Screenshots Copy-paste attributed text https://user-images.githubusercontent.com/35942988/234060270-82170964-c1b1-4dbf-bea2-3d6108857b3f.mov Multiple cursors (control-shift click) https://user-images.githubusercontent.com/35942988/234060289-f564f8be-ae57-482d-9037-9fd144591a1c.mov
1 parent 84505b4 commit dba645d

11 files changed

+59
-27
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ let package = Package(
1515
dependencies: [
1616
.package(
1717
url: "https://github.com/krzyzanowskim/STTextView.git",
18-
from: "0.4.1"
18+
from: "0.5.3"
1919
),
2020
.package(
2121
url: "https://github.com/CodeEditApp/CodeEditLanguages.git",

Sources/CodeEditTextView/Controller/STTextViewController+Cursor.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ extension STTextViewController {
3131
line -= 1
3232
if line < 1 {
3333
// If `column` exceeds the line length, set cursor to the end of the line.
34-
let index = min(lineRange.upperBound, string.index(lineRange.lowerBound, offsetBy: column - 1))
34+
// min = line begining, max = line end.
35+
let index = max(
36+
lineRange.lowerBound,
37+
min(lineRange.upperBound, string.index(lineRange.lowerBound, offsetBy: column - 1))
38+
)
3539
if let newRange = NSTextRange(NSRange(index..<index, in: string), provider: provider) {
3640
self.textView.setSelectedRange(newRange)
3741
}
@@ -46,7 +50,7 @@ extension STTextViewController {
4650
func updateCursorPosition() {
4751
guard let textLayoutManager = textView.textLayoutManager as NSTextLayoutManager?,
4852
let textContentManager = textLayoutManager.textContentManager as NSTextContentManager?,
49-
let insertionPointLocation = textLayoutManager.insertionPointLocation,
53+
let insertionPointLocation = textLayoutManager.insertionPointLocations.first,
5054
let documentStartLocation = textLayoutManager.documentRange.location as NSTextLocation?,
5155
let documentEndLocation = textLayoutManager.documentRange.endLocation as NSTextLocation?
5256
else {
@@ -96,7 +100,9 @@ extension STTextViewController {
96100
if col == 1 { line += 1 }
97101
}
98102

99-
self.cursorPosition.wrappedValue = (line, col)
103+
DispatchQueue.main.async {
104+
self.cursorPosition.wrappedValue = (line, col)
105+
}
100106
return false
101107
}
102108
}

Sources/CodeEditTextView/Controller/STTextViewController+Highlighter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ extension STTextViewController {
2828
provider = highlightProvider
2929
} else {
3030
let textProvider: ResolvingQueryCursor.TextProvider = { [weak self] range, _ -> String? in
31-
return self?.textView.textContentStorage.textStorage?.mutableString.substring(with: range)
31+
return self?.textView.textContentStorage?.textStorage?.mutableString.substring(with: range)
3232
}
3333

3434
provider = TreeSitterClient(codeLanguage: language, textProvider: textProvider)

Sources/CodeEditTextView/Controller/STTextViewController.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ public class STTextViewController: NSViewController, STTextViewDelegate, ThemeAt
162162
rulerView.font = rulerFont
163163
rulerView.selectedLineHighlightColor = theme.lineHighlight
164164
rulerView.rulerInsets = STRulerInsets(leading: rulerFont.pointSize * 1.6, trailing: 8)
165+
rulerView.allowsMarkers = false
165166

166167
if self.isEditable == false {
167168
rulerView.selectedLineTextColor = nil
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// STTextView+ContentStorage.swift
3+
//
4+
//
5+
// Created by Khan Winter on 4/24/23.
6+
//
7+
8+
import Foundation
9+
import AppKit
10+
import STTextView
11+
12+
extension STTextView {
13+
/// Convenience that unwraps `textContentManager` as an `NSTextContentStorage` subclass.
14+
var textContentStorage: NSTextContentStorage? {
15+
return textContentManager as? NSTextContentStorage
16+
}
17+
}

Sources/CodeEditTextView/Extensions/STTextView+/STTextView+TextInterface.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,21 @@ extension STTextView: TextInterface {
1616
return self.selectedRange()
1717
}
1818
set {
19+
guard let textContentStorage = textContentStorage else {
20+
return
21+
}
1922
if let textRange = NSTextRange(newValue, provider: textContentStorage) {
2023
self.setSelectedRange(textRange)
2124
}
2225
}
2326
}
2427

2528
public var length: Int {
26-
textContentStorage.length
29+
textContentStorage?.length ?? 0
2730
}
2831

2932
public func substring(from range: NSRange) -> String? {
30-
return textContentStorage.substring(from: range)
33+
return textContentStorage?.substring(from: range)
3134
}
3235

3336
public func applyMutation(_ mutation: TextStory.TextMutation) {
@@ -39,10 +42,10 @@ extension STTextView: TextInterface {
3942
})
4043
}
4144

42-
textContentStorage.performEditingTransaction {
43-
textContentStorage.applyMutation(mutation)
45+
textContentStorage?.performEditingTransaction {
46+
textContentStorage?.applyMutation(mutation)
4447
}
4548

46-
didChangeText()
49+
textDidChange(nil)
4750
}
4851
}

Sources/CodeEditTextView/Extensions/STTextView+/STTextView+VisibleRange.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import AppKit
1212
extension STTextView {
1313
/// A helper for calculating the visible range on the text view with some small vertical padding.
1414
var visibleTextRange: NSRange? {
15+
guard let textContentStorage = textContentStorage else {
16+
return nil
17+
}
18+
1519
// This helper finds the visible rect of the text using the enclosing scroll view, then finds the nearest
1620
// `NSTextElement`s to those points and uses those elements to create the returned range.
1721

Sources/CodeEditTextView/Filters/STTextViewController+TextFormation.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,14 @@ extension STTextViewController {
9696
public func textView(_ textView: STTextView,
9797
shouldChangeTextIn affectedCharRange: NSTextRange,
9898
replacementString: String?) -> Bool {
99-
guard let range = affectedCharRange.nsRange(using: textView.textContentStorage) else {
99+
guard let textContentStorage = textView.textContentStorage,
100+
let range = affectedCharRange.nsRange(using: textContentStorage) else {
100101
return true
101102
}
102103

103104
let mutation = TextMutation(string: replacementString ?? "",
104105
range: range,
105-
limit: textView.textContentStorage.length)
106+
limit: textView.textContentStorage?.length ?? 0)
106107

107108
textView.undoManager?.beginUndoGrouping()
108109

Sources/CodeEditTextView/Highlighting/Highlighter.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Highlighter: NSObject {
3232

3333
/// The range of the entire document
3434
private var entireTextRange: Range<Int> {
35-
return 0..<(textView.textContentStorage.textStorage?.length ?? 0)
35+
return 0..<(textView.textContentStorage?.textStorage?.length ?? 0)
3636
}
3737

3838
/// The set of visible indexes in tht text view
@@ -82,12 +82,12 @@ class Highlighter: NSObject {
8282

8383
highlightProvider?.setLanguage(codeLanguage: language)
8484

85-
guard textView.textContentStorage.textStorage != nil else {
85+
guard textView.textContentStorage?.textStorage != nil else {
8686
assertionFailure("Text view does not have a textStorage")
8787
return
8888
}
8989

90-
textView.textContentStorage.textStorage?.delegate = self
90+
textView.textContentStorage?.textStorage?.delegate = self
9191
highlightProvider?.setUp(textView: textView)
9292

9393
if let scrollView = textView.enclosingScrollView {
@@ -188,7 +188,7 @@ private extension Highlighter {
188188
}
189189

190190
// Loop through each highlight and modify the textStorage accordingly.
191-
textView.textContentStorage.textStorage?.beginEditing()
191+
textView.textContentStorage?.textStorage?.beginEditing()
192192

193193
// Create a set of indexes that were not highlighted.
194194
var ignoredIndexes = IndexSet(integersIn: rangeToHighlight)
@@ -200,7 +200,7 @@ private extension Highlighter {
200200
// for: NSTextRange(highlight.range,
201201
// provider: textView.textContentStorage)!)
202202
// Temp solution (until Apple fixes above)
203-
textView.textContentStorage.textStorage?.setAttributes(
203+
textView.textContentStorage?.textStorage?.setAttributes(
204204
attributeProvider.attributesFor(highlight.capture),
205205
range: highlight.range
206206
)
@@ -213,13 +213,13 @@ private extension Highlighter {
213213
// This fixes the case where characters are changed to have a non-text color, and then are skipped when
214214
// they need to be changed back.
215215
for ignoredRange in ignoredIndexes.rangeView {
216-
textView.textContentStorage.textStorage?.setAttributes(
216+
textView.textContentStorage?.textStorage?.setAttributes(
217217
attributeProvider.attributesFor(nil),
218218
range: NSRange(ignoredRange)
219219
)
220220
}
221221

222-
textView.textContentStorage.textStorage?.endEditing()
222+
textView.textContentStorage?.textStorage?.endEditing()
223223

224224
// After applying edits to the text storage we need to invalidate the layout
225225
// of the highlighted text.

Sources/CodeEditTextView/Highlighting/HighlighterTextView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ public protocol HighlighterTextView {
2121
extension STTextView: HighlighterTextView {
2222
public var documentRange: NSRange {
2323
return NSRange(location: 0,
24-
length: textContentStorage.textStorage?.length ?? 0)
24+
length: textContentStorage?.textStorage?.length ?? 0)
2525
}
2626

2727
public func stringForRange(_ nsRange: NSRange) -> String? {
28-
return textContentStorage.textStorage?.mutableString.substring(with: nsRange)
28+
return textContentStorage?.textStorage?.mutableString.substring(with: nsRange)
2929
}
3030
}

0 commit comments

Comments
 (0)