macos: intent to open quick terminal
parent
f096675eaf
commit
2c1e83ba2f
|
|
@ -14,6 +14,7 @@
|
|||
9351BE8E3D22937F003B3499 /* nvim in Resources */ = {isa = PBXBuildFile; fileRef = 9351BE8E2D22937F003B3499 /* nvim */; };
|
||||
A50297352DFA0F3400B4E924 /* Double+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50297342DFA0F3300B4E924 /* Double+Extension.swift */; };
|
||||
A511940F2E050595007258CC /* CloseTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A511940E2E050590007258CC /* CloseTerminalIntent.swift */; };
|
||||
A51194112E05A483007258CC /* QuickTerminalIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A51194102E05A480007258CC /* QuickTerminalIntent.swift */; };
|
||||
A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
|
||||
A514C8D72B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
|
||||
A514C8D82B54DC6800493A16 /* Ghostty.App.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53D0C992B543F3B00305CE6 /* Ghostty.App.swift */; };
|
||||
|
|
@ -151,6 +152,7 @@
|
|||
9351BE8E2D22937F003B3499 /* nvim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = nvim; path = "../zig-out/share/nvim"; sourceTree = "<group>"; };
|
||||
A50297342DFA0F3300B4E924 /* Double+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Extension.swift"; sourceTree = "<group>"; };
|
||||
A511940E2E050590007258CC /* CloseTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloseTerminalIntent.swift; sourceTree = "<group>"; };
|
||||
A51194102E05A480007258CC /* QuickTerminalIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickTerminalIntent.swift; sourceTree = "<group>"; };
|
||||
A514C8D52B54A16400493A16 /* Ghostty.Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Config.swift; sourceTree = "<group>"; };
|
||||
A51544FD2DFB1110009E85D8 /* TitlebarTabsTahoeTerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitlebarTabsTahoeTerminalWindow.swift; sourceTree = "<group>"; };
|
||||
A51544FF2DFB112E009E85D8 /* TerminalTabsTitlebarTahoe.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TerminalTabsTitlebarTahoe.xib; sourceTree = "<group>"; };
|
||||
|
|
@ -630,6 +632,7 @@
|
|||
A511940E2E050590007258CC /* CloseTerminalIntent.swift */,
|
||||
A5E4082D2E0237410035FEAC /* NewTerminalIntent.swift */,
|
||||
A5E408332E03200F0035FEAC /* GetTerminalDetailsIntent.swift */,
|
||||
A51194102E05A480007258CC /* QuickTerminalIntent.swift */,
|
||||
A5E408422E047D060035FEAC /* CommandPaletteIntent.swift */,
|
||||
A5E408462E0485270035FEAC /* InputIntent.swift */,
|
||||
A5E408442E0483F80035FEAC /* KeybindIntent.swift */,
|
||||
|
|
@ -806,6 +809,7 @@
|
|||
A53A29812DB44A6100B6E02C /* KeyboardShortcut+Extension.swift in Sources */,
|
||||
A50297352DFA0F3400B4E924 /* Double+Extension.swift in Sources */,
|
||||
A5CBD0562C9E65B80017A1AE /* DraggableWindowView.swift in Sources */,
|
||||
A51194112E05A483007258CC /* QuickTerminalIntent.swift in Sources */,
|
||||
C1F26EE92B76CBFC00404083 /* VibrantLayer.m in Sources */,
|
||||
A5593FDF2DF8D57C00B47B10 /* TerminalWindow.swift in Sources */,
|
||||
A58636712DF298FB00E04A10 /* ExpiringUndoManager.swift in Sources */,
|
||||
|
|
|
|||
|
|
@ -92,7 +92,10 @@ class AppDelegate: NSObject,
|
|||
lazy var undoManager = ExpiringUndoManager()
|
||||
|
||||
/// Our quick terminal. This starts out uninitialized and only initializes if used.
|
||||
private var quickController: QuickTerminalController? = nil
|
||||
private(set) lazy var quickController = QuickTerminalController(
|
||||
ghostty,
|
||||
position: derivedConfig.quickTerminalPosition
|
||||
)
|
||||
|
||||
/// Manages updates
|
||||
let updaterController: SPUStandardUpdaterController
|
||||
|
|
@ -286,7 +289,7 @@ class AppDelegate: NSObject,
|
|||
// NOTE(mitchellh): I don't think we need this check at all anymore. I'm keeping it
|
||||
// here because I don't want to remove it in a patch release cycle but we should
|
||||
// target removing it soon.
|
||||
if (self.quickController == nil && windows.allSatisfy { !$0.isVisible }) {
|
||||
if (windows.allSatisfy { !$0.isVisible }) {
|
||||
return .terminateNow
|
||||
}
|
||||
|
||||
|
|
@ -919,14 +922,6 @@ class AppDelegate: NSObject,
|
|||
}
|
||||
|
||||
@IBAction func toggleQuickTerminal(_ sender: Any) {
|
||||
if quickController == nil {
|
||||
quickController = QuickTerminalController(
|
||||
ghostty,
|
||||
position: derivedConfig.quickTerminalPosition
|
||||
)
|
||||
}
|
||||
|
||||
guard let quickController = self.quickController else { return }
|
||||
quickController.toggle()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ struct TerminalEntity: AppEntity {
|
|||
@Property(title: "Working Directory")
|
||||
var workingDirectory: String?
|
||||
|
||||
@Property(title: "Kind")
|
||||
var kind: Kind
|
||||
|
||||
@MainActor
|
||||
@DeferredProperty(title: "Full Contents")
|
||||
@available(macOS 26.0, *)
|
||||
|
|
@ -67,6 +70,27 @@ struct TerminalEntity: AppEntity {
|
|||
self.title = view.title
|
||||
self.workingDirectory = view.pwd
|
||||
self.screenshot = view.screenshot()
|
||||
|
||||
// Determine the kind based on the window controller type
|
||||
if view.window?.windowController is QuickTerminalController {
|
||||
self.kind = .quick
|
||||
} else {
|
||||
self.kind = .normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension TerminalEntity {
|
||||
enum Kind: String, AppEnum {
|
||||
case normal
|
||||
case quick
|
||||
|
||||
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Terminal Kind")
|
||||
|
||||
static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [
|
||||
.normal: .init(title: "Normal"),
|
||||
.quick: .init(title: "Quick")
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +125,8 @@ struct TerminalQuery: EntityStringQuery, EnumerableEntityQuery {
|
|||
|
||||
@MainActor
|
||||
var all: [Ghostty.SurfaceView] {
|
||||
// Find all of our terminal windows (includes quick terminal)
|
||||
// Find all of our terminal windows. This will include the quick terminal
|
||||
// but only if it was previously opened.
|
||||
let controllers = NSApp.windows.compactMap {
|
||||
$0.windowController as? BaseTerminalController
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
import AppKit
|
||||
import AppIntents
|
||||
|
||||
struct QuickTerminalIntent: AppIntent {
|
||||
static var title: LocalizedStringResource = "Open the Quick Terminal"
|
||||
static var description = IntentDescription("Open the Quick Terminal. If it is already open, then do nothing.")
|
||||
|
||||
@available(macOS 26.0, *)
|
||||
static var supportedModes: IntentModes = .background
|
||||
|
||||
@MainActor
|
||||
func perform() async throws -> some IntentResult & ReturnsValue<[TerminalEntity]> {
|
||||
guard let delegate = NSApp.delegate as? AppDelegate else {
|
||||
throw GhosttyIntentError.appUnavailable
|
||||
}
|
||||
|
||||
// This is safe to call even if it is already shown.
|
||||
let c = delegate.quickController
|
||||
c.animateIn()
|
||||
|
||||
// Grab all our terminals
|
||||
let terminals = c.surfaceTree.root?.leaves().map {
|
||||
TerminalEntity($0)
|
||||
} ?? []
|
||||
|
||||
return .result(value: terminals)
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +42,11 @@ class QuickTerminalController: BaseTerminalController {
|
|||
) {
|
||||
self.position = position
|
||||
self.derivedConfig = DerivedConfig(ghostty.config)
|
||||
super.init(ghostty, baseConfig: base, surfaceTree: tree)
|
||||
|
||||
// Important detail here: we initialize with an empty surface tree so
|
||||
// that we don't start a terminal process. This gets started when the
|
||||
// first terminal is shown in `animateIn`.
|
||||
super.init(ghostty, baseConfig: base, surfaceTree: .init())
|
||||
|
||||
// Setup our notifications for behaviors
|
||||
let center = NotificationCenter.default
|
||||
|
|
|
|||
Loading…
Reference in New Issue