Change AppleScript strategy to use clipboard copy/paste

Instead of typing commands character by character, which can be slow
and error-prone with special characters, we now:
1. Copy the command to clipboard using NSPasteboard
2. Use Cmd+V to paste it in the terminal
3. Press Enter to execute

This approach is more reliable, faster, and handles special characters
better. Terminal.app continues to use 'do script' since it supports
it natively.
This commit is contained in:
Peter Steinberger 2025-06-18 09:58:21 +02:00
parent db1583b88b
commit 75203f79ab
2 changed files with 20 additions and 31 deletions

View file

@ -129,41 +129,20 @@ enum Terminal: String, CaseIterable {
""" """
} }
// Warp has issues with key code 36 (Enter), so we use a special approach // For all other terminals, use clipboard approach for reliability
if self == .warp { // This avoids issues with special characters and long commands
// Note: The command is already copied to clipboard before this script runs
return """ return """
tell application "\(processName)" tell application "\(processName)"
activate activate
tell application "System Events" tell application "System Events"
-- Create new window/tab
keystroke "n" using {command down} keystroke "n" using {command down}
end tell delay 0.5
delay 3 -- Paste command from clipboard
tell application "System Events" keystroke "v" using {command down}
-- Warp needs special handling for command execution
-- First, type the command
keystroke "\(config.keystrokeEscapedCommand)"
delay 0.1 delay 0.1
-- Try multiple approaches to execute the command -- Execute the command
-- Option 1: Ctrl+J (line feed)
keystroke "j" using {control down}
delay 0.1
-- Option 2: If that didn't work, try regular Enter
key code 36
end tell
end tell
"""
}
// Standard approach for other terminals
return """
tell application "\(processName)"
activate
tell application "System Events"
keystroke "n" using {command down}
end tell
delay 3
tell application "System Events"
keystroke "\(config.keystrokeEscapedCommand)"
key code 36 key code 36
end tell end tell
end tell end tell
@ -381,6 +360,10 @@ final class TerminalLauncher {
switch method { switch method {
case .appleScript(let script): case .appleScript(let script):
logger.debug("Generated AppleScript:\n\(script)") logger.debug("Generated AppleScript:\n\(script)")
// For non-Terminal.app terminals, copy command to clipboard first
if config.terminal != .terminal {
copyToClipboard(config.fullCommand)
}
try executeAppleScript(script) try executeAppleScript(script)
case .processWithArgs(let args): case .processWithArgs(let args):
@ -439,6 +422,12 @@ final class TerminalLauncher {
} }
} }
private func copyToClipboard(_ text: String) {
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
pasteboard.setString(text, forType: .string)
}
private func executeAppleScript(_ script: String) throws { private func executeAppleScript(_ script: String) throws {
do { do {
// Use a longer timeout (15 seconds) for terminal launch operations // Use a longer timeout (15 seconds) for terminal launch operations
@ -504,7 +493,7 @@ final class TerminalLauncher {
let expandedWorkingDir = (workingDirectory as NSString).expandingTildeInPath let expandedWorkingDir = (workingDirectory as NSString).expandingTildeInPath
// Use provided tty-fwd path or find bundled one // Use provided tty-fwd path or find bundled one
let ttyFwd = ttyFwdPath ?? findTTYFwdBinary() _ = ttyFwdPath ?? findTTYFwdBinary()
// The command comes pre-formatted from Rust, just launch it // The command comes pre-formatted from Rust, just launch it
// Pass the working directory separately to avoid double-escaping issues // Pass the working directory separately to avoid double-escaping issues