Skip to content

Commit

Permalink
Merge in changes for tmux 1.8
Browse files Browse the repository at this point in the history
  • Loading branch information
gnachman committed Mar 10, 2013
2 parents 99221cc + b3d4acf commit ac8c0f2
Show file tree
Hide file tree
Showing 25 changed files with 555 additions and 536 deletions.
21 changes: 20 additions & 1 deletion NSStringITerm.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,27 @@

#import <Foundation/Foundation.h>

// This is the standard unicode replacement character for when input couldn't
// be parsed properly but we need to render something there.
#define UNICODE_REPLACEMENT_CHAR 0xfffd

// Examine the leading UTF-8 sequence in a char array and check that it
// is properly encoded. Computes the number of bytes to use for the
// first code point. Returns the first code point, if it exists, in *result.
//
// Return value:
// positive: This many bytes compose a legal Unicode character.
// negative: abs(this many) bytes are illegal, should be replaced by one
// single replacement symbol.
// zero: Unfinished sequence, input needs to grow.
int decode_utf8_char(const unsigned char * restrict datap,
int datalen,
int * restrict result);

@interface NSString (iTerm)

+ (NSString *)stringWithInt:(int)num;
+ (BOOL)isDoubleWidthCharacter:(int)unicode
encoding:(NSStringEncoding)e
ambiguousIsDoubleWidth:(BOOL)ambiguousIsDoubleWidth;

- (NSMutableString *)stringReplaceSubstringFrom:(NSString *)oldSubstring to:(NSString *)newSubstring;
Expand All @@ -60,4 +75,8 @@
// Convert a string of hex values (an even number of [0-9A-Fa-f]) into data.
- (NSData *)dataFromHexValues;

// Always returns a non-null vaule, but it may contain replacement chars for
// malformed utf-8 sequences.
- (NSString *)initWithUTF8DataIgnoringErrors:(NSData *)data;

@end
95 changes: 94 additions & 1 deletion NSStringITerm.m
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ + (NSString *)stringWithInt:(int)num
}

+ (BOOL)isDoubleWidthCharacter:(int)unicode
encoding:(NSStringEncoding)e
ambiguousIsDoubleWidth:(BOOL)ambiguousIsDoubleWidth
{
if (unicode <= 0xa0 ||
Expand Down Expand Up @@ -458,4 +457,98 @@ - (NSString *)stringByEscapingQuotes {
stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
}

int decode_utf8_char(const unsigned char *datap,
int datalen,
int * restrict result)
{
unsigned int theChar;
int utf8Length;
unsigned char c;
// This maps a utf-8 sequence length to the smallest code point it should
// encode (e.g., using 5 bytes to encode an ascii character would be
// considered an error).
unsigned int smallest[7] = { 0, 0, 0x80UL, 0x800UL, 0x10000UL, 0x200000UL, 0x4000000UL };

if (datalen == 0) {
return 0;
}

c = *datap;
if ((c & 0x80) == 0x00) {
*result = c;
return 1;
} else if ((c & 0xE0) == 0xC0) {
theChar = c & 0x1F;
utf8Length = 2;
} else if ((c & 0xF0) == 0xE0) {
theChar = c & 0x0F;
utf8Length = 3;
} else if ((c & 0xF8) == 0xF0) {
theChar = c & 0x07;
utf8Length = 4;
} else if ((c & 0xFC) == 0xF8) {
theChar = c & 0x03;
utf8Length = 5;
} else if ((c & 0xFE) == 0xFC) {
theChar = c & 0x01;
utf8Length = 6;
} else {
return -1;
}
for (int i = 1; i < utf8Length; i++) {
if (datalen <= i) {
return 0;
}
c = datap[i];
if ((c & 0xc0) != 0x80) {
// Expected a continuation character but did not get one.
return -i;
}
theChar = (theChar << 6) | (c & 0x3F);
}

if (theChar < smallest[utf8Length]) {
// Reject overlong sequences.
return -utf8Length;
}

*result = (int)theChar;
return utf8Length;
}

- (NSString *)initWithUTF8DataIgnoringErrors:(NSData *)data {
const unsigned char *p = data.bytes;
int len = data.length;
int utf8DecodeResult;
int theChar = 0;
NSMutableData *utf16Data = [NSMutableData data];

while (len > 0) {
utf8DecodeResult = decode_utf8_char(p, len, &theChar);
if (utf8DecodeResult == 0) {
// Stop on end of stream.
break;
} else if (utf8DecodeResult < 0) {
theChar = UNICODE_REPLACEMENT_CHAR;
utf8DecodeResult = -utf8DecodeResult;
} else if (theChar > 0xFFFF) {
// Convert to surrogate pair.
UniChar high, low;
high = ((theChar - 0x10000) >> 10) + 0xd800;
low = (theChar & 0x3ff) + 0xdc00;

[utf16Data appendBytes:&high length:sizeof(high)];
theChar = low;
}

UniChar c = theChar;
[utf16Data appendBytes:&c length:sizeof(c)];

p += utf8DecodeResult;
len -= utf8DecodeResult;
}

return [self initWithData:utf16Data encoding:NSUTF16LittleEndianStringEncoding];
}

@end
14 changes: 12 additions & 2 deletions PTYSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -2339,7 +2339,7 @@ - (void)setUniqueID:(NSString*)uniqueID

- (NSString*)formattedName:(NSString*)base
{
NSString *prefix = tmuxController_ ? @"↣ " : @"";
NSString *prefix = tmuxController_ ? [NSString stringWithFormat:@"↣ %@: ", [[self tab] tmuxWindowName]] : @"";

BOOL baseIsBookmarkName = [base isEqualToString:bookmarkName];
PreferencePanel* panel = [PreferencePanel sharedInstance];
Expand Down Expand Up @@ -2880,6 +2880,7 @@ - (BOOL)doubleWidth
- (void)setDoubleWidth:(BOOL)set
{
doubleWidth = set;
tmuxController_.ambiguousIsDoubleWidth = set;
}

- (BOOL)xtermMouseReporting
Expand Down Expand Up @@ -3242,7 +3243,11 @@ - (void)setFont:(NSFont*)font
}
// If the window isn't able to adjust, or adjust enough, make the session
// work with whatever size we ended up having.
[[self tab] fitSessionToCurrentViewSize:self];
if ([self isTmuxClient]) {
[tmuxController_ windowDidResize:[[self tab] realParentWindow]];
} else {
[[self tab] fitSessionToCurrentViewSize:self];
}
}

- (void)synchronizeTmuxFonts:(NSNotification *)notification
Expand Down Expand Up @@ -3630,6 +3635,7 @@ - (void)startTmuxMode
tmuxMode_ = TMUX_GATEWAY;
tmuxGateway_ = [[TmuxGateway alloc] initWithDelegate:self];
tmuxController_ = [[TmuxController alloc] initWithGateway:tmuxGateway_];
tmuxController_.ambiguousIsDoubleWidth = doubleWidth;
NSSize theSize;
Profile *tmuxBookmark = [PTYTab tmuxBookmark];
theSize.width = MAX(1, [[tmuxBookmark objectForKey:KEY_COLUMNS] intValue]);
Expand Down Expand Up @@ -3746,6 +3752,10 @@ - (void)tmuxWindowClosedWithId:(int)windowId

- (void)tmuxWindowRenamedWithId:(int)windowId to:(NSString *)newName
{
PTYTab *tab = [tmuxController_ window:windowId];
if (tab) {
[tab setTmuxWindowName:newName];
}
[tmuxController_ windowWasRenamedWithId:windowId to:newName];
}

Expand Down
4 changes: 4 additions & 0 deletions PTYTab.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ static const int MIN_SESSION_COLUMNS = 2;

// Temporarily hidden live views (this is needed to hold a reference count).
NSMutableArray *hiddenLiveViews_; // SessionView objects

NSString *tmuxWindowName_;
}

// init/dealloc
Expand Down Expand Up @@ -255,6 +257,8 @@ static const int MIN_SESSION_COLUMNS = 2;
- (NSSize)tmuxSize;
// Size we are given the current layout
- (NSSize)maxTmuxSize;
- (NSString *)tmuxWindowName;
- (void)setTmuxWindowName:(NSString *)tmuxWindowName;

- (int)tmuxWindow;
- (BOOL)isTmuxTab;
Expand Down
24 changes: 19 additions & 5 deletions PTYTab.m
Original file line number Diff line number Diff line change
Expand Up @@ -2113,8 +2113,8 @@ - (void)notifyWindowChanged
}

+ (PTYTab *)tabWithArrangement:(NSDictionary*)arrangement
inTerminal:(PseudoTerminal*)term
hasFlexibleView:(BOOL)hasFlexible
inTerminal:(PseudoTerminal*)term
hasFlexibleView:(BOOL)hasFlexible
{
PTYTab* theTab;
// Build a tree with splitters and SessionViews but no PTYSessions.
Expand Down Expand Up @@ -2335,6 +2335,18 @@ - (int)tmuxWindow
return tmuxWindow_;
}

- (NSString *)tmuxWindowName
{
return tmuxWindowName_ ? tmuxWindowName_ : @"tmux";
}

- (void)setTmuxWindowName:(NSString *)tmuxWindowName
{
[tmuxWindowName_ autorelease];
tmuxWindowName_ = [tmuxWindowName retain];
[[self realParentWindow] setWindowTitle];
}

+ (Profile *)tmuxBookmark
{
Profile *bookmark = [[ProfileModel sharedInstance] bookmarkWithName:@"tmux"];
Expand Down Expand Up @@ -2970,9 +2982,11 @@ - (void)splitView:(PTYSplitView *)splitView draggingDidEndOfSplit:(int)splitterI

// Ask the tmux server to perform the move and we'll update our layout when
// it finishes.
[tmuxController_ windowPane:[session tmuxPane]
resizedBy:amount
horizontally:[splitView isVertical]];
if (amount > 0) {
[tmuxController_ windowPane:[session tmuxPane]
resizedBy:amount
horizontally:[splitView isVertical]];
}
}

// Prevent any session from becoming smaller than its minimum size because of
Expand Down
2 changes: 0 additions & 2 deletions PTYTextView.m
Original file line number Diff line number Diff line change
Expand Up @@ -6732,7 +6732,6 @@ - (int)inputMethodEditorLength
fg,
bg,
&len,
0,
[[dataSource session] doubleWidth],
NULL);

Expand Down Expand Up @@ -6778,7 +6777,6 @@ - (BOOL)drawInputMethodEditorTextAt:(int)xStart
fg,
bg,
&len,
0,
[[dataSource session] doubleWidth],
&cursorIndex);
int cursorX = 0;
Expand Down
4 changes: 2 additions & 2 deletions PseudoTerminal.m
Original file line number Diff line number Diff line change
Expand Up @@ -1382,7 +1382,7 @@ - (void)loadTmuxLayout:(NSMutableDictionary *)parseTree
inTerminal:self
tmuxWindow:window
tmuxController:tmuxController];
[self setWindowTitle:name];
[tab setTmuxWindowName:name];
[tab setReportIdealSizeAsCurrent:YES];
[self fitWindowToTabs];
[tab setReportIdealSizeAsCurrent:NO];
Expand Down Expand Up @@ -2167,7 +2167,7 @@ - (void)windowDidToggleToolbarVisibility:(id)sender
if ([term lionFullScreen]) {
[term restoreFrameAfterToolbarToggle];
} else {
PtyLog(@"zeroing preToolbarToggleFrame_");
PtyLog(@"zeroing preToolbarToggleFrame_");
preToolbarToggleFrame_ = NSZeroRect;
}
if ([[[term window] toolbar] isVisible] != [itad toolbarShouldBeVisible]) {
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
This site hosts code for <a href="http://iterm2.com">iTerm2</a>. Issues are still on <a href="http://iterm2.com/bugs">Google Code</a> becaue Github doesn't support attachments.

8 changes: 4 additions & 4 deletions ScreenChar.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
*/

#import <Cocoa/Cocoa.h>
#import "NSStringITerm.h"

// This is used in the rightmost column when a double-width character would
// have been split in half and was wrapped to the next line. It is nonprintable
Expand Down Expand Up @@ -62,10 +63,7 @@
#define ITERM2_PRIVATE_BEGIN 0xf000
#define ITERM2_PRIVATE_END 0xf003

// This is the standard unicode replacement character for when input couldn't
// be parsed properly but we need to render something there.
#define UNICODE_REPLACEMENT_CHAR 0xfffd
#define ONECHAR_UNKNOWN ('?') // Used for encodings other than utf-8.
#define ONECHAR_UNKNOWN ('?') // Relacement character for encodings other than utf-8.

// Alternate semantics definitions
// Default background color
Expand Down Expand Up @@ -235,3 +233,5 @@ NSString* ScreenCharArrayToStringDebug(screen_char_t* screenChars,

// Convert an array of chars to a string, quickly.
NSString* CharArrayToString(unichar* charHaystack, int o);

void DumpScreenCharArray(screen_char_t* screenChars, int lineLength);
4 changes: 4 additions & 0 deletions ScreenChar.m
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,10 @@ BOOL IsHighSurrogate(unichar c)
freeWhenDone:NO] autorelease];
}

void DumpScreenCharArray(screen_char_t* screenChars, int lineLength) {
NSLog(@"%@", ScreenCharArrayToStringDebug(screenChars, lineLength));
}

NSString* ScreenCharArrayToStringDebug(screen_char_t* screenChars,
int lineLength) {
NSMutableString* result = [NSMutableString stringWithCapacity:lineLength];
Expand Down
2 changes: 2 additions & 0 deletions TmuxController.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extern NSString *kTmuxControllerAttachedSessionDidChange;
@property (nonatomic, retain) NSMutableDictionary *windowPositions;
@property (nonatomic, copy) NSString *sessionName;
@property (nonatomic, retain) NSArray *sessions;
@property (nonatomic, assign) BOOL ambiguousIsDoubleWidth;

- (id)initWithGateway:(TmuxGateway *)gateway;
- (void)openWindowsInitial;
Expand Down Expand Up @@ -117,6 +118,7 @@ extern NSString *kTmuxControllerAttachedSessionDidChange;
- (void)killSession:(NSString *)sessionName;
- (void)attachToSession:(NSString *)sessionName;
- (void)addSessionWithName:(NSString *)sessionName;
// NOTE: If the session name is bogus (or any other error occurs) the selector will not be called.
- (void)listWindowsInSession:(NSString *)sessionName
target:(id)target
selector:(SEL)selector
Expand Down
Loading

0 comments on commit ac8c0f2

Please sign in to comment.