Skip to content

Commit bb72694

Browse files
Improve Editor Configuration, Rename to SourceEditor (CodeEditApp#336)
### Description Improved the organization of our editor's configuration options by organizing them into a separate type from the SwiftUI API. This type is further organized into four structs based on the configuration option's effect on the editor. #### Detailed Changes - Creates a new `SourceEditorConfiguration` struct. - Passed to `CodeEditSourceEditor` and `TextViewController` to update configuration. - One single object for all configuration that doesn't usually change during editing (no state is stored here). - Has an efficient method for updating the editor for a new configuration (moved from `CodeEditSourceEditor`'s SwiftUI update method to `SourceEditorConfiguration`). - Organized into four categories: appearance, behavior, layout, and peripherals. Each has it's own documentation. - Adds a new API for toggling the gutter view. - Renames `CodeEditSourceEditor` to `SourceEditor` (requested by @austincondiff). - Updates docc docs to reflect new API. - Updates README to reflect new API (as well as a few missing/broken links). I found a small bug with the refactor guide while making these changes. I may move them out of this PR. ### Related Issues * closes CodeEditApp#115 * closes CodeEditApp#319 ### 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 N/A no content changes
1 parent c2fdc98 commit bb72694

33 files changed

+1044
-1052
lines changed

Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample/Views/ContentView.swift

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,28 @@ struct ContentView: View {
1919

2020
@State private var language: CodeLanguage = .default
2121
@State private var theme: EditorTheme = .light
22+
@State private var cursorPositions: [CursorPosition] = [.init(line: 1, column: 1)]
23+
2224
@State private var font: NSFont = NSFont.monospacedSystemFont(ofSize: 12, weight: .medium)
2325
@AppStorage("wrapLines") private var wrapLines: Bool = true
24-
@State private var cursorPositions: [CursorPosition] = [.init(line: 1, column: 1)]
2526
@AppStorage("systemCursor") private var useSystemCursor: Bool = false
26-
@State private var isInLongParse = false
27-
@State private var settingsIsPresented: Bool = false
28-
@State private var treeSitterClient = TreeSitterClient()
29-
@AppStorage("showMinimap") private var showMinimap: Bool = true
3027
@State private var indentOption: IndentOption = .spaces(count: 4)
3128
@AppStorage("reformatAtColumn") private var reformatAtColumn: Int = 80
29+
30+
@AppStorage("showGutter") private var showGutter: Bool = true
31+
@AppStorage("showMinimap") private var showMinimap: Bool = true
3232
@AppStorage("showReformattingGuide") private var showReformattingGuide: Bool = false
33-
@State private var invisibleCharactersConfig: InvisibleCharactersConfig = .empty
33+
@State private var invisibleCharactersConfig: InvisibleCharactersConfiguration = .empty
34+
@State private var warningCharacters: Set<UInt16> = []
35+
36+
@State private var isInLongParse = false
37+
@State private var settingsIsPresented: Bool = false
38+
39+
@State private var treeSitterClient = TreeSitterClient()
40+
41+
private func contentInsets(proxy: GeometryProxy) -> NSEdgeInsets {
42+
NSEdgeInsets(top: proxy.safeAreaInsets.top, left: showGutter ? 0 : 1, bottom: 28.0, right: 0)
43+
}
3444

3545
init(document: Binding<CodeEditSourceEditorExampleDocument>, fileURL: URL?) {
3646
self._document = document
@@ -39,26 +49,25 @@ struct ContentView: View {
3949

4050
var body: some View {
4151
GeometryReader { proxy in
42-
CodeEditSourceEditor(
52+
SourceEditor(
4353
document.text,
4454
language: language,
45-
theme: theme,
46-
font: font,
47-
tabWidth: 4,
48-
indentOption: indentOption,
49-
lineHeight: 1.2,
50-
wrapLines: wrapLines,
51-
editorOverscroll: 0.3,
52-
cursorPositions: $cursorPositions,
53-
useThemeBackground: true,
54-
highlightProviders: [treeSitterClient],
55-
contentInsets: NSEdgeInsets(top: proxy.safeAreaInsets.top, left: 0, bottom: 28.0, right: 0),
56-
additionalTextInsets: NSEdgeInsets(top: 1, left: 0, bottom: 1, right: 0),
57-
useSystemCursor: useSystemCursor,
58-
showMinimap: showMinimap,
59-
reformatAtColumn: reformatAtColumn,
60-
showReformattingGuide: showReformattingGuide,
61-
invisibleCharactersConfig: invisibleCharactersConfig
55+
configuration: SourceEditorConfiguration(
56+
appearance: .init(theme: theme, font: font, wrapLines: wrapLines),
57+
behavior: .init(
58+
indentOption: indentOption,
59+
reformatAtColumn: reformatAtColumn
60+
),
61+
layout: .init(contentInsets: contentInsets(proxy: proxy)),
62+
peripherals: .init(
63+
showGutter: showGutter,
64+
showMinimap: showMinimap,
65+
showReformattingGuide: showReformattingGuide,
66+
invisibleCharactersConfiguration: invisibleCharactersConfig,
67+
warningCharacters: warningCharacters
68+
)
69+
),
70+
cursorPositions: $cursorPositions
6271
)
6372
.overlay(alignment: .bottom) {
6473
StatusBar(
@@ -70,11 +79,13 @@ struct ContentView: View {
7079
isInLongParse: $isInLongParse,
7180
language: $language,
7281
theme: $theme,
82+
showGutter: $showGutter,
7383
showMinimap: $showMinimap,
7484
indentOption: $indentOption,
7585
reformatAtColumn: $reformatAtColumn,
7686
showReformattingGuide: $showReformattingGuide,
77-
invisibles: $invisibleCharactersConfig
87+
invisibles: $invisibleCharactersConfig,
88+
warningCharacters: $warningCharacters
7889
)
7990
}
8091
.ignoresSafeArea()

Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample/Views/StatusBar.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,21 @@ struct StatusBar: View {
2222
@Binding var isInLongParse: Bool
2323
@Binding var language: CodeLanguage
2424
@Binding var theme: EditorTheme
25+
@Binding var showGutter: Bool
2526
@Binding var showMinimap: Bool
2627
@Binding var indentOption: IndentOption
2728
@Binding var reformatAtColumn: Int
2829
@Binding var showReformattingGuide: Bool
29-
@Binding var invisibles: InvisibleCharactersConfig
30+
@Binding var invisibles: InvisibleCharactersConfiguration
31+
@Binding var warningCharacters: Set<UInt16>
3032

3133
var body: some View {
3234
HStack {
3335
Menu {
3436
IndentPicker(indentOption: $indentOption, enabled: document.text.length == 0)
3537
.buttonStyle(.borderless)
3638
Toggle("Wrap Lines", isOn: $wrapLines)
39+
Toggle("Show Gutter", isOn: $showGutter)
3740
Toggle("Show Minimap", isOn: $showMinimap)
3841
Toggle("Show Reformatting Guide", isOn: $showReformattingGuide)
3942
Picker("Reformat column at column", selection: $reformatAtColumn) {
@@ -61,16 +64,16 @@ struct StatusBar: View {
6164
"Warning Characters",
6265
isOn: Binding(
6366
get: {
64-
!invisibles.warningCharacters.isEmpty
67+
!warningCharacters.isEmpty
6568
},
6669
set: { newValue in
6770
// In this example app, we only add one character
6871
// For real apps, consider providing a table where users can add UTF16
6972
// char codes to warn about, as well as a set of good defaults.
7073
if newValue {
71-
invisibles.warningCharacters.insert(0x200B) // zero-width space
74+
warningCharacters.insert(0x200B) // zero-width space
7275
} else {
73-
invisibles.warningCharacters.removeAll()
76+
warningCharacters.removeAll()
7477
}
7578
}
7679
)

README.md

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55

66

77
<p align="center">
8-
<a aria-label="Follow CodeEdit on Twitter" href="https://twitter.com/CodeEditApp" target="_blank">
9-
<img alt="" src="https://img.shields.io/badge/Follow%[email protected]?style=for-the-badge&logo=Twitter">
8+
<a aria-label="Follow CodeEdit on X" href="https://x.com/CodeEditApp" target="_blank">
9+
<img alt="" src="https://img.shields.io/badge/Follow%[email protected]?style=for-the-badge&logo=X">
10+
</a>
11+
<a aria-label="Follow CodeEdit on Bluesky" href="https://bsky.app/profile/codeedit.app" target="_blank">
12+
<img alt="" src="https://img.shields.io/badge/Follow%[email protected]?style=for-the-badge&logo=Bluesky">
1013
</a>
1114
<a aria-label="Join the community on Discord" href="https://discord.gg/vChUXVf9Em" target="_blank">
1215
<img alt="" src="https://img.shields.io/badge/Join%20the%20community-black.svg?style=for-the-badge&logo=Discord">
@@ -33,45 +36,50 @@ An Xcode-inspired code editor view written in Swift powered by tree-sitter for [
3336

3437
This package is fully documented [here](https://codeeditapp.github.io/CodeEditSourceEditor/documentation/codeeditsourceeditor/).
3538

36-
## Usage
39+
## Usage (SwiftUI)
3740

3841
```swift
3942
import CodeEditSourceEditor
4043

4144
struct ContentView: View {
42-
4345
@State var text = "let x = 1.0"
46+
47+
/// Automatically updates with cursor positions, or update the binding to set the user's cursors.
48+
@State var cursorPositions: [CursorPosition] = []
49+
50+
/// Configure the editor's appearance, features, and editing behavior...
4451
@State var theme = EditorTheme(...)
4552
@State var font = NSFont.monospacedSystemFont(ofSize: 11, weight: .regular)
46-
@State var tabWidth = 4
47-
@State var lineHeight = 1.2
48-
@State var editorOverscroll = 0.3
53+
@State var indentOption = .spaces(count: 4)
4954

5055
var body: some View {
51-
CodeEditSourceEditor(
56+
SourceEditor(
5257
$text,
53-
language: .swift,
54-
theme: $theme,
55-
font: $font,
56-
tabWidth: $tabWidth,
57-
lineHeight: $lineHeight,
58-
editorOverscroll: $editorOverscroll
58+
language: language,
59+
// Tons of customization options, with good defaults to get started quickly.
60+
configuration: SourceEditorConfiguration(
61+
appearance: .init(theme: theme, font: font),
62+
behavior: .init(indentOption: indentOption)
63+
),
64+
cursorPositions: $cursorPositions
5965
)
6066
}
6167
}
6268
```
6369

70+
An AppKit API is also available.
71+
6472
## Currently Supported Languages
6573

6674
See this issue https://github.com/CodeEditApp/CodeEditLanguages/issues/10 on `CodeEditLanguages` for more information on supported languages.
6775

6876
## Dependencies
6977

70-
Special thanks to [Matt Massicotte](https://twitter.com/mattie) for the great work he's done!
78+
Special thanks to [Matt Massicotte](https://bsky.app/profile/massicotte.org) for the great work he's done!
7179

7280
| Package | Source | Author |
7381
| :- | :- | :- |
74-
| `SwiftTreeSitter` | [GitHub](https://github.com/ChimeHQ/SwiftTreeSitter) | [Matt Massicotte](https://twitter.com/mattie) |
82+
| `SwiftTreeSitter` | [GitHub](https://github.com/ChimeHQ/SwiftTreeSitter) | [Matt Massicotte](https://bsky.app/profile/massicotte.org) |
7583

7684
## License
7785

0 commit comments

Comments
 (0)