diff --git a/supacode/App/AppShortcuts.swift b/supacode/App/AppShortcuts.swift index 8dd149fd..2d799b1a 100644 --- a/supacode/App/AppShortcuts.swift +++ b/supacode/App/AppShortcuts.swift @@ -152,6 +152,9 @@ enum AppShortcuts { static let selectTerminalPaneLeft = "select_terminal_pane_left" static let selectTerminalPaneRight = "select_terminal_pane_right" static let toggleSplitZoom = "toggle_split_zoom" + static let startSearch = "start_search" + static let findNext = "find_next" + static let findPrevious = "find_previous" } enum Scope: String { @@ -200,6 +203,9 @@ enum AppShortcuts { static let stopRunScript = AppShortcut(key: ".", modifiers: .command) static let checkForUpdates = AppShortcut(key: "u", modifiers: [.command, .shift]) static let showDiff = AppShortcut(key: "y", modifiers: [.command, .shift]) + static let startSearch = AppShortcut(key: "f", modifiers: .command) + static let findNext = AppShortcut(key: "g", modifiers: .command) + static let findPrevious = AppShortcut(key: "g", modifiers: [.command, .shift]) static let toggleCanvas = AppShortcut( keyEquivalent: .return, ghosttyKeyName: "return", modifiers: [.command, .option] ) @@ -786,6 +792,24 @@ enum AppShortcuts { scope: .localInteraction, shortcut: expandCanvasCard ), + .init( + id: CommandID.startSearch, + title: "Find", + scope: .configurableAppAction, + shortcut: startSearch + ), + .init( + id: CommandID.findNext, + title: "Find Next", + scope: .configurableAppAction, + shortcut: findNext + ), + .init( + id: CommandID.findPrevious, + title: "Find Previous", + scope: .configurableAppAction, + shortcut: findPrevious + ), ] static func userOverrideConflicts( diff --git a/supacode/App/supacodeApp.swift b/supacode/App/supacodeApp.swift index e86ad408..1c37663b 100644 --- a/supacode/App/supacodeApp.swift +++ b/supacode/App/supacodeApp.swift @@ -803,7 +803,10 @@ struct SupacodeApp: App { Group { WorktreeCommands(store: store) SidebarCommands(store: store) - TerminalCommands(ghosttyShortcuts: ghosttyShortcuts) + TerminalCommands( + ghosttyShortcuts: ghosttyShortcuts, + resolvedKeybindings: store.resolvedKeybindings + ) WindowCommands( store: store, terminalManager: terminalManager, diff --git a/supacode/Commands/TerminalCommands.swift b/supacode/Commands/TerminalCommands.swift index c9375231..f3669c2f 100644 --- a/supacode/Commands/TerminalCommands.swift +++ b/supacode/Commands/TerminalCommands.swift @@ -2,6 +2,7 @@ import SwiftUI struct TerminalCommands: Commands { let ghosttyShortcuts: GhosttyShortcutManager + let resolvedKeybindings: ResolvedKeybindingMap @FocusedValue(\.newTerminalAction) private var newTerminalAction @FocusedValue(\.closeSurfaceAction) private var closeSurfaceAction @FocusedValue(\.closeTabAction) private var closeTabAction @@ -70,8 +71,7 @@ struct TerminalCommands: Commands { } .modifier( KeyboardShortcutModifier( - shortcut: ghosttyShortcuts.keyboardShortcut(for: "start_search") - ?? KeyboardShortcut("f", modifiers: .command) + shortcut: resolvedKeybindings.keyboardShortcut(for: AppShortcuts.CommandID.startSearch) ) ) .disabled(startSearchAction == nil) @@ -81,8 +81,7 @@ struct TerminalCommands: Commands { } .modifier( KeyboardShortcutModifier( - shortcut: ghosttyShortcuts.keyboardShortcut(for: "navigate_search:previous") - ?? KeyboardShortcut("g", modifiers: .command) + shortcut: resolvedKeybindings.keyboardShortcut(for: AppShortcuts.CommandID.findNext) ) ) .disabled(navigateSearchNextAction == nil) @@ -92,8 +91,7 @@ struct TerminalCommands: Commands { } .modifier( KeyboardShortcutModifier( - shortcut: ghosttyShortcuts.keyboardShortcut(for: "navigate_search:next") - ?? KeyboardShortcut("g", modifiers: [.command, .shift]) + shortcut: resolvedKeybindings.keyboardShortcut(for: AppShortcuts.CommandID.findPrevious) ) ) .disabled(navigateSearchPreviousAction == nil) @@ -104,10 +102,7 @@ struct TerminalCommands: Commands { endSearchAction?() } .modifier( - KeyboardShortcutModifier( - shortcut: ghosttyShortcuts.keyboardShortcut(for: "end_search") - ?? KeyboardShortcut(.escape, modifiers: []) - ) + KeyboardShortcutModifier(shortcut: ghosttyShortcuts.keyboardShortcut(for: "end_search")) ) .disabled(endSearchAction == nil) @@ -117,10 +112,7 @@ struct TerminalCommands: Commands { searchSelectionAction?() } .modifier( - KeyboardShortcutModifier( - shortcut: ghosttyShortcuts.keyboardShortcut(for: "search_selection") - ?? KeyboardShortcut("e", modifiers: .command) - ) + KeyboardShortcutModifier(shortcut: ghosttyShortcuts.keyboardShortcut(for: "search_selection")) ) .disabled(searchSelectionAction == nil) } diff --git a/supacode/Features/Terminal/Views/GhosttySurfaceSearchOverlay.swift b/supacode/Features/Terminal/Views/GhosttySurfaceSearchOverlay.swift index b7af128f..95668f8a 100644 --- a/supacode/Features/Terminal/Views/GhosttySurfaceSearchOverlay.swift +++ b/supacode/Features/Terminal/Views/GhosttySurfaceSearchOverlay.swift @@ -5,6 +5,7 @@ struct GhosttySurfaceSearchOverlay: View { let surfaceView: GhosttySurfaceView @Bindable var state: GhosttySurfaceState @Environment(GhosttyShortcutManager.self) private var ghosttyShortcuts + @Environment(\.resolvedKeybindings) private var resolvedKeybindings @State private var searchText: String @State private var corner: GhosttySearchCorner = .topRight @@ -51,24 +52,24 @@ struct GhosttySurfaceSearchOverlay: View { } label: { SearchButtonLabel( title: "Previous", - shortcut: ghosttyShortcuts.display(for: "search:next"), + shortcut: resolvedKeybindings.display(for: AppShortcuts.CommandID.findPrevious), systemImage: "chevron.up" ) } .buttonStyle(GhosttySearchButtonStyle()) - .help("Find Previous (⇧⌘G)") + .help(searchButtonHelp("Find Previous", commandID: AppShortcuts.CommandID.findPrevious)) Button { navigateSearch(.next) } label: { SearchButtonLabel( title: "Next", - shortcut: ghosttyShortcuts.display(for: "search:previous"), + shortcut: resolvedKeybindings.display(for: AppShortcuts.CommandID.findNext), systemImage: "chevron.down" ) } .buttonStyle(GhosttySearchButtonStyle()) - .help("Find Next (⌘G)") + .help(searchButtonHelp("Find Next", commandID: AppShortcuts.CommandID.findNext)) Button { closeSearch() @@ -76,7 +77,7 @@ struct GhosttySurfaceSearchOverlay: View { } label: { SearchButtonLabel( title: "Close", - shortcut: ghosttyShortcuts.display(for: "end_search"), + shortcut: nil, systemImage: "xmark" ) } @@ -200,6 +201,13 @@ struct GhosttySurfaceSearchOverlay: View { emitSearch(searchText) } + private func searchButtonHelp(_ title: String, commandID: String) -> String { + if let shortcut = resolvedKeybindings.display(for: commandID) { + return "\(title) (\(shortcut))" + } + return title + } + private func focusSearchField() { isSearchFieldFocused = false Task { @MainActor in