From 5fab6faf042c06706a7da5606e6d21d9b445fcb3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 19 Apr 2025 13:44:47 -0700 Subject: [PATCH] macOS: hook up command palette C API to actual command palette --- .../Command Palette/CommandPalette.swift | 3 +- .../Features/Terminal/TerminalView.swift | 32 ++++++++++++++++++- macos/Sources/Ghostty/Ghostty.Input.swift | 2 +- macos/Sources/Helpers/Weak.swift | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/macos/Sources/Features/Command Palette/CommandPalette.swift b/macos/Sources/Features/Command Palette/CommandPalette.swift index cd68eeeb1..09425f471 100644 --- a/macos/Sources/Features/Command Palette/CommandPalette.swift +++ b/macos/Sources/Features/Command Palette/CommandPalette.swift @@ -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) diff --git a/macos/Sources/Features/Terminal/TerminalView.swift b/macos/Sources/Features/Terminal/TerminalView.swift index fe48b6b73..5a86b9ff8 100644 --- a/macos/Sources/Features/Terminal/TerminalView.swift +++ b/macos/Sources/Features/Terminal/TerminalView.swift @@ -44,6 +44,10 @@ struct TerminalView: 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 = .init() + // This seems like a crutch after switching from SwiftUI to AppKit lifecycle. @FocusState private var focused: Bool @@ -68,6 +72,25 @@ struct TerminalView: 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? = 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: 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: View { CommandPaletteView( isPresented: $showingCommandPalette, - backgroundColor: ghostty.config.backgroundColor + backgroundColor: ghostty.config.backgroundColor, + options: commandOptions ) .transition( .move(edge: .top) diff --git a/macos/Sources/Ghostty/Ghostty.Input.swift b/macos/Sources/Ghostty/Ghostty.Input.swift index cb4fdc451..0be579122 100644 --- a/macos/Sources/Ghostty/Ghostty.Input.swift +++ b/macos/Sources/Ghostty/Ghostty.Input.swift @@ -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 diff --git a/macos/Sources/Helpers/Weak.swift b/macos/Sources/Helpers/Weak.swift index d5f784844..0fbb9bd87 100644 --- a/macos/Sources/Helpers/Weak.swift +++ b/macos/Sources/Helpers/Weak.swift @@ -3,7 +3,7 @@ class Weak { weak var value: T? - init(_ value: T) { + init(_ value: T? = nil) { self.value = value } }