From 1c5ba230194f5450dcf98600378fd968576ee5b2 Mon Sep 17 00:00:00 2001 From: tomkrus007 Date: Thu, 16 Apr 2026 15:20:58 +0800 Subject: [PATCH 1/2] support ghostty --- cd to .../cd to .../main.m | 170 ++++++++++++++++++++++++++----------- 1 file changed, 119 insertions(+), 51 deletions(-) diff --git a/cd to .../cd to .../main.m b/cd to .../cd to .../main.m index 945df9f..9677071 100644 --- a/cd to .../cd to .../main.m +++ b/cd to .../cd to .../main.m @@ -8,6 +8,7 @@ #import #import +#import #import "Finder.h" #import "Terminal.h" @@ -17,13 +18,116 @@ NSUInteger linesOfHistory(TerminalTab* tab) { return [[hist componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] count]; } +// Check if Ghostty is currently running +BOOL isGhosttyRunning(void) { + NSArray* runningApps = [[NSWorkspace sharedWorkspace] runningApplications]; + for (NSRunningApplication* app in runningApps) { + if ([app.bundleIdentifier isEqualToString:@"com.mitchellh.ghostty"]) { + return YES; + } + } + return NO; +} + +void openInGhostty(NSURL* url) { + NSLog(@"[cdto] Trying Ghostty..."); + NSURL* appURL = [[NSWorkspace sharedWorkspace] + URLForApplicationWithBundleIdentifier:@"com.mitchellh.ghostty"]; + if (appURL == nil) { + NSLog(@"[cdto] Ghostty app not found!"); + return; + } + NSLog(@"[cdto] Found Ghostty at: %@", appURL); + + NSString* workingDir = [url path]; + NSLog(@"[cdto] Opening with working directory: %@", workingDir); + NSLog(@"[cdto] Ghostty running: %@", isGhosttyRunning() ? @"YES" : @"NO"); + + NSTask* task = [[NSTask alloc] init]; + task.executableURL = [NSURL fileURLWithPath:@"/usr/bin/osascript"]; + task.arguments = @[ + @"-e", @"on run argv", + @"-e", @"set workingDir to item 1 of argv", + @"-e", @"tell application \"Ghostty\"", + @"-e", @"set cfg to new surface configuration", + @"-e", @"set initial working directory of cfg to workingDir", + @"-e", @"if it is running then", + @"-e", @"if (count of windows) > 0 then", + @"-e", @"new tab in front window with configuration cfg", + @"-e", @"else", + @"-e", @"new window with configuration cfg", + @"-e", @"end if", + @"-e", @"else", + @"-e", @"new window with configuration cfg", + @"-e", @"end if", + @"-e", @"activate", + @"-e", @"end tell", + @"-e", @"end run", + @"--", workingDir + ]; + [task launch]; + [task waitUntilExit]; + + if (task.terminationStatus == 0) { + NSLog(@"[cdto] Ghostty opened successfully"); + } else { + NSLog(@"[cdto] Ghostty AppleScript failed with exit code: %d", task.terminationStatus); + } +} + +void openInTerminal(NSURL* url) { + NSLog(@"[cdto] Trying Terminal..."); + TerminalApplication* terminal = [SBApplication applicationWithBundleIdentifier:@"com.apple.Terminal"]; + + TerminalWindow* win = nil; + if ([[terminal windows] count] == 1){ + win = [[terminal windows] objectAtLocation:@1]; + win = [[terminal windows] objectWithID: [NSNumber numberWithInteger:win.id]]; + } + [terminal open:@[url]]; + TerminalWindow* newWin = [[terminal windows] objectAtLocation:@1]; + newWin = [[terminal windows] objectWithID: [NSNumber numberWithInteger:newWin.id]]; + TerminalTab* newTab = [[newWin tabs] objectAtLocation:@1]; + + NSString* setName = [[NSUserDefaults standardUserDefaults] stringForKey:@"cdto-new-window-setting"]; + if(setName != nil && ![setName isEqualToString:@""]) { + TerminalSettingsSet* chosenSet = nil; + for (TerminalSettingsSet *set in [terminal settingsSets]) { + if([[set name] isEqualToString:setName]){ + chosenSet = set; + } + } + if(chosenSet != nil){ + newTab.currentSettings = chosenSet; + } + } + + if([[NSUserDefaults standardUserDefaults] boolForKey:@"cdto-close-default-window"]){ + if([[win tabs] count] == 1){ + TerminalTab* tab = [[win tabs]objectAtLocation:@1]; + if(![tab busy]){ + NSUInteger oldTabLines = linesOfHistory(tab); + while([newTab busy]){ + [NSThread sleepForTimeInterval:0.1f]; + } + NSUInteger newTabLines = linesOfHistory(newTab); + if(oldTabLines == newTabLines){ + [win closeSaving:TerminalSaveOptionsNo savingIn:nil]; + } + } + } + } + + [terminal activate]; +} + int main(int argc, const char * argv[]) { @autoreleasepool { - // Setup code that might create autoreleased objects goes here. + NSString* terminalApp = [[NSUserDefaults standardUserDefaults] stringForKey:@"cdto-terminal-app"]; + NSLog(@"[cdto] cdto-terminal-app value: '%@'", terminalApp); + FinderApplication* finder = [SBApplication applicationWithBundleIdentifier:@"com.apple.Finder"]; - - TerminalApplication* terminal = [SBApplication applicationWithBundleIdentifier:@"com.apple.Terminal"]; - + FinderItem *target = [(NSArray*)[[finder selection] get] firstObject]; FinderFinderWindow* findWin = [[finder FinderWindows] objectAtLocation:@1]; findWin = [[finder FinderWindows] objectWithID:[NSNumber numberWithInteger: findWin.id]]; @@ -32,65 +136,29 @@ int main(int argc, const char * argv[]) { target = [[findWin target] get]; selected = false; } - + NSDictionary* itemProperties = [target properties]; id originalItem = [itemProperties objectForKey:@"originalItem"]; if (originalItem != nil && originalItem != [NSNull null]){ target = originalItem; } - + NSString* fileUrl = [target URL]; + NSLog(@"[cdto] fileUrl: %@", fileUrl); if(fileUrl != nil && ![fileUrl hasSuffix:@"/"] && selected){ fileUrl = [fileUrl stringByDeletingLastPathComponent]; } - + NSURL* url = [NSURL URLWithString:fileUrl]; + NSLog(@"[cdto] url: %@", url); if (url != nil){ - TerminalWindow* win = nil; - if ([[terminal windows] count] == 1){ - //get front most and then reference by id - win = [[terminal windows] objectAtLocation:@1]; - win = [[terminal windows] objectWithID: [NSNumber numberWithInteger:win.id]]; - } - [terminal open:@[url]]; - //get front most and then reference by id - TerminalWindow* newWin = [[terminal windows] objectAtLocation:@1]; - newWin = [[terminal windows] objectWithID: [NSNumber numberWithInteger:newWin.id]]; - TerminalTab* newTab = [[newWin tabs] objectAtLocation:@1]; - - NSString* setName = [[NSUserDefaults standardUserDefaults] stringForKey:@"cdto-new-window-setting"]; - if(setName != nil && ![setName isEqualToString:@""]) { //setting set - TerminalSettingsSet* chosenSet = nil; - for (TerminalSettingsSet *set in [terminal settingsSets]) { - if([[set name] isEqualToString:setName]){ - chosenSet = set; - } - } - if(chosenSet != nil){ - newTab.currentSettings = chosenSet; - } - } - - if([[NSUserDefaults standardUserDefaults] boolForKey:@"cdto-close-default-window"]){ //close first launch window - if([[win tabs] count] == 1){ - TerminalTab* tab = [[win tabs]objectAtLocation:@1]; - if(![tab busy]){ - //if history has same number of lines as new window - // assume automatically opened new window, and close it - NSUInteger oldTabLines = linesOfHistory(tab); - while([newTab busy]){ - [NSThread sleepForTimeInterval:0.1f]; - } - NSUInteger newTabLines = linesOfHistory(newTab); - if(oldTabLines == newTabLines){ - [win closeSaving:TerminalSaveOptionsNo savingIn:nil]; - } - } - } + if ([terminalApp isEqualToString:@"ghostty"]) { + openInGhostty(url); + } else { + openInTerminal(url); } - - - [terminal activate]; + } else { + NSLog(@"[cdto] url is nil, doing nothing"); } } } From 70373230dff2d4092989b1ef7433df11c166e4e4 Mon Sep 17 00:00:00 2001 From: tomkrus007 Date: Thu, 16 Apr 2026 15:27:16 +0800 Subject: [PATCH 2/2] add how to support ghostty --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f6be42e..ab8715c 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,12 @@ _Eg. if you wanted cd to windows to be "Red Sands"_ defaults write name.tuley.jay.cd-to cdto-new-window-setting -string "Red Sands" ``` +To support ghostty: + +```bash +defaults write name.tuley.jay.cd-to cdto-terminal-app ghostty +``` + @@ -93,7 +99,7 @@ Version 2.0 (2005) * Ported to objective-c using appscript, boosting launch & execution speed * properly resolves aliases * no longer shows icon in dock on launch - + Version 1.0 (2003) * targeted Panther OS X 10.3 * was applescript