Skip to content

Commit 63c307c

Browse files
authored
Merge pull request laullon#178 from tiennou/feature/iterm2-support
iTerm2 support
2 parents 6f5d027 + 953cf33 commit 63c307c

File tree

6 files changed

+241
-8
lines changed

6 files changed

+241
-8
lines changed

Classes/Util/PBTerminalUtil.m

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,85 @@
77

88
#import "PBTerminalUtil.h"
99
#import "Terminal.h"
10+
#import "iTerm2GeneratedScriptingBridge.h"
11+
#import "PBGitDefaults.h"
12+
13+
@interface PBTerminalUtil () <SBApplicationDelegate>
14+
@end
1015

1116
@implementation PBTerminalUtil
1217

13-
+ (NSString *) initialCommand:(NSURL *)workingDirectory {
14-
return [NSString stringWithFormat:@"cd \"%@\"; clear; echo '# Opened by GitX'; ",
15-
workingDirectory.path];
18+
+ (void)runCommand:(NSString *)command inDirectory:(NSURL *)directory {
19+
[[self terminalHandler] runCommand:command inDirectory:directory];
20+
}
21+
22+
+ (instancetype)terminalHandler {
23+
static dispatch_once_t onceToken;
24+
static PBTerminalUtil *term = nil;
25+
dispatch_once(&onceToken, ^{
26+
term = [[self alloc] init];
27+
});
28+
return term;
29+
}
30+
31+
- (void)runCommand:(NSString *)command inDirectory:(NSURL *)directory {
32+
NSString *terminalHandler = [PBGitDefaults terminalHandler];
33+
BOOL ran = NO;
34+
35+
if ([terminalHandler isEqualToString:@"com.googlecode.iterm2"]) {
36+
ran = [self runiTerm2Command:command inDirectory:directory];
37+
}
38+
39+
// Fall back to Apple Terminal.
40+
if (!ran) {
41+
if (![terminalHandler isEqualToString:@"com.apple.Terminal"])
42+
NSLog(@"Unexpected terminal handler %@, using Terminal.app", terminalHandler);
43+
ran = [self runTerminalCommand:command inDirectory:directory];
44+
}
45+
46+
if (!ran) {
47+
NSLog(@"No usable terminal handler found");
48+
}
1649
}
1750

18-
+ (void) runCommand:(NSString *)command inDirectory:(NSURL *)directory {
19-
NSString * initialCommand = [self initialCommand:directory];
20-
NSString * fullCommand = [initialCommand stringByAppendingString:command];
21-
51+
- (nullable id)eventDidFail:(const AppleEvent *)event withError:(NSError *)error {
52+
NSLog(@"terminal handler error: %@", error);
53+
return nil;
54+
}
55+
56+
- (BOOL)runTerminalCommand:(NSString *)command inDirectory:(NSURL *)directory {
57+
NSString *fullCommand = [NSString stringWithFormat:@"cd \"%@\"; clear; echo '# Opened by GitX'; %@", directory.path, command];
58+
2259
TerminalApplication *term = [SBApplication applicationWithBundleIdentifier: @"com.apple.Terminal"];
60+
if (!term)
61+
return NO;
62+
term.delegate = self;
63+
2364
[term doScript:fullCommand in: nil];
65+
66+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
67+
[term activate];
68+
});
69+
70+
return YES;
71+
}
72+
73+
- (BOOL)runiTerm2Command:(NSString *)command inDirectory:(NSURL *)directory {
74+
NSString *fullCommand = [NSString stringWithFormat:@"cd \"%@\"; clear; echo '# Opened by GitX'; %@", directory.path, command];
75+
76+
iTerm2Application *term = [SBApplication applicationWithBundleIdentifier: @"com.googlecode.iterm2"];
77+
if (!term)
78+
return NO;
79+
term.delegate = self;
80+
81+
iTerm2Window *win = [term createWindowWithDefaultProfileCommand:nil];
82+
[win.currentSession writeContentsOfFile:nil text:fullCommand newline:YES];
83+
2484
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
2585
[term activate];
2686
});
87+
88+
return YES;
2789
}
2890

29-
@end
91+
@end

Classes/git/PBGitDefaults.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
+ (NSInteger)historySearchMode;
3232
+ (void)setHistorySearchMode:(NSInteger)mode;
3333
+ (BOOL)useRepositoryWatcher;
34+
+ (NSString *)terminalHandler;
3435

3536

3637
// Suppressed Dialog Warnings

Classes/git/PBGitDefaults.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#define kHistorySearchMode @"PBHistorySearchMode"
3131
#define kSuppressedDialogWarnings @"Suppressed Dialog Warnings"
3232
#define kUseRepositoryWatcher @"PBUseRepositoryWatcher"
33+
#define kTerminalHandler @"PBTerminalHandler"
3334

3435
@implementation PBGitDefaults
3536

@@ -64,6 +65,8 @@ + (void)initialize
6465
forKey:kHistorySearchMode];
6566
[defaultValues setObject:[NSNumber numberWithBool:YES]
6667
forKey:kUseRepositoryWatcher];
68+
[defaultValues setObject:@"com.apple.Terminal"
69+
forKey:kTerminalHandler];
6770
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
6871
}
6972

@@ -226,4 +229,9 @@ + (BOOL) useRepositoryWatcher
226229
return [[NSUserDefaults standardUserDefaults] boolForKey:kUseRepositoryWatcher];
227230
}
228231

232+
+ (NSString *)terminalHandler
233+
{
234+
return [[NSUserDefaults standardUserDefaults] stringForKey:kTerminalHandler];
235+
}
236+
229237
@end
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* iTerm2.h
3+
*/
4+
5+
#import <AppKit/AppKit.h>
6+
#import <ScriptingBridge/ScriptingBridge.h>
7+
8+
9+
@class iTerm2Application, iTerm2Window, iTerm2Tab, iTerm2Session;
10+
11+
enum iTerm2SaveOptions {
12+
iTerm2SaveOptionsYes = 'yes ' /* Save the file. */,
13+
iTerm2SaveOptionsNo = 'no ' /* Do not save the file. */,
14+
iTerm2SaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
15+
};
16+
typedef enum iTerm2SaveOptions iTerm2SaveOptions;
17+
18+
@protocol iTerm2GenericMethods
19+
20+
- (void) delete; // Delete an object.
21+
- (void) duplicateTo:(SBObject *)to withProperties:(NSDictionary *)withProperties; // Copy object(s) and put the copies at a new location.
22+
- (BOOL) exists; // Verify if an object exists.
23+
- (void) moveTo:(SBObject *)to; // Move object(s) to a new location.
24+
- (void) close; // Close a document.
25+
- (iTerm2Tab *) createTabWithProfile:(NSString *)withProfile command:(NSString *)command; // Create a new tab
26+
- (iTerm2Tab *) createTabWithDefaultProfileCommand:(NSString *)command; // Create a new tab with the default profile
27+
- (void) writeContentsOfFile:(NSURL *)contentsOfFile text:(NSString *)text newline:(BOOL)newline; // Send text as though it was typed.
28+
- (void) select; // Make receiver visible and selected.
29+
- (iTerm2Session *) splitVerticallyWithProfile:(NSString *)withProfile command:(NSString *)command; // Split a session vertically.
30+
- (iTerm2Session *) splitVerticallyWithDefaultProfileCommand:(NSString *)command; // Split a session vertically, using the default profile for the new session
31+
- (iTerm2Session *) splitVerticallyWithSameProfileCommand:(NSString *)command; // Split a session vertically, using the original session's profile for the new session
32+
- (iTerm2Session *) splitHorizontallyWithProfile:(NSString *)withProfile command:(NSString *)command; // Split a session horizontally.
33+
- (iTerm2Session *) splitHorizontallyWithDefaultProfileCommand:(NSString *)command; // Split a session horizontally, using the default profile for the new session
34+
- (iTerm2Session *) splitHorizontallyWithSameProfileCommand:(NSString *)command; // Split a session horizontally, using the original session's profile for the new session
35+
- (NSString *) variableNamed:(NSString *)named; // Returns the value of a session variable with the given name
36+
- (NSString *) setVariableNamed:(NSString *)named to:(NSString *)to; // Sets the value of a session variable
37+
- (void) revealHotkeyWindow; // Reveals a hotkey window. Only to be called on windows that are hotkey windows.
38+
- (void) hideHotkeyWindow; // Hides a hotkey window. Only to be called on windows that are hotkey windows.
39+
- (void) toggleHotkeyWindow; // Toggles the visibility of a hotkey window. Only to be called on windows that are hotkey windows.
40+
41+
@end
42+
43+
44+
45+
/*
46+
* Standard Suite
47+
*/
48+
49+
// The application's top-level scripting object.
50+
@interface iTerm2Application : SBApplication
51+
52+
- (SBElementArray<iTerm2Window *> *) windows;
53+
54+
@property (copy) iTerm2Window *currentWindow; // The frontmost window
55+
@property (copy, readonly) NSString *name; // The name of the application.
56+
@property (readonly) BOOL frontmost; // Is this the frontmost (active) application?
57+
@property (copy, readonly) NSString *version; // The version of the application.
58+
59+
- (iTerm2Window *) createWindowWithProfile:(NSString *)x command:(NSString *)command; // Create a new window
60+
- (iTerm2Window *) createHotkeyWindowWithProfile:(NSString *)x; // Create a hotkey window
61+
- (iTerm2Window *) createWindowWithDefaultProfileCommand:(NSString *)command; // Create a new window with the default profile
62+
63+
@end
64+
65+
// A window.
66+
@interface iTerm2Window : SBObject <iTerm2GenericMethods>
67+
68+
- (SBElementArray<iTerm2Tab *> *) tabs;
69+
70+
- (NSInteger) id; // The unique identifier of the session.
71+
@property (copy, readonly) NSString *alternateIdentifier; // The alternate unique identifier of the session.
72+
@property (copy, readonly) NSString *name; // The full title of the window.
73+
@property NSInteger index; // The index of the window, ordered front to back.
74+
@property NSRect bounds; // The bounding rectangle of the window.
75+
@property (readonly) BOOL closeable; // Whether the window has a close box.
76+
@property (readonly) BOOL miniaturizable; // Whether the window can be minimized.
77+
@property BOOL miniaturized; // Whether the window is currently minimized.
78+
@property (readonly) BOOL resizable; // Whether the window can be resized.
79+
@property BOOL visible; // Whether the window is currently visible.
80+
@property (readonly) BOOL zoomable; // Whether the window can be zoomed.
81+
@property BOOL zoomed; // Whether the window is currently zoomed.
82+
@property BOOL frontmost; // Whether the window is currently the frontmost window.
83+
@property (copy) iTerm2Tab *currentTab; // The currently selected tab
84+
@property (copy) iTerm2Session *currentSession; // The current session in a window
85+
@property BOOL isHotkeyWindow; // Whether the window is a hotkey window.
86+
@property (copy) NSString *hotkeyWindowProfile; // If the window is a hotkey window, this gives the name of the profile that created the window.
87+
@property NSPoint position; // The position of the window, relative to the upper left corner of the screen.
88+
@property NSPoint origin; // The position of the window, relative to the lower left corner of the screen.
89+
@property NSPoint size; // The width and height of the window
90+
@property NSRect frame; // The bounding rectangle, relative to the lower left corner of the screen.
91+
92+
93+
@end
94+
95+
96+
97+
/*
98+
* iTerm2 Suite
99+
*/
100+
101+
// A terminal tab
102+
@interface iTerm2Tab : SBObject <iTerm2GenericMethods>
103+
104+
- (SBElementArray<iTerm2Session *> *) sessions;
105+
106+
@property (copy) iTerm2Session *currentSession; // The current session in a tab
107+
@property NSInteger index; // Index of tab in parent tab view control
108+
109+
110+
@end
111+
112+
// A terminal session
113+
@interface iTerm2Session : SBObject <iTerm2GenericMethods>
114+
115+
- (NSString *) id; // The unique identifier of the session.
116+
@property BOOL isProcessing; // The session has received output recently.
117+
@property BOOL isAtShellPrompt; // The terminal is at the shell prompt. Requires shell integration.
118+
@property NSInteger columns;
119+
@property NSInteger rows;
120+
@property (copy, readonly) NSString *tty;
121+
@property (copy) NSString *contents; // The currently visible contents of the session.
122+
@property (copy, readonly) NSString *text; // The currently visible contents of the session.
123+
@property (copy) NSString *colorPreset;
124+
@property (copy) NSColor *backgroundColor;
125+
@property (copy) NSColor *boldColor;
126+
@property (copy) NSColor *cursorColor;
127+
@property (copy) NSColor *cursorTextColor;
128+
@property (copy) NSColor *foregroundColor;
129+
@property (copy) NSColor *selectedTextColor;
130+
@property (copy) NSColor *selectionColor;
131+
@property (copy) NSColor *ANSIBlackColor;
132+
@property (copy) NSColor *ANSIRedColor;
133+
@property (copy) NSColor *ANSIGreenColor;
134+
@property (copy) NSColor *ANSIYellowColor;
135+
@property (copy) NSColor *ANSIBlueColor;
136+
@property (copy) NSColor *ANSIMagentaColor;
137+
@property (copy) NSColor *ANSICyanColor;
138+
@property (copy) NSColor *ANSIWhiteColor;
139+
@property (copy) NSColor *ANSIBrightBlackColor;
140+
@property (copy) NSColor *ANSIBrightRedColor;
141+
@property (copy) NSColor *ANSIBrightGreenColor;
142+
@property (copy) NSColor *ANSIBrightYellowColor;
143+
@property (copy) NSColor *ANSIBrightBlueColor;
144+
@property (copy) NSColor *ANSIBrightMagentaColor;
145+
@property (copy) NSColor *ANSIBrightCyanColor;
146+
@property (copy) NSColor *ANSIBrightWhiteColor;
147+
@property (copy) NSColor *underlineColor;
148+
@property BOOL useUnderlineColor; // Whether the use a dedicated color for underlining.
149+
@property (copy) NSString *backgroundImage;
150+
@property (copy) NSString *name;
151+
@property double transparency;
152+
@property (copy, readonly) NSString *uniqueID;
153+
@property (copy, readonly) NSString *profileName; // The session's profile name
154+
@property (copy) NSString *answerbackString; // ENQ Answerback string
155+
156+
157+
@end
158+

GitX.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@
615615
97CF01F618A6C5BB00E30F2B /* deleted_file.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = deleted_file.pdf; sourceTree = "<group>"; };
616616
97CF01F718A6C5BB00E30F2B /* empty_file.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = empty_file.pdf; sourceTree = "<group>"; };
617617
97CF01F818A6C5BB00E30F2B /* new_file.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = new_file.pdf; sourceTree = "<group>"; };
618+
A1021294218C5A2000D97D11 /* iTerm2GeneratedScriptingBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = iTerm2GeneratedScriptingBridge.h; sourceTree = "<group>"; };
618619
A2F8D0DD17AAB32500580B84 /* PBGitStash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitStash.h; sourceTree = "<group>"; };
619620
A2F8D0DE17AAB32500580B84 /* PBGitStash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitStash.m; sourceTree = "<group>"; };
620621
A2F8D0E917AAB95E00580B84 /* PBSourceViewGitStashItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBSourceViewGitStashItem.h; sourceTree = "<group>"; };
@@ -872,6 +873,7 @@
872873
4D6E4F791E56851A004C3A6F /* PBMacros.h */,
873874
4DF173E721A1D60A003CD3CE /* NSAppearance+PBDarkMode.h */,
874875
4DF173E821A1D60A003CD3CE /* NSAppearance+PBDarkMode.m */,
876+
A1021294218C5A2000D97D11 /* iTerm2GeneratedScriptingBridge.h */,
875877
);
876878
path = Classes;
877879
sourceTree = "<group>";

Resources/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
<string>0.12</string>
5353
<key>LSApplicationCategoryType</key>
5454
<string>public.app-category.developer-tools</string>
55+
<key>NSAppleEventsUsageDescription</key>
56+
<string>GitX needs authorization in order to open your Terminal application.</string>
5557
<key>NSAppleScriptEnabled</key>
5658
<true/>
5759
<key>NSMainNibFile</key>

0 commit comments

Comments
 (0)