forked from gnachman/iTerm2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TmuxHistoryParser.m
97 lines (88 loc) · 3.14 KB
/
TmuxHistoryParser.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
//
// TmuxHistoryParser.m
// iTerm
//
// Created by George Nachman on 11/29/11.
//
#import "TmuxHistoryParser.h"
#import "ScreenChar.h"
#import "VT100Screen.h"
#import "VT100Terminal.h"
@implementation TmuxHistoryParser
+ (TmuxHistoryParser *)sharedInstance
{
static TmuxHistoryParser *instance;
if (!instance) {
instance = [[TmuxHistoryParser alloc] init];
}
return instance;
}
// Returns nil on error
- (NSData *)dataForHistoryLine:(NSString *)hist
withTerminal:(VT100Terminal *)terminal
ambiguousIsDoubleWidth:(BOOL)ambiguousIsDoubleWidth
{
screen_char_t *screenChars;
NSMutableData *result = [NSMutableData data];
[terminal putStreamData:[hist dataUsingEncoding:NSUTF8StringEncoding]];
VT100TCC token;
token = [terminal getNextToken];
while (token.type != VT100_WAIT &&
token.type != VT100CC_NULL) {
if (token.type != VT100_NOTSUPPORT) {
int len = 0;
switch (token.type) {
case VT100_STRING:
case VT100_ASCIISTRING:
// Allocate double space in case they're all double-width characters.
screenChars = malloc(sizeof(screen_char_t) * 2 * token.u.string.length);
StringToScreenChars(token.u.string,
screenChars,
[terminal foregroundColorCode],
[terminal backgroundColorCode],
&len,
ambiguousIsDoubleWidth,
NULL);
if ([terminal charset]) {
TranslateCharacterSet(screenChars, len);
}
[result appendBytes:screenChars
length:sizeof(screen_char_t) * len];
free(screenChars);
break;
case VT100CSI_SGR:
break;
case VT100CC_SO:
break;
case VT100CC_SI:
break;
}
}
token = [terminal getNextToken];
}
return result;
}
// Return an NSArray of NSData's. Each NSData is an array of screen_char_t's,
// with the last element in each being the newline. Returns nil on error.
- (NSArray *)parseDumpHistoryResponse:(NSString *)response
ambiguousIsDoubleWidth:(BOOL)ambiguousIsDoubleWidth
{
if (![response length]) {
return [NSArray array];
}
NSArray *lines = [response componentsSeparatedByString:@"\n"];
NSMutableArray *screenLines = [NSMutableArray array];
VT100Terminal *terminal = [[[VT100Terminal alloc] init] autorelease];
[terminal setEncoding:NSUTF8StringEncoding];
for (NSString *line in lines) {
NSData *data = [self dataForHistoryLine:line
withTerminal:terminal
ambiguousIsDoubleWidth:ambiguousIsDoubleWidth];
if (!data) {
return nil;
}
[screenLines addObject:data];
}
return screenLines;
}
@end