mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
macOS: hook up command palette C API to actual command palette
This commit is contained in:
@ -76,6 +76,7 @@ struct CommandPaletteView: View {
|
||||
.padding(.bottom, 4)
|
||||
|
||||
CommandTable(
|
||||
options: options,
|
||||
query: $query,
|
||||
selectedIndex: $selectedIndex,
|
||||
hoveredOptionID: $hoveredOptionID)
|
||||
@ -197,7 +198,7 @@ fileprivate struct CommandRow: View {
|
||||
var body: some View {
|
||||
Button(action: option.action) {
|
||||
HStack {
|
||||
Text(option.title)
|
||||
Text(option.title.lowercased())
|
||||
Spacer()
|
||||
if let shortcut = option.shortcut {
|
||||
Text(shortcut)
|
||||
|
@ -44,6 +44,10 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
|
||||
// An optional delegate to receive information about terminal changes.
|
||||
weak var delegate: (any TerminalViewDelegate)? = nil
|
||||
|
||||
// The most recently focused surface, equal to focusedSurface when
|
||||
// it is non-nil.
|
||||
@State private var lastFocusedSurface: Weak<Ghostty.SurfaceView> = .init()
|
||||
|
||||
// This seems like a crutch after switching from SwiftUI to AppKit lifecycle.
|
||||
@FocusState private var focused: Bool
|
||||
|
||||
@ -68,6 +72,25 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
|
||||
return URL(fileURLWithPath: surfacePwd)
|
||||
}
|
||||
|
||||
// The commands available to the command palette.
|
||||
private var commandOptions: [CommandOption] {
|
||||
guard let surface = lastFocusedSurface.value?.surface else { return [] }
|
||||
|
||||
var ptr: UnsafeMutablePointer<ghostty_command_s>? = nil
|
||||
var count: Int = 0
|
||||
ghostty_surface_commands(surface, &ptr, &count)
|
||||
guard let ptr else { return [] }
|
||||
|
||||
let buffer = UnsafeBufferPointer(start: ptr, count: count)
|
||||
return Array(buffer).map { c in
|
||||
let action = String(cString: c.action)
|
||||
return CommandOption(
|
||||
title: String(cString: c.title),
|
||||
shortcut: ghostty.config.keyEquivalent(for: action)?.description
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
||||
@State var showingCommandPalette = false
|
||||
|
||||
var body: some View {
|
||||
@ -100,6 +123,12 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
|
||||
.focused($focused)
|
||||
.onAppear { self.focused = true }
|
||||
.onChange(of: focusedSurface) { newValue in
|
||||
// We want to keep track of our last focused surface so even if
|
||||
// we lose focus we keep this set to the last non-nil value.
|
||||
if newValue != nil {
|
||||
lastFocusedSurface = .init(newValue)
|
||||
}
|
||||
|
||||
self.delegate?.focusedSurfaceDidChange(to: newValue)
|
||||
}
|
||||
.onChange(of: title) { newValue in
|
||||
@ -133,7 +162,8 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
|
||||
|
||||
CommandPaletteView(
|
||||
isPresented: $showingCommandPalette,
|
||||
backgroundColor: ghostty.config.backgroundColor
|
||||
backgroundColor: ghostty.config.backgroundColor,
|
||||
options: commandOptions
|
||||
)
|
||||
.transition(
|
||||
.move(edge: .top)
|
||||
|
@ -11,7 +11,7 @@ extension Ghostty {
|
||||
return Self.keyToEquivalent[key]
|
||||
}
|
||||
|
||||
/// Return the keyboard shortcut for a trigger.
|
||||
/// Return the key equivalent for the given trigger.
|
||||
///
|
||||
/// Returns nil if the trigger doesn't have an equivalent KeyboardShortcut. This is possible
|
||||
/// because Ghostty input triggers are a superset of what can be represented by a macOS
|
||||
|
@ -3,7 +3,7 @@
|
||||
class Weak<T: AnyObject> {
|
||||
weak var value: T?
|
||||
|
||||
init(_ value: T) {
|
||||
init(_ value: T? = nil) {
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user