mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-27 09:43:55 +00:00
macos: new terminal intent
This commit is contained in:
@@ -167,7 +167,7 @@ class AppDelegate: NSObject,
|
||||
|
||||
// This registers the Ghostty => Services menu to exist.
|
||||
NSApp.servicesMenu = menuServices
|
||||
|
||||
|
||||
// Setup a local event monitor for app-level keyboard shortcuts. See
|
||||
// localEventHandler for more info why.
|
||||
_ = NSEvent.addLocalMonitorForEvents(
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
enum GhosttyIntentError: Error, CustomLocalizedStringResourceConvertible {
|
||||
case appUnavailable
|
||||
|
||||
var localizedStringResource: LocalizedStringResource {
|
||||
switch self {
|
||||
case .appUnavailable: return "The Ghostty app isn't properly initialized."
|
||||
}
|
||||
}
|
||||
}
|
||||
81
macos/Sources/Features/App Intents/NewTerminalIntent.swift
Normal file
81
macos/Sources/Features/App Intents/NewTerminalIntent.swift
Normal file
@@ -0,0 +1,81 @@
|
||||
import AppKit
|
||||
import AppIntents
|
||||
|
||||
/// App intent that allows creating a new terminal window or tab.
|
||||
///
|
||||
/// This requires macOS 15 or greater because we use features of macOS 15 here.
|
||||
@available(macOS 15.0, *)
|
||||
struct NewTerminalIntent: AppIntent {
|
||||
static var title: LocalizedStringResource = "New Terminal"
|
||||
static var description = IntentDescription("Create a new terminal.")
|
||||
|
||||
@Parameter(
|
||||
title: "Location",
|
||||
description: "The location that the terminal should be created.",
|
||||
default: .window
|
||||
)
|
||||
var location: NewTerminalLocation
|
||||
|
||||
@Parameter(
|
||||
title: "Working Directory",
|
||||
description: "The working directory to open in the terminal.",
|
||||
supportedContentTypes: [.folder]
|
||||
)
|
||||
var workingDirectory: IntentFile?
|
||||
|
||||
@available(macOS 26.0, *)
|
||||
static var supportedModes: IntentModes = .foreground(.immediate)
|
||||
|
||||
@available(macOS, obsoleted: 26.0, message: "Replaced by supportedModes")
|
||||
static var openAppWhenRun = true
|
||||
|
||||
static var parameterSummary: some ParameterSummary {
|
||||
Summary("New Terminal \(\.$location)")
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func perform() async throws -> some IntentResult {
|
||||
guard let appDelegate = NSApp.delegate as? AppDelegate else {
|
||||
throw GhosttyIntentError.appUnavailable
|
||||
}
|
||||
|
||||
var config = Ghostty.SurfaceConfiguration()
|
||||
|
||||
// If we were given a working directory then open that directory
|
||||
if let url = workingDirectory?.fileURL {
|
||||
let dir = url.hasDirectoryPath ? url : url.deletingLastPathComponent()
|
||||
config.workingDirectory = dir.path(percentEncoded: false)
|
||||
}
|
||||
|
||||
switch location {
|
||||
case .window:
|
||||
_ = TerminalController.newWindow(
|
||||
appDelegate.ghostty,
|
||||
withBaseConfig: config)
|
||||
|
||||
case .tab:
|
||||
_ = TerminalController.newTab(
|
||||
appDelegate.ghostty,
|
||||
from: TerminalController.preferredParent?.window,
|
||||
withBaseConfig: config)
|
||||
}
|
||||
|
||||
return .result()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: NewTerminalLocation
|
||||
|
||||
enum NewTerminalLocation: String {
|
||||
case tab
|
||||
case window
|
||||
}
|
||||
|
||||
extension NewTerminalLocation: AppEnum {
|
||||
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Terminal Location")
|
||||
|
||||
static var caseDisplayRepresentations: [Self: DisplayRepresentation] = [
|
||||
.tab: .init(title: "Tab"),
|
||||
.window: .init(title: "Window"),
|
||||
]
|
||||
}
|
||||
@@ -169,7 +169,7 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr
|
||||
private static var lastCascadePoint = NSPoint(x: 0, y: 0)
|
||||
|
||||
// The preferred parent terminal controller.
|
||||
private static var preferredParent: TerminalController? {
|
||||
static var preferredParent: TerminalController? {
|
||||
all.first {
|
||||
$0.window?.isMainWindow ?? false
|
||||
} ?? all.last
|
||||
|
||||
Reference in New Issue
Block a user