forked from niw/terminaltabswitching
-
Notifications
You must be signed in to change notification settings - Fork 13
/
TerminalTabSwitching.m
120 lines (99 loc) · 4.27 KB
/
TerminalTabSwitching.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#import "JRSwizzle.h"
@implementation NSWindowController(TerminalTabSwitching)
- (void)selectRepresentedTabViewItem:(NSMenuItem*)item
{
NSTabViewItem* tabViewItem = [item representedObject];
[[tabViewItem tabView] selectTabViewItem:tabViewItem];
}
- (void)updateTabListMenu
{
NSMenu* windowsMenu = [[NSApplication sharedApplication] windowsMenu];
for(NSMenuItem* menuItem in [windowsMenu itemArray])
{
// NSString* key = [menuItem keyEquivalent];
// if(([key length] == 1 && 0x30 <= [key characterAtIndex:0] && [key characterAtIndex:0] <= 0x39)
// || [menuItem action] == @selector(selectRepresentedTabViewItem:))
if([menuItem action] == @selector(selectRepresentedTabViewItem:))
[windowsMenu removeItem:menuItem];
}
NSArray* tabViewItems = [[self valueForKey:@"tabView"] tabViewItems];
for(size_t tabIndex = 0; tabIndex < [tabViewItems count]; ++tabIndex)
{
NSString* keyEquivalent = (tabIndex < 10) ? [NSString stringWithFormat:@"%ld", (tabIndex+1)%10] : @"";
NSTabViewItem* tabViewItem = [tabViewItems objectAtIndex:tabIndex];
NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:[tabViewItem label]
action:@selector(selectRepresentedTabViewItem:)
keyEquivalent:keyEquivalent];
[menuItem setRepresentedObject:tabViewItem];
[windowsMenu addItem:menuItem];
[menuItem release];
}
}
- (void)TerminalTabSwitching_windowDidLoad
{
// This method is not called at first time for the first main window.
[self TerminalTabSwitching_windowDidLoad];
[[NSApplication sharedApplication] removeWindowsItem:[self window]];
[[self window] setExcludedFromWindowsMenu:YES];
[self updateTabListMenu];
}
- (void)TerminalTabSwitching_windowDidBecomeMain:(id)fp8
{
[self TerminalTabSwitching_windowDidBecomeMain:fp8];
[self updateTabListMenu];
}
- (void)TerminalTabSwitching_newTab:(id)fp8
{
[self TerminalTabSwitching_newTab:fp8];
[self updateTabListMenu];
}
- (void)TerminalTabSwitching_tabView:(id)arg1 didCloseTabViewItem:(id)arg2
{
[self TerminalTabSwitching_tabView:arg1 didCloseTabViewItem:arg2];
[self updateTabListMenu];
}
- (void)TerminalTabSwitching_mergeAllWindows:(id)fp8
{
[self TerminalTabSwitching_mergeAllWindows:fp8];
[self updateTabListMenu];
}
@end
#pragma mark -
@implementation NSTabViewItem(TerminalTabSwitching)
- (void)TerminalTabSwitching_setReorderState:(int)arg1
{
[self TerminalTabSwitching_setReorderState:arg1];
if(arg1 == 0) {
// FIXME what is the best way to grab current NSWindowController from self
[[[[NSApplication sharedApplication] mainWindow] windowController]updateTabListMenu];
}
}
@end
#pragma mark -
@interface TerminalTabSwitching : NSObject
@end
@implementation TerminalTabSwitching
+ (void)load
{
[NSClassFromString(@"TTWindowController") jr_swizzleMethod:@selector(windowDidLoad) withMethod:@selector(TerminalTabSwitching_windowDidLoad) error:NULL];
[NSClassFromString(@"TTWindowController") jr_swizzleMethod:@selector(windowDidBecomeMain:) withMethod:@selector(TerminalTabSwitching_windowDidBecomeMain:) error:NULL];
[NSClassFromString(@"TTWindowController") jr_swizzleMethod:@selector(newTab:) withMethod:@selector(TerminalTabSwitching_newTab:) error:NULL];
[NSClassFromString(@"TTWindowController") jr_swizzleMethod:@selector(tabView:didCloseTabViewItem:) withMethod:@selector(TerminalTabSwitching_tabView:didCloseTabViewItem:) error:NULL];
[NSClassFromString(@"TTWindowController") jr_swizzleMethod:@selector(mergeAllWindows:) withMethod:@selector(TerminalTabSwitching_mergeAllWindows:) error:NULL];
[NSClassFromString(@"TTTabViewItem") jr_swizzleMethod:@selector(setReorderState:) withMethod:@selector(TerminalTabSwitching_setReorderState:) error:NULL];
NSApplication *app = [NSApplication sharedApplication];
NSWindow *mainWindow = [app mainWindow];
// NOTE The issue of timing to install SIMBL hook, we need to exclude the window already laoded here.
// After loaded, we can exclude new windows inside windowDidLoad callback method.
BOOL shouldExcludeMainWindow = ![mainWindow isExcludedFromWindowsMenu];
if(shouldExcludeMainWindow) {
[app removeWindowsItem:mainWindow];
[mainWindow setExcludedFromWindowsMenu:YES];
}
[[app windowsMenu] addItem:[NSMenuItem separatorItem]];
if(shouldExcludeMainWindow) {
[[mainWindow windowController] updateTabListMenu];
}
NSLog(@"TerminalTabSwitching installed");
}
@end