Skip to content

Commit 938e279

Browse files
committed
Added replace all logic. Adjusted panel text field coloring.
1 parent 0b7a36c commit 938e279

File tree

6 files changed

+83
-14
lines changed

6 files changed

+83
-14
lines changed

Sources/CodeEditSourceEditor/CodeEditUI/PanelTextField.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,24 @@ struct PanelTextField<LeadingAccessories: View, TrailingAccessories: View>: View
6666
Color(.textBackgroundColor)
6767
} else {
6868
if colorScheme == .light {
69-
Color.black.opacity(0.06)
69+
// TODO: if over sidebar 0.06 else 0.085
70+
// Color.black.opacity(0.06)
71+
Color.black.opacity(0.085)
7072
} else {
71-
Color.white.opacity(0.24)
73+
// TODO: if over sidebar 0.24 else 0.06
74+
// Color.white.opacity(0.24)
75+
Color.white.opacity(0.06)
7276
}
7377
}
7478
} else {
7579
if colorScheme == .light {
76-
Color.clear
80+
// TODO: if over sidebar 0.0 else 0.06
81+
// Color.clear
82+
Color.black.opacity(0.06)
7783
} else {
78-
Color.white.opacity(0.14)
84+
// TODO: if over sidebar 0.14 else 0.045
85+
// Color.white.opacity(0.14)
86+
Color.white.opacity(0.045)
7987
}
8088
}
8189
}
@@ -98,6 +106,7 @@ struct PanelTextField<LeadingAccessories: View, TrailingAccessories: View>: View
98106
Text(helperText)
99107
.font(.caption)
100108
.foregroundStyle(.secondary)
109+
.lineLimit(1)
101110
}
102111
}
103112
if clearable == true {

Sources/CodeEditSourceEditor/Find/FindPanelDelegate.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ protocol FindPanelDelegate: AnyObject {
1818
func findPanelPrevButtonClicked()
1919
func findPanelNextButtonClicked()
2020
func findPanelReplaceButtonClicked()
21+
func findPanelReplaceAllButtonClicked()
2122
func findPanelUpdateMatchCount(_ count: Int)
2223
func findPanelClearEmphasis()
2324
}

Sources/CodeEditSourceEditor/Find/FindViewController+FindPanelDelegate.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@ extension FindViewController: FindPanelDelegate {
206206
replaceCurrentMatch()
207207
}
208208

209+
func findPanelReplaceAllButtonClicked() {
210+
guard !findMatches.isEmpty else { return }
211+
replaceAllMatches()
212+
}
213+
209214
func findPanelUpdateMatchCount(_ count: Int) {
210215
findPanel.updateMatchCount(count)
211216
}

Sources/CodeEditSourceEditor/Find/FindViewController+Operations.swift

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,6 @@ extension FindViewController {
8181
findMatches[index].location += lengthDiff
8282
}
8383

84-
// Remove the current match from the array
85-
findMatches.remove(at: currentFindMatchIndex)
86-
8784
// Keep the current index in bounds
8885
currentFindMatchIndex = min(currentFindMatchIndex, findMatches.count - 1)
8986
findPanel.findDelegate?.findPanelUpdateMatchCount(findMatches.count)
@@ -93,6 +90,52 @@ extension FindViewController {
9390
addEmphases()
9491
}
9592

93+
func replaceAllMatches() {
94+
guard let target = target,
95+
!findMatches.isEmpty,
96+
let textViewController = target as? TextViewController else { return }
97+
98+
// Sort matches in reverse order to avoid range shifting issues
99+
let sortedMatches = findMatches.sorted { $0.location > $1.location }
100+
101+
// Begin undo grouping using CEUndoManager
102+
if let ceUndoManager = textViewController.textView.undoManager as? CEUndoManager.DelegatedUndoManager {
103+
ceUndoManager.beginUndoGrouping()
104+
}
105+
106+
// Replace each match
107+
for matchRange in sortedMatches {
108+
// Set cursor positions to the match range
109+
target.setCursorPositions([CursorPosition(range: matchRange)])
110+
111+
// Replace the text using the cursor positions
112+
textViewController.textView.insertText(replaceText, replacementRange: matchRange)
113+
}
114+
115+
// End undo grouping
116+
if let ceUndoManager = textViewController.textView.undoManager as? CEUndoManager.DelegatedUndoManager {
117+
ceUndoManager.endUndoGrouping()
118+
}
119+
120+
// Set cursor position to the end of the last replaced match
121+
if let lastMatch = sortedMatches.first {
122+
let endPosition = lastMatch.location + replaceText.utf16.count
123+
let cursorRange = NSRange(location: endPosition, length: 0)
124+
target.setCursorPositions([CursorPosition(range: cursorRange)])
125+
textViewController.textView.selectionManager.setSelectedRanges([cursorRange])
126+
textViewController.textView.scrollSelectionToVisible()
127+
textViewController.textView.needsDisplay = true
128+
}
129+
130+
// Clear all matches since they've been replaced
131+
findMatches = []
132+
currentFindMatchIndex = 0
133+
findPanel.findDelegate?.findPanelUpdateMatchCount(0)
134+
135+
// Update the emphases
136+
addEmphases()
137+
}
138+
96139
func addEmphases() {
97140
guard let target = target,
98141
let emphasisManager = target.emphasisManager else { return }

Sources/CodeEditSourceEditor/Find/PanelView/FindPanelView.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ struct FindPanelView: View {
1616
@FocusState private var isReplaceFieldFocused: Bool
1717

1818
var body: some View {
19-
VStack(spacing: 5) {
19+
VStack(alignment: .leading, spacing: 5) {
2020
HStack(spacing: 5) {
2121
PanelTextField(
2222
"Text",
@@ -117,6 +117,7 @@ struct FindPanelView: View {
117117
leadingAccessories: {
118118
HStack(spacing: 0) {
119119
Image(systemName: "pencil")
120+
.foregroundStyle(.secondary)
120121
.padding(.leading, 8)
121122
.padding(.trailing, 5)
122123
Text("With")
@@ -135,20 +136,26 @@ struct FindPanelView: View {
135136
ControlGroup {
136137
Button(action: viewModel.replaceButtonClicked) {
137138
Text("Replace")
138-
.opacity(viewModel.findText.isEmpty || viewModel.matchCount == 0 ? 0.33 : 1)
139+
.opacity(
140+
!viewModel.isFocused
141+
|| viewModel.findText.isEmpty
142+
|| viewModel.matchCount == 0 ? 0.33 : 1
143+
)
139144
.frame(width: viewModel.findControlsWidth/2 - 12 - 0.5)
140145
}
141146
// TODO: disable if there is not an active match
142-
.disabled(viewModel.findText.isEmpty || viewModel.matchCount == 0)
147+
.disabled(
148+
!viewModel.isFocused
149+
|| viewModel.findText.isEmpty
150+
|| viewModel.matchCount == 0
151+
)
143152
Divider()
144153
.overlay(Color(nsColor: .tertiaryLabelColor))
145-
Button(action: {
146-
// TODO: Replace all action
147-
}, label: {
154+
Button(action: viewModel.replaceAllButtonClicked) {
148155
Text("All")
149156
.opacity(viewModel.findText.isEmpty || viewModel.matchCount == 0 ? 0.33 : 1)
150157
.frame(width: viewModel.findControlsWidth/2 - 12 - 0.5)
151-
})
158+
}
152159
.disabled(viewModel.findText.isEmpty || viewModel.matchCount == 0)
153160
}
154161
.controlGroupStyle(PanelControlGroupStyle())

Sources/CodeEditSourceEditor/Find/PanelView/FindPanelViewModel.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ class FindPanelViewModel: ObservableObject {
105105
delegate?.findPanelReplaceButtonClicked()
106106
}
107107

108+
func replaceAllButtonClicked() {
109+
delegate?.findPanelReplaceAllButtonClicked()
110+
}
111+
108112
func toggleWrapAround() {
109113
wrapAround.toggle()
110114
delegate?.findPanelDidUpdateWrapAround(wrapAround)

0 commit comments

Comments
 (0)