diff --git a/Cocoa/GBTerminalTextFieldCell.m b/Cocoa/GBTerminalTextFieldCell.m index 95f6551..47a3a35 100644 --- a/Cocoa/GBTerminalTextFieldCell.m +++ b/Cocoa/GBTerminalTextFieldCell.m @@ -25,6 +25,7 @@ { NSMutableOrderedSet *lines; NSUInteger current_line; + bool reverse_search_mode; } - (instancetype)init @@ -39,15 +40,23 @@ - (void)moveUp:(id)sender { + reverse_search_mode = false; if (current_line != 0) { current_line--; [self setString:[lines objectAtIndex:current_line]]; } + else { + [self setSelectedRange:NSMakeRange(0, 0)]; + NSBeep(); + } } - (void)moveDown:(id)sender { + reverse_search_mode = false; if (current_line == [lines count]) { + [self setString:@""]; + NSBeep(); return; } current_line++; @@ -59,7 +68,7 @@ } } --(void) insertNewline:(id)sender +-(void)insertNewline:(id)sender { if ([self.string length]) { NSString *string = [self.string copy]; @@ -68,6 +77,116 @@ } [super insertNewline:sender]; current_line = [lines count]; + reverse_search_mode = false; } +- (void)keyDown:(NSEvent *)event +{ + if (event.keyCode == kVK_ANSI_R && (event.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagControl) { + if ([lines count] == 0) { + NSBeep(); + return; + } + if (!reverse_search_mode) { + [self selectAll:self]; + current_line = [lines count] - 1; + } + else { + if (current_line != 0) { + current_line--; + } + else { + NSBeep(); + } + } + + if (self.string.length) { + [self updateReverseSearch]; + } + else { + [self setNeedsDisplay:YES]; + reverse_search_mode = true; + } + + } + else { + [super keyDown:event]; + } +} + +- (void) updateReverseSearch +{ + NSUInteger old_line = current_line; + reverse_search_mode = false; + NSString *substring = [self.string substringWithRange:self.selectedRange]; + do { + NSString *line = [lines objectAtIndex:current_line]; + NSRange range = [line rangeOfString:substring]; + if (range.location != NSNotFound) { + self.string = line; + [self setSelectedRange:range]; + reverse_search_mode = true; + return; + } + } while (current_line--); + current_line = old_line; + reverse_search_mode = true; + NSBeep(); +} + +- (void) insertText:(NSString *)string replacementRange:(NSRange)range +{ + if (reverse_search_mode) { + range = self.selectedRange; + self.string = [[self.string substringWithRange:range] stringByAppendingString:string]; + [self selectAll:nil]; + [self updateReverseSearch]; + } + else { + [super insertText:string replacementRange:range]; + } +} + +-(void)deleteBackward:(id)sender +{ + if (reverse_search_mode && self.string.length) { + NSRange range = self.selectedRange; + range.length--; + self.string = [self.string substringWithRange:range]; + if (range.length) { + [self selectAll:nil]; + [self updateReverseSearch]; + } + else { + reverse_search_mode = true; + current_line = [lines count] - 1; + } + } + else { + [super deleteBackward:sender]; + } +} + +-(void)setSelectedRanges:(NSArray *)ranges affinity:(NSSelectionAffinity)affinity stillSelecting:(BOOL)stillSelectingFlag +{ + reverse_search_mode = false; + [super setSelectedRanges:ranges affinity:affinity stillSelecting:stillSelectingFlag]; +} + +- (BOOL)resignFirstResponder { + reverse_search_mode = false; + return [super resignFirstResponder]; +} + +-(void)drawRect:(NSRect)dirtyRect +{ + [super drawRect:dirtyRect]; + if (reverse_search_mode && [super string].length == 0) { + NSMutableDictionary *attributes = [self.typingAttributes mutableCopy]; + NSColor *color = [attributes[NSForegroundColorAttributeName] colorWithAlphaComponent:0.5]; + [attributes setObject:color forKey:NSForegroundColorAttributeName]; + [[[NSAttributedString alloc] initWithString:@"Reverse search..." attributes:attributes] drawAtPoint:NSMakePoint(2, 0)]; + } + +} @end