Skip to content

Commit 6af339c

Browse files
committed
Indent wrapped lines (CodeEditTextView #18): settings, UI, tests; git status skip unknown types; lint fixes
- Add wrappedLineIndent setting and UI in Text Editing preferences - Add TextEditingSettingsTests for wrapped line indent - GitClient+Status: skip unknown porcelain v2 entry types instead of throwing - Lint: shorten doc comment, strip trailing whitespace in WorkspaceView - CodeFileView: pass wrappedLineIndent when using local CodeEditSourceEditor
1 parent cec6287 commit 6af339c

File tree

6 files changed

+96
-2
lines changed

6 files changed

+96
-2
lines changed

CodeEdit/Features/Editor/Views/CodeFileView.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ struct CodeFileView: View {
3131
var lineHeightMultiple
3232
@AppSettings(\.textEditing.wrapLinesToEditorWidth)
3333
var wrapLinesToEditorWidth
34+
@AppSettings(\.textEditing.wrappedLineIndent)
35+
var wrappedLineIndent
3436
@AppSettings(\.textEditing.overscroll)
3537
var overscroll
3638
@AppSettings(\.textEditing.font)
@@ -125,6 +127,7 @@ struct CodeFileView: View {
125127
lineHeightMultiple: lineHeightMultiple,
126128
letterSpacing: letterSpacing,
127129
wrapLines: wrapLinesToEditorWidth,
130+
wrappedLineIndent: wrappedLineIndent,
128131
useSystemCursor: useSystemCursor,
129132
tabWidth: defaultTabWidth,
130133
bracketPairEmphasis: getBracketPairEmphasis()

CodeEdit/Features/Settings/Pages/TextEditingSettings/Models/TextEditingSettings.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extension SettingsData {
1818
"Prefer Indent Using",
1919
"Tab Width",
2020
"Wrap lines to editor width",
21+
"Indent wrapped lines",
2122
"Editor Overscroll",
2223
"Font",
2324
"Font Size",
@@ -60,6 +61,11 @@ extension SettingsData {
6061
/// A flag indicating whether to wrap lines to editor width
6162
var wrapLinesToEditorWidth: Bool = true
6263

64+
/// Spaces to indent continuation lines when line wrapping
65+
/// is on (e.g. 4 or 12). See:
66+
/// https://github.com/CodeEditApp/CodeEditTextView/issues/18
67+
var wrappedLineIndent: Int = 4
68+
6369
/// The percentage of overscroll to apply to the text view
6470
var overscroll: OverscrollOption = .medium
6571

@@ -122,6 +128,10 @@ extension SettingsData {
122128
Bool.self,
123129
forKey: .wrapLinesToEditorWidth
124130
) ?? true
131+
self.wrappedLineIndent = try container.decodeIfPresent(
132+
Int.self,
133+
forKey: .wrappedLineIndent
134+
) ?? 4
125135
self.overscroll = try container.decodeIfPresent(
126136
OverscrollOption.self,
127137
forKey: .overscroll

CodeEdit/Features/Settings/Pages/TextEditingSettings/TextEditingSettingsView.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct TextEditingSettingsView: View {
2121
indentOption
2222
defaultTabWidth
2323
wrapLinesToEditorWidth
24+
wrappedLineIndent
2425
useSystemCursor
2526
overscroll
2627
}
@@ -86,6 +87,25 @@ private extension TextEditingSettingsView {
8687
Toggle("Wrap lines to editor width", isOn: $textEditing.wrapLinesToEditorWidth)
8788
}
8889

90+
@ViewBuilder private var wrappedLineIndent: some View {
91+
HStack(alignment: .top) {
92+
Stepper(
93+
"Indent wrapped lines",
94+
value: Binding<Double>(
95+
get: { Double(textEditing.wrappedLineIndent) },
96+
set: { textEditing.wrappedLineIndent = Int($0) }
97+
),
98+
in: 0...24,
99+
step: 1,
100+
format: .number
101+
)
102+
Text("spaces")
103+
.foregroundColor(.secondary)
104+
}
105+
.disabled(!textEditing.wrapLinesToEditorWidth)
106+
.help("Number of spaces to indent continuation lines when line wrapping is on (e.g. like Xcode).")
107+
}
108+
89109
@ViewBuilder private var useSystemCursor: some View {
90110
if #available(macOS 14, *) {
91111
Toggle("Use System Cursor", isOn: $textEditing.useSystemCursor)

CodeEdit/Features/SourceControl/Client/GitClient+Status.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ extension GitClient {
7575
case "!", "#": // Ignored files or Header
7676
try substringToNextNull(from: &index, output: output) // move the index to the next line.
7777
default:
78-
throw GitClientError.statusInvalidChangeType(output[typeIndex])
78+
// Skip unknown entry types (e.g. future porcelain v2 types or unexpected output)
79+
try substringToNextNull(from: &index, output: output)
7980
}
8081
}
8182

CodeEdit/WorkspaceView.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ struct WorkspaceView: View {
8787
.task {
8888
// Only refresh git data if source control is enabled
8989
guard sourceControlIsEnabled else { return }
90-
9190
do {
9291
try await sourceControlManager.refreshRemotes()
9392
try await sourceControlManager.refreshStashEntries()
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//
2+
// TextEditingSettingsTests.swift
3+
// CodeEditTests
4+
//
5+
// Tests for Text Editing settings, including wrapped line indent (CodeEditTextView #18).
6+
//
7+
8+
import Foundation
9+
import Testing
10+
@testable import CodeEdit
11+
12+
@Suite("Text Editing Settings")
13+
struct TextEditingSettingsTests {
14+
15+
// MARK: - Wrapped line indent (indent wrapped lines - CodeEditTextView #18)
16+
17+
@Test("Default wrapped line indent is 4 spaces")
18+
func defaultWrappedLineIndentIsFour() {
19+
let settings = SettingsData.TextEditingSettings()
20+
#expect(settings.wrappedLineIndent == 4)
21+
}
22+
23+
@Test("Wrapped line indent round-trips through Codable")
24+
func wrappedLineIndentRoundTrips() throws {
25+
var settings = SettingsData.TextEditingSettings()
26+
settings.wrappedLineIndent = 12
27+
28+
let encoded = try JSONEncoder().encode(settings)
29+
let decoded = try JSONDecoder().decode(SettingsData.TextEditingSettings.self, from: encoded)
30+
#expect(decoded.wrappedLineIndent == 12)
31+
}
32+
33+
@Test("Decode with missing wrappedLineIndent uses default 4")
34+
func decodeMissingWrappedLineIndentUsesDefault() throws {
35+
// JSON without wrappedLineIndent key (e.g. existing user preferences)
36+
let json = """
37+
{"wrapLinesToEditorWidth": true}
38+
"""
39+
let data = json.data(using: .utf8)!
40+
// Decode a minimal object; TextEditingSettings init(from:) decodes each key with default
41+
let decoded = try JSONDecoder().decode(SettingsData.TextEditingSettings.self, from: data)
42+
#expect(decoded.wrappedLineIndent == 4)
43+
}
44+
45+
@Test("Wrapped line indent accepts valid range 0–24")
46+
func wrappedLineIndentValidRange() throws {
47+
for value in [0, 4, 8, 12, 24] {
48+
var settings = SettingsData.TextEditingSettings()
49+
settings.wrappedLineIndent = value
50+
let encoded = try JSONEncoder().encode(settings)
51+
let decoded = try JSONDecoder().decode(SettingsData.TextEditingSettings.self, from: encoded)
52+
#expect(decoded.wrappedLineIndent == value)
53+
}
54+
}
55+
56+
@Test("Wrap lines to editor width default is true")
57+
func wrapLinesToEditorWidthDefault() {
58+
let settings = SettingsData.TextEditingSettings()
59+
#expect(settings.wrapLinesToEditorWidth == true)
60+
}
61+
}

0 commit comments

Comments
 (0)