Skip to content

Commit f054983

Browse files
Added global search keyboard shortcut (#2094)
### Description Added the Cmd+Shift+F keyboard shortcut to open the search navigator and focuses the search field. ### Related Issues Closes #2093 ### 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 https://github.com/user-attachments/assets/a3e607b7-39a6-4da6-9ac7-38764113b621
1 parent 688dc84 commit f054983

File tree

5 files changed

+94
-56
lines changed

5 files changed

+94
-56
lines changed

CodeEdit/Features/Documents/Controllers/CodeEditWindowController.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,21 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
143143
}
144144
}
145145

146+
/// Opens the search navigator and focuses the search field
147+
@IBAction func openSearchNavigator(_ sender: Any? = nil) {
148+
if navigatorCollapsed {
149+
toggleFirstPanel()
150+
}
151+
152+
if let navigatorViewModel = navigatorSidebarViewModel,
153+
let searchTab = navigatorViewModel.tabItems.first(where: { $0 == .search }) {
154+
DispatchQueue.main.async {
155+
self.workspace?.searchState?.shouldFocusSearchField = true
156+
navigatorViewModel.setNavigatorTab(tab: searchTab)
157+
}
158+
}
159+
}
160+
146161
@IBAction func openQuickly(_ sender: Any?) {
147162
if let workspace, let state = workspace.openQuicklyViewModel {
148163
if let quickOpenPanel {

CodeEdit/Features/Documents/WorkspaceDocument/WorkspaceDocument+SearchState.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ extension WorkspaceDocument {
3535

3636
@Published var findNavigatorStatus: FindNavigatorStatus = .none
3737

38+
@Published var shouldFocusSearchField: Bool = false
39+
3840
unowned var workspace: WorkspaceDocument
3941
var tempSearchResults = [SearchResultModel]()
4042
var caseSensitive: Bool = false

CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorForm.swift

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,63 +25,13 @@ struct FindNavigatorForm: View {
2525
@State private var preserveCase: Bool = false
2626
@State private var scopedToOpenEditors: Bool = false
2727
@State private var excludeSettings: Bool = true
28+
@FocusState private var isSearchFieldFocused: Bool
2829

2930
init(state: WorkspaceDocument.SearchState) {
3031
self.state = state
3132
selectedMode = state.selectedMode
3233
}
3334

34-
private func getMenuList(_ index: Int) -> [SearchModeModel] {
35-
index == 0 ? SearchModeModel.SearchModes : selectedMode[index - 1].children
36-
}
37-
38-
private func onSelectMenuItem(_ index: Int, searchMode: SearchModeModel) {
39-
var newSelectedMode: [SearchModeModel] = []
40-
41-
switch index {
42-
case 0:
43-
newSelectedMode.append(searchMode)
44-
self.updateSelectedMode(searchMode, searchModel: &newSelectedMode)
45-
self.selectedMode = newSelectedMode
46-
case 1:
47-
if let firstMode = selectedMode.first {
48-
newSelectedMode.append(contentsOf: [firstMode, searchMode])
49-
if let thirdMode = searchMode.children.first {
50-
if let selectedThirdMode = selectedMode.third, searchMode.children.contains(selectedThirdMode) {
51-
newSelectedMode.append(selectedThirdMode)
52-
} else {
53-
newSelectedMode.append(thirdMode)
54-
}
55-
}
56-
}
57-
self.selectedMode = newSelectedMode
58-
case 2:
59-
if let firstMode = selectedMode.first, let secondMode = selectedMode.second {
60-
newSelectedMode.append(contentsOf: [firstMode, secondMode, searchMode])
61-
}
62-
self.selectedMode = newSelectedMode
63-
default:
64-
return
65-
}
66-
}
67-
68-
private func updateSelectedMode(_ searchMode: SearchModeModel, searchModel: inout [SearchModeModel]) {
69-
if let secondMode = searchMode.children.first {
70-
if let selectedSecondMode = selectedMode.second, searchMode.children.contains(selectedSecondMode) {
71-
searchModel.append(contentsOf: selectedMode.dropFirst())
72-
} else {
73-
searchModel.append(secondMode)
74-
if let thirdMode = secondMode.children.first, let selectedThirdMode = selectedMode.third {
75-
if secondMode.children.contains(selectedThirdMode) {
76-
searchModel.append(selectedThirdMode)
77-
} else {
78-
searchModel.append(thirdMode)
79-
}
80-
}
81-
}
82-
}
83-
}
84-
8535
private var chevron: some View {
8636
Image(systemName: "chevron.compact.right")
8737
.foregroundStyle(.tertiary)
@@ -152,6 +102,7 @@ struct FindNavigatorForm: View {
152102
},
153103
hasValue: caseSensitive
154104
)
105+
.focused($isSearchFieldFocused)
155106
.onSubmit {
156107
if !state.searchQuery.isEmpty {
157108
Task {
@@ -262,16 +213,65 @@ struct FindNavigatorForm: View {
262213
}
263214
}
264215
}
216+
.onReceive(state.$shouldFocusSearchField) { shouldFocus in
217+
if shouldFocus {
218+
isSearchFieldFocused = true
219+
state.shouldFocusSearchField = false
220+
}
221+
}
265222
.lineLimit(1...5)
266223
}
267224
}
268225

269-
extension Array {
270-
var second: Element? {
271-
self.count > 1 ? self[1] : nil
226+
extension FindNavigatorForm {
227+
private func getMenuList(_ index: Int) -> [SearchModeModel] {
228+
index == 0 ? SearchModeModel.SearchModes : selectedMode[index - 1].children
229+
}
230+
231+
private func onSelectMenuItem(_ index: Int, searchMode: SearchModeModel) {
232+
var newSelectedMode: [SearchModeModel] = []
233+
234+
switch index {
235+
case 0:
236+
newSelectedMode.append(searchMode)
237+
self.updateSelectedMode(searchMode, searchModel: &newSelectedMode)
238+
self.selectedMode = newSelectedMode
239+
case 1:
240+
if let firstMode = selectedMode.first {
241+
newSelectedMode.append(contentsOf: [firstMode, searchMode])
242+
if let thirdMode = searchMode.children.first {
243+
if let selectedThirdMode = selectedMode.third, searchMode.children.contains(selectedThirdMode) {
244+
newSelectedMode.append(selectedThirdMode)
245+
} else {
246+
newSelectedMode.append(thirdMode)
247+
}
248+
}
249+
}
250+
self.selectedMode = newSelectedMode
251+
case 2:
252+
if let firstMode = selectedMode.first, let secondMode = selectedMode.second {
253+
newSelectedMode.append(contentsOf: [firstMode, secondMode, searchMode])
254+
}
255+
self.selectedMode = newSelectedMode
256+
default:
257+
return
258+
}
272259
}
273260

274-
var third: Element? {
275-
self.count > 2 ? self[2] : nil
261+
private func updateSelectedMode(_ searchMode: SearchModeModel, searchModel: inout [SearchModeModel]) {
262+
if let secondMode = searchMode.children.first {
263+
if let selectedSecondMode = selectedMode.second, searchMode.children.contains(selectedSecondMode) {
264+
searchModel.append(contentsOf: selectedMode.dropFirst())
265+
} else {
266+
searchModel.append(secondMode)
267+
if let thirdMode = secondMode.children.first, let selectedThirdMode = selectedMode.third {
268+
if secondMode.children.contains(selectedThirdMode) {
269+
searchModel.append(selectedThirdMode)
270+
} else {
271+
searchModel.append(thirdMode)
272+
}
273+
}
274+
}
275+
}
276276
}
277277
}

CodeEdit/Features/WindowCommands/ViewCommands.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ struct ViewCommands: Commands {
3333
}
3434
.keyboardShortcut("p", modifiers: [.shift, .command])
3535

36+
Button("Open Search Navigator") {
37+
NSApp.sendAction(#selector(CodeEditWindowController.openSearchNavigator(_:)), to: nil, from: nil)
38+
}
39+
.keyboardShortcut("f", modifiers: [.shift, .command])
40+
3641
Menu("Font Size") {
3742
Button("Increase") {
3843
if editorFontSize < 288 {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// Array+Index.swift
3+
// CodeEdit
4+
//
5+
// Created by Abe Malla on 7/24/25.
6+
//
7+
8+
extension Array {
9+
var second: Element? {
10+
self.count > 1 ? self[1] : nil
11+
}
12+
13+
var third: Element? {
14+
self.count > 2 ? self[2] : nil
15+
}
16+
}

0 commit comments

Comments
 (0)