Skip to content

Commit 910fe88

Browse files
committed
Fix initial status bar cursor position
1 parent cec6287 commit 910fe88

4 files changed

Lines changed: 43 additions & 4 deletions

File tree

CodeEdit/Features/Editor/Models/EditorInstance.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import CodeEditSourceEditor
1414
/// A single instance of an editor in a group with a published ``EditorInstance/cursorPositions`` variable to publish
1515
/// the user's current location in a file.
1616
class EditorInstance: ObservableObject, Hashable {
17+
private static let defaultCursorPositions = [CursorPosition(line: 1, column: 1)]
18+
1719
/// The file presented in this editor instance.
1820
let file: CEWorkspaceFile
1921

@@ -43,9 +45,10 @@ class EditorInstance: ObservableObject, Hashable {
4345
replaceText = workspace?.searchState?.replaceText
4446
replaceTextSubject = PassthroughSubject()
4547

46-
self.cursorPositions = (
47-
cursorPositions ?? editorState?.editorCursorPositions ?? [CursorPosition(line: 1, column: 1)]
48-
)
48+
let restoredCursorPositions = editorState?.editorCursorPositions
49+
self.cursorPositions = cursorPositions
50+
?? (restoredCursorPositions?.isEmpty == false ? restoredCursorPositions : nil)
51+
?? Self.defaultCursorPositions
4952
self.scrollPosition = editorState?.scrollPosition
5053

5154
// Setup listeners
@@ -124,6 +127,8 @@ class EditorInstance: ObservableObject, Hashable {
124127

125128
/// Translates ranges (eg: from a cursor position) to other information like the number of lines in a range.
126129
class RangeTranslator: TextViewCoordinator {
130+
let controllerDidAppearSubject = PassthroughSubject<Void, Never>()
131+
127132
private weak var textViewController: TextViewController?
128133

129134
init() { }
@@ -136,6 +141,7 @@ class EditorInstance: ObservableObject, Hashable {
136141
if controller.isEditable && controller.isSelectable {
137142
controller.view.window?.makeFirstResponder(controller.textView)
138143
}
144+
controllerDidAppearSubject.send()
139145
}
140146

141147
func destroy() {
@@ -158,6 +164,10 @@ class EditorInstance: ObservableObject, Hashable {
158164
return (endTextLine.index - startTextLine.index) + 1
159165
}
160166

167+
func resolveCursorPosition(_ cursorPosition: CursorPosition) -> CursorPosition {
168+
textViewController?.resolveCursorPosition(cursorPosition) ?? cursorPosition
169+
}
170+
161171
func moveLinesUp() {
162172
guard let controller = textViewController else { return }
163173
controller.moveLinesUp()

CodeEdit/Features/Editor/Views/CodeFileView.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ struct CodeFileView: View {
158158
)
159159
},
160160
set: { newState in
161-
editorInstance.cursorPositions = newState.cursorPositions ?? []
161+
if let cursorPositions = newState.cursorPositions {
162+
editorInstance.cursorPositions = cursorPositions
163+
}
162164
editorInstance.scrollPosition = newState.scrollPosition
163165
editorInstance.findText = newState.findText
164166
editorInstance.findTextSubject.send(newState.findText)

CodeEdit/Features/StatusBar/Views/StatusBarItems/StatusBarCursorPositionLabel.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ struct StatusBarCursorPositionLabel: View {
3535
.onAppear {
3636
updateSource()
3737
}
38+
.onReceive(editorManager.$activeEditor) { _ in
39+
updateSource()
40+
}
3841
.onReceive(editorManager.tabBarTabIdSubject) { _ in
3942
updateSource()
4043
}
@@ -54,6 +57,7 @@ struct StatusBarCursorPositionLabel: View {
5457

5558
init(editorInstance: EditorInstance) {
5659
self.editorInstance = editorInstance
60+
self._cursorPositions = State(initialValue: editorInstance.cursorPositions)
5761
}
5862

5963
var body: some View {
@@ -64,6 +68,9 @@ struct StatusBarCursorPositionLabel: View {
6468
.onReceive(editorInstance.$cursorPositions) { newValue in
6569
self.cursorPositions = newValue
6670
}
71+
.onReceive(editorInstance.rangeTranslator.controllerDidAppearSubject) { _ in
72+
self.cursorPositions = editorInstance.cursorPositions
73+
}
6774
}
6875

6976
private var foregroundColor: Color {
@@ -84,6 +91,8 @@ struct StatusBarCursorPositionLabel: View {
8491
/// Create a label string for cursor positions.
8592
/// - Returns: A string describing the user's location in a document.
8693
func getLabel() -> String {
94+
let cursorPositions = cursorPositions.map(editorInstance.rangeTranslator.resolveCursorPosition)
95+
8796
if cursorPositions.isEmpty {
8897
return ""
8998
}
@@ -115,6 +124,13 @@ struct StatusBarCursorPositionLabel: View {
115124
}
116125

117126
// When there's a single cursor, display the line and column.
127+
if cursorPositions[0].start.line <= 0 || cursorPositions[0].start.column <= 0 {
128+
if cursorPositions[0].range != .notFound && cursorPositions[0].range.location > 0 {
129+
return "Char: \(cursorPositions[0].range.location) Len: 0"
130+
}
131+
return "Line: 1 Col: 1"
132+
}
133+
118134
return "Line: \(cursorPositions[0].start.line) Col: \(cursorPositions[0].start.column)"
119135
}
120136
}

CodeEditUITests/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorUITests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ final class ProjectNavigatorUITests: XCTestCase {
3939
XCTAssertTrue(readmeEditor.exists)
4040
XCTAssertNotNil(readmeEditor.value as? String)
4141

42+
let cursorPositionLabel = window.staticTexts["CursorPositionLabel"]
43+
XCTAssertTrue(cursorPositionLabel.waitForExistence(timeout: 2.0), "Cursor position label not found")
44+
45+
let resolvedCursorPosition = NSPredicate(
46+
format: "value CONTAINS %@ AND NOT value CONTAINS %@",
47+
"Line:",
48+
"-1"
49+
)
50+
expectation(for: resolvedCursorPosition, evaluatedWith: cursorPositionLabel)
51+
waitForExpectations(timeout: 2.0)
52+
4253
let rowCount = navigator.descendants(matching: .outlineRow).count
4354

4455
// Open a folder

0 commit comments

Comments
 (0)