Skip to content

Commit 0608dda

Browse files
committed
Update Documentation and README Examples
1 parent 368c54d commit 0608dda

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

README.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,28 @@ This package is fully documented [here](https://codeeditapp.github.io/CodeEditSo
3838

3939
## Usage (SwiftUI)
4040

41+
CodeEditSourceEditor provides two APIs for creating an editor: SwiftUI and AppKit. The SwiftUI API provides extremely customizable and flexible configuration options, including two-way bindings for state like cursor positions and scroll position.
42+
43+
For more complex features that require access to the underlying text view or text storage, we've developed the <doc:TextViewCoordinators> API. Using this API, developers can inject custom behavior into the editor as events happen, without having to work with state or bindings.
44+
4145
```swift
4246
import CodeEditSourceEditor
4347

4448
struct ContentView: View {
4549
@State var text = "let x = 1.0"
4650

47-
/// Automatically updates with cursor positions, or update the binding to set the user's cursors.
48-
@State var cursorPositions: [CursorPosition] = []
51+
/// Automatically updates with cursor positions, scroll position, find panel text.
52+
/// Everything in this object is two-way, use it to update cursor positions, scroll position, etc.
53+
@State var editorState = SourceEditorState()
4954

5055
/// Configure the editor's appearance, features, and editing behavior...
5156
@State var theme = EditorTheme(...)
5257
@State var font = NSFont.monospacedSystemFont(ofSize: 11, weight: .regular)
5358
@State var indentOption = .spaces(count: 4)
5459

60+
/// *Powerful* customization options with our text view coordinators API
61+
@State var autoCompleteCoordinator = AutoCompleteCoordinator()
62+
5563
var body: some View {
5664
SourceEditor(
5765
$text,
@@ -61,9 +69,27 @@ struct ContentView: View {
6169
appearance: .init(theme: theme, font: font),
6270
behavior: .init(indentOption: indentOption)
6371
),
64-
cursorPositions: $cursorPositions
72+
state: $editorState,
73+
coordinators: [autoCompleteCoordinator]
6574
)
6675
}
76+
77+
/// Autocompletes "Hello" to "Hello world!" whenever it's typed.
78+
final class AutoCompleteCoordinator: TextViewCoordinator {
79+
func prepareCoordinator(controller: TextViewController) { }
80+
81+
func textViewDidChangeText(controller: TextViewController) {
82+
for cursorPosition in controller.cursorPositions where cursorPosition.range.location >= 5 {
83+
let location = cursorPosition.range.location
84+
let previousRange = NSRange(start: location - 5, end: location)
85+
let string = (controller.text as NSString).substring(with: previousRange)
86+
87+
if string.lowercased() == "hello" {
88+
controller.textView.replaceCharacters(in: NSRange(location: location, length: 0), with: " world!")
89+
}
90+
}
91+
}
92+
}
6793
}
6894
```
6995

Sources/CodeEditSourceEditor/Documentation.docc/SourceEditor.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
## Usage
44

5-
CodeEditSourceEditor provides two APIs for creating an editor: SwiftUI and AppKit.
5+
CodeEditSourceEditor provides two APIs for creating an editor: SwiftUI and AppKit. We provide a fast and efficient SwiftUI API that avoids unnecessary view updates whenever possible. It also provides extremely customizable and flexible configuration options, including two-way bindings for state like cursor positions and scroll position.
6+
7+
For more complex features that require access to the underlying text view or text storage, we've developed the <doc:TextViewCoordinators> API. Using this API, developers can inject custom behavior into the editor as events happen, without having to work with state or bindings.
68

79
#### SwiftUI
810

@@ -12,11 +14,12 @@ import CodeEditSourceEditor
1214
struct ContentView: View {
1315

1416
@State var text = "let x = 1.0"
15-
// For large documents use (avoids SwiftUI inneficiency)
17+
// For large documents use a text storage object (avoids SwiftUI comparisons)
1618
// var text: NSTextStorage
1719

18-
/// Automatically updates with cursor positions, or update the binding to set the user's cursors.
19-
@State var cursorPositions: [CursorPosition] = []
20+
/// Automatically updates with cursor positions, scroll position, find panel text.
21+
/// Everything in this object is two-way, use it to update cursor positions, scroll position, etc.
22+
@State var editorState = SourceEditorState()
2023

2124
/// Configure the editor's appearance, features, and editing behavior...
2225
@State var theme = EditorTheme(...)
@@ -25,6 +28,9 @@ struct ContentView: View {
2528
@State var editorOverscroll = 0.3
2629
@State var showMinimap = true
2730

31+
/// *Powerful* customization options with text coordinators
32+
@State var autoCompleteCoordinator = AutoCompleteCoordinator()
33+
2834
var body: some View {
2935
SourceEditor(
3036
$text,
@@ -35,9 +41,27 @@ struct ContentView: View {
3541
layout: .init(editorOverscroll: editorOverscroll),
3642
peripherals: .init(showMinimap: showMinimap)
3743
),
38-
cursorPositions: $cursorPositions
44+
state: $editorState,
45+
coordinators: [autoCompleteCoordinator]
3946
)
4047
}
48+
49+
/// Autocompletes "Hello" to "Hello world!" whenever it's typed.
50+
class AutoCompleteCoordinator: TextViewCoordinator {
51+
func prepareCoordinator(controller: TextViewController) { }
52+
53+
func textViewDidChangeText(controller: TextViewController) {
54+
for cursorPosition in controller.cursorPositions.reversed() where cursorPosition.range.location >= 5 {
55+
let location = cursorPosition.range.location
56+
let previousRange = NSRange(start: location - 5, end: location)
57+
let string = (controller.text as NSString).substring(with: previousRange)
58+
59+
if string.lowercased() == "hello" {
60+
controller.textView.replaceCharacters(in: NSRange(location: location, length: 0), with: " world!")
61+
}
62+
}
63+
}
64+
}
4165
}
4266
```
4367

0 commit comments

Comments
 (0)