mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 17:26:09 +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)
|
.padding(.bottom, 4)
|
||||||
|
|
||||||
CommandTable(
|
CommandTable(
|
||||||
|
options: options,
|
||||||
query: $query,
|
query: $query,
|
||||||
selectedIndex: $selectedIndex,
|
selectedIndex: $selectedIndex,
|
||||||
hoveredOptionID: $hoveredOptionID)
|
hoveredOptionID: $hoveredOptionID)
|
||||||
@ -197,7 +198,7 @@ fileprivate struct CommandRow: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
Button(action: option.action) {
|
Button(action: option.action) {
|
||||||
HStack {
|
HStack {
|
||||||
Text(option.title)
|
Text(option.title.lowercased())
|
||||||
Spacer()
|
Spacer()
|
||||||
if let shortcut = option.shortcut {
|
if let shortcut = option.shortcut {
|
||||||
Text(shortcut)
|
Text(shortcut)
|
||||||
|
@ -44,6 +44,10 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
|
|||||||
// An optional delegate to receive information about terminal changes.
|
// An optional delegate to receive information about terminal changes.
|
||||||
weak var delegate: (any TerminalViewDelegate)? = nil
|
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.
|
// This seems like a crutch after switching from SwiftUI to AppKit lifecycle.
|
||||||
@FocusState private var focused: Bool
|
@FocusState private var focused: Bool
|
||||||
|
|
||||||
@ -68,6 +72,25 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
|
|||||||
return URL(fileURLWithPath: surfacePwd)
|
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
|
@State var showingCommandPalette = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@ -100,6 +123,12 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
|
|||||||
.focused($focused)
|
.focused($focused)
|
||||||
.onAppear { self.focused = true }
|
.onAppear { self.focused = true }
|
||||||
.onChange(of: focusedSurface) { newValue in
|
.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)
|
self.delegate?.focusedSurfaceDidChange(to: newValue)
|
||||||
}
|
}
|
||||||
.onChange(of: title) { newValue in
|
.onChange(of: title) { newValue in
|
||||||
@ -133,7 +162,8 @@ struct TerminalView<ViewModel: TerminalViewModel>: View {
|
|||||||
|
|
||||||
CommandPaletteView(
|
CommandPaletteView(
|
||||||
isPresented: $showingCommandPalette,
|
isPresented: $showingCommandPalette,
|
||||||
backgroundColor: ghostty.config.backgroundColor
|
backgroundColor: ghostty.config.backgroundColor,
|
||||||
|
options: commandOptions
|
||||||
)
|
)
|
||||||
.transition(
|
.transition(
|
||||||
.move(edge: .top)
|
.move(edge: .top)
|
||||||
|
@ -11,7 +11,7 @@ extension Ghostty {
|
|||||||
return Self.keyToEquivalent[key]
|
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
|
/// 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
|
/// because Ghostty input triggers are a superset of what can be represented by a macOS
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class Weak<T: AnyObject> {
|
class Weak<T: AnyObject> {
|
||||||
weak var value: T?
|
weak var value: T?
|
||||||
|
|
||||||
init(_ value: T) {
|
init(_ value: T? = nil) {
|
||||||
self.value = value
|
self.value = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user