Skip to content

Added global search keyboard shortcut #2094

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,21 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
}
}

/// Opens the search navigator and focuses the search field
@IBAction func openSearchNavigator(_ sender: Any? = nil) {
if navigatorCollapsed {
toggleFirstPanel()
}

if let navigatorViewModel = navigatorSidebarViewModel,
let searchTab = navigatorViewModel.tabItems.first(where: { $0 == .search }) {
DispatchQueue.main.async {
self.workspace?.searchState?.shouldFocusSearchField = true
navigatorViewModel.setNavigatorTab(tab: searchTab)
}
}
}

@IBAction func openQuickly(_ sender: Any?) {
if let workspace, let state = workspace.openQuicklyViewModel {
if let quickOpenPanel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ extension WorkspaceDocument {

@Published var findNavigatorStatus: FindNavigatorStatus = .none

@Published var shouldFocusSearchField: Bool = false

unowned var workspace: WorkspaceDocument
var tempSearchResults = [SearchResultModel]()
var caseSensitive: Bool = false
Expand Down
112 changes: 56 additions & 56 deletions CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorForm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,63 +25,13 @@ struct FindNavigatorForm: View {
@State private var preserveCase: Bool = false
@State private var scopedToOpenEditors: Bool = false
@State private var excludeSettings: Bool = true
@FocusState private var isSearchFieldFocused: Bool

init(state: WorkspaceDocument.SearchState) {
self.state = state
selectedMode = state.selectedMode
}

private func getMenuList(_ index: Int) -> [SearchModeModel] {
index == 0 ? SearchModeModel.SearchModes : selectedMode[index - 1].children
}

private func onSelectMenuItem(_ index: Int, searchMode: SearchModeModel) {
var newSelectedMode: [SearchModeModel] = []

switch index {
case 0:
newSelectedMode.append(searchMode)
self.updateSelectedMode(searchMode, searchModel: &newSelectedMode)
self.selectedMode = newSelectedMode
case 1:
if let firstMode = selectedMode.first {
newSelectedMode.append(contentsOf: [firstMode, searchMode])
if let thirdMode = searchMode.children.first {
if let selectedThirdMode = selectedMode.third, searchMode.children.contains(selectedThirdMode) {
newSelectedMode.append(selectedThirdMode)
} else {
newSelectedMode.append(thirdMode)
}
}
}
self.selectedMode = newSelectedMode
case 2:
if let firstMode = selectedMode.first, let secondMode = selectedMode.second {
newSelectedMode.append(contentsOf: [firstMode, secondMode, searchMode])
}
self.selectedMode = newSelectedMode
default:
return
}
}

private func updateSelectedMode(_ searchMode: SearchModeModel, searchModel: inout [SearchModeModel]) {
if let secondMode = searchMode.children.first {
if let selectedSecondMode = selectedMode.second, searchMode.children.contains(selectedSecondMode) {
searchModel.append(contentsOf: selectedMode.dropFirst())
} else {
searchModel.append(secondMode)
if let thirdMode = secondMode.children.first, let selectedThirdMode = selectedMode.third {
if secondMode.children.contains(selectedThirdMode) {
searchModel.append(selectedThirdMode)
} else {
searchModel.append(thirdMode)
}
}
}
}
}

private var chevron: some View {
Image(systemName: "chevron.compact.right")
.foregroundStyle(.tertiary)
Expand Down Expand Up @@ -152,6 +102,7 @@ struct FindNavigatorForm: View {
},
hasValue: caseSensitive
)
.focused($isSearchFieldFocused)
.onSubmit {
if !state.searchQuery.isEmpty {
Task {
Expand Down Expand Up @@ -262,16 +213,65 @@ struct FindNavigatorForm: View {
}
}
}
.onReceive(state.$shouldFocusSearchField) { shouldFocus in
if shouldFocus {
isSearchFieldFocused = true
state.shouldFocusSearchField = false
}
}
.lineLimit(1...5)
}
}

extension Array {
var second: Element? {
self.count > 1 ? self[1] : nil
extension FindNavigatorForm {
private func getMenuList(_ index: Int) -> [SearchModeModel] {
index == 0 ? SearchModeModel.SearchModes : selectedMode[index - 1].children
}

private func onSelectMenuItem(_ index: Int, searchMode: SearchModeModel) {
var newSelectedMode: [SearchModeModel] = []

switch index {
case 0:
newSelectedMode.append(searchMode)
self.updateSelectedMode(searchMode, searchModel: &newSelectedMode)
self.selectedMode = newSelectedMode
case 1:
if let firstMode = selectedMode.first {
newSelectedMode.append(contentsOf: [firstMode, searchMode])
if let thirdMode = searchMode.children.first {
if let selectedThirdMode = selectedMode.third, searchMode.children.contains(selectedThirdMode) {
newSelectedMode.append(selectedThirdMode)
} else {
newSelectedMode.append(thirdMode)
}
}
}
self.selectedMode = newSelectedMode
case 2:
if let firstMode = selectedMode.first, let secondMode = selectedMode.second {
newSelectedMode.append(contentsOf: [firstMode, secondMode, searchMode])
}
self.selectedMode = newSelectedMode
default:
return
}
}

var third: Element? {
self.count > 2 ? self[2] : nil
private func updateSelectedMode(_ searchMode: SearchModeModel, searchModel: inout [SearchModeModel]) {
if let secondMode = searchMode.children.first {
if let selectedSecondMode = selectedMode.second, searchMode.children.contains(selectedSecondMode) {
searchModel.append(contentsOf: selectedMode.dropFirst())
} else {
searchModel.append(secondMode)
if let thirdMode = secondMode.children.first, let selectedThirdMode = selectedMode.third {
if secondMode.children.contains(selectedThirdMode) {
searchModel.append(selectedThirdMode)
} else {
searchModel.append(thirdMode)
}
}
}
}
}
}
5 changes: 5 additions & 0 deletions CodeEdit/Features/WindowCommands/ViewCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ struct ViewCommands: Commands {
}
.keyboardShortcut("p", modifiers: [.shift, .command])

Button("Open Search Navigator") {
NSApp.sendAction(#selector(CodeEditWindowController.openSearchNavigator(_:)), to: nil, from: nil)
}
.keyboardShortcut("f", modifiers: [.shift, .command])

Menu("Font Size") {
Button("Increase") {
if editorFontSize < 288 {
Expand Down
16 changes: 16 additions & 0 deletions CodeEdit/Utils/Extensions/Array/Array+Index.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Array+Index.swift
// CodeEdit
//
// Created by Abe Malla on 7/24/25.
//

extension Array {
var second: Element? {
self.count > 1 ? self[1] : nil
}

var third: Element? {
self.count > 2 ? self[2] : nil
}
}
Loading