Skip to content

Commit b96f270

Browse files
Find: Replace and Match Case Toggle (#301)
### Description This PR adds the following functionality to the source editor find panel: - Replace: Enables replacing matched text with the specified replacement. - Toggle Match Navigation Wrap-Around: Allows cycling through matches from the beginning when reaching the end. - Toggle Match Case: Adds an option to filter matches by case sensitivity. - Made find panel responsive at small sizes using `ViewThatFits`. ### Related Issues * #295 * CodeEditApp/CodeEditTextView#1 ### Checklist <!--- Add things that are not yet implemented above --> - [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 https://github.com/user-attachments/assets/ec23ffe7-6d24-48b7-889a-11a92ec6c147 https://github.com/user-attachments/assets/cfca6d8e-7b97-4258-ae2e-ee82bbf6b9af --------- Co-authored-by: Khan Winter <35942988+thecoolwinter@users.noreply.github.com>
1 parent 3dccebd commit b96f270

34 files changed

+1489
-646
lines changed

Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.resolved

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ let package = Package(
2424
url: "https://github.com/CodeEditApp/CodeEditLanguages.git",
2525
exact: "0.1.20"
2626
),
27+
// CodeEditSymbols
28+
.package(
29+
url: "https://github.com/CodeEditApp/CodeEditSymbols.git",
30+
exact: "0.2.3"
31+
),
2732
// SwiftLint
2833
.package(
2934
url: "https://github.com/lukepistrol/SwiftLintPlugin",
@@ -43,7 +48,8 @@ let package = Package(
4348
dependencies: [
4449
"CodeEditTextView",
4550
"CodeEditLanguages",
46-
"TextFormation"
51+
"TextFormation",
52+
"CodeEditSymbols"
4753
],
4854
plugins: [
4955
.plugin(name: "SwiftLint", package: "SwiftLintPlugin")

Sources/CodeEditSourceEditor/Controller/TextViewController+Cursor.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import AppKit
1111
extension TextViewController {
1212
/// Sets new cursor positions.
1313
/// - Parameter positions: The positions to set. Lines and columns are 1-indexed.
14-
public func setCursorPositions(_ positions: [CursorPosition]) {
14+
public func setCursorPositions(_ positions: [CursorPosition], scrollToVisible: Bool = false) {
1515
if isPostingCursorNotification { return }
1616
var newSelectedRanges: [NSRange] = []
1717
for position in positions {
@@ -33,6 +33,10 @@ extension TextViewController {
3333
}
3434
}
3535
textView.selectionManager.setSelectedRanges(newSelectedRanges)
36+
37+
if scrollToVisible {
38+
textView.scrollSelectionToVisible()
39+
}
3640
}
3741

3842
/// Update the ``TextViewController/cursorPositions`` variable with new text selections from the text view.

Sources/CodeEditSourceEditor/Controller/TextViewController+FindPanelTarget.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
// Created by Khan Winter on 3/16/25.
66
//
77

8-
import Foundation
8+
import AppKit
99
import CodeEditTextView
1010

1111
extension TextViewController: FindPanelTarget {
12+
var findPanelTargetView: NSView {
13+
textView
14+
}
15+
1216
func findPanelWillShow(panelHeight: CGFloat) {
1317
updateContentInsets()
1418
}
@@ -17,6 +21,10 @@ extension TextViewController: FindPanelTarget {
1721
updateContentInsets()
1822
}
1923

24+
func findPanelModeDidChange(to mode: FindPanelMode) {
25+
updateContentInsets()
26+
}
27+
2028
var emphasisManager: EmphasisManager? {
2129
textView?.emphasisManager
2230
}

Sources/CodeEditSourceEditor/Controller/TextViewController+LoadView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ extension TextViewController {
220220
self.findViewController?.showFindPanel()
221221
return nil
222222
case (0, "\u{1b}"): // Escape key
223-
self.findViewController?.findPanel.dismiss()
223+
self.findViewController?.hideFindPanel()
224224
return nil
225225
case (_, _):
226226
return event

Sources/CodeEditSourceEditor/Controller/TextViewController+StyleViews.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ extension TextViewController {
9696
minimapView.scrollView.contentInsets.bottom += additionalTextInsets?.bottom ?? 0
9797

9898
// Inset the top by the find panel height
99-
let findInset = (findViewController?.isShowingFindPanel ?? false) ? FindPanel.height : 0
99+
let findInset: CGFloat = if findViewController?.viewModel.isShowingFindPanel ?? false {
100+
findViewController?.viewModel.panelHeight ?? 0
101+
} else {
102+
0
103+
}
100104
scrollView.contentInsets.top += findInset
101105
minimapView.scrollView.contentInsets.top += findInset
102106

Sources/CodeEditSourceEditor/Find/FindPanelDelegate.swift

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// FindPanelMode.swift
3+
// CodeEditSourceEditor
4+
//
5+
// Created by Khan Winter on 4/18/25.
6+
//
7+
8+
enum FindPanelMode: CaseIterable {
9+
case find
10+
case replace
11+
12+
var displayName: String {
13+
switch self {
14+
case .find:
15+
return "Find"
16+
case .replace:
17+
return "Replace"
18+
}
19+
}
20+
}

Sources/CodeEditSourceEditor/Find/FindPanelTarget.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@
55
// Created by Khan Winter on 3/10/25.
66
//
77

8-
import Foundation
8+
import AppKit
99
import CodeEditTextView
1010

1111
protocol FindPanelTarget: AnyObject {
12-
var emphasisManager: EmphasisManager? { get }
13-
var text: String { get }
12+
var textView: TextView! { get }
13+
var findPanelTargetView: NSView { get }
1414

1515
var cursorPositions: [CursorPosition] { get }
16-
func setCursorPositions(_ positions: [CursorPosition])
16+
func setCursorPositions(_ positions: [CursorPosition], scrollToVisible: Bool)
1717
func updateCursorPosition()
1818

1919
func findPanelWillShow(panelHeight: CGFloat)
2020
func findPanelWillHide(panelHeight: CGFloat)
21+
func findPanelModeDidChange(to mode: FindPanelMode)
2122
}

0 commit comments

Comments
 (0)