Skip to content
Snippets Groups Projects
Commit f37ebb5a authored by George Nachman's avatar George Nachman
Browse files

Implement tail find

parent 013f2532
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -32,6 +32,7 @@
#import "TextViewWrapper.h"
#import "FindViewController.h"
#import "ITAddressBookMgr.h"
#import "LineBuffer.h"
 
#include <sys/time.h>
 
Loading
Loading
@@ -227,6 +228,9 @@ typedef enum {
 
// Does the terminal think this session is focused?
BOOL focused_;
FindContext tailFindContext_;
NSTimer *tailFindTimer_;
}
 
// Return the current pasteboard value as a string.
Loading
Loading
@@ -508,6 +512,7 @@ typedef enum {
- (void)launchCoprocessWithCommand:(NSString *)command;
 
- (void)setFocused:(BOOL)focused;
- (BOOL)wantsContentChangedNotification;
 
@end
 
Loading
Loading
@@ -528,5 +533,8 @@ typedef enum {
- (NSString*)_lang;
- (NSString*)encodingName;
- (void)setDvrFrame;
- (void)stopTailFind;
- (void)beginTailFind;
- (void)continueTailFind;
 
@end
Loading
Loading
@@ -31,6 +31,7 @@
#import "ScreenChar.h"
#import "PreferencePanel.h"
#import "Trouter.h"
#import "LineBuffer.h"
 
#include <sys/time.h>
#define PRETTY_BOLD
Loading
Loading
@@ -298,6 +299,9 @@ typedef struct PTYFontInfo PTYFontInfo;
 
// Show a background indicator when in broadcast input mode
BOOL useBackgroundIndicator_;
// Find context just after initialization.
FindContext initialFindContext_;
}
 
+ (NSCursor *)textViewCursor;
Loading
Loading
@@ -531,6 +535,11 @@ typedef struct PTYFontInfo PTYFontInfo;
- (double)perceivedBrightness:(NSColor*)c;
- (void)drawOutlineInRect:(NSRect)rect topOnly:(BOOL)topOnly;
 
// Add a search result for highlighting in yellow.
- (void)addResultFromX:(int)resStartX absY:(long long)absStartY toX:(int)resEndX toAbsY:(long long)absEndY;
- (FindContext *)initialFindContext;
@end
 
//
Loading
Loading
Loading
Loading
@@ -302,6 +302,7 @@ void StringToScreenChars(NSString *s,
- (BOOL)continueFindAllResults:(NSMutableArray*)results
inContext:(FindContext*)context;
- (void)cancelFindInContext:(FindContext*)context;
- (void)setFindContextPositionToEnd:(FindContext *)context;
 
- (void) dumpDebugLog;
 
Loading
Loading
@@ -317,6 +318,10 @@ void StringToScreenChars(NSString *s,
// Accessor.
- (DVR*)dvr;
 
// If this returns true then the textview will broadcast iTermTabContentsChanged
// when a dirty char is found.
- (BOOL)shouldSendContentsChangedNotification;
// Load a frame from a dvr decoder.
- (void)setFromFrame:(screen_char_t*)s len:(int)len info:(DVRFrameInfo)info;
 
Loading
Loading
Loading
Loading
@@ -50,13 +50,35 @@
}
@end
 
#define FindOptCaseInsensitive (1 << 0)
#define FindOptBackwards (1 << 1)
#define FindOptRegex (1 << 2)
#define FindMultipleResults (1 << 3)
typedef struct FindContext {
// Current absolute block number being searched.
int absBlockNum;
// The substring to search for.
NSString* substring;
// A bitwise OR of the options defined above.
int options;
// 1: search forward. -1: search backward.
int dir;
// The offset within a block to begin searching. -1 means the end of the
// block.
int offset;
// The offset within a block at which to stop searching. No results
// with an offset at or beyond this position will be returned.
int stopAt;
// Searching: a search is in progress and this context can be used to search.
// Matched: At least one result has been found. This context can be used to
// search again.
// NotFound: No results were found and the end of the buffer was reached.
enum { Searching, Matched, NotFound } status;
int matchLength;
NSMutableArray* results; // used for multiple results
Loading
Loading
@@ -245,10 +267,6 @@ typedef struct FindContext {
// Search for a substring. If found, return the position of the hit. Otherwise return -1. Use 0 for the start to indicate the beginning of the buffer or
// pass the result of a previous findSubstring result. The number of positions the result occupies will be set in *length (which would be different than the
// length of the substring in the presence of double-width characters.
#define FindOptCaseInsensitive (1 << 0)
#define FindOptBackwards (1 << 1)
#define FindOptRegex (1 << 2)
#define FindMultipleResults (1 << 3)
- (void)initFind:(NSString*)substring startingAt:(int)start options:(int)options withContext:(FindContext*)context;
- (void)releaseFind:(FindContext*)context;
- (void)findSubstring:(FindContext*)context stopAt:(int)stopAt;
Loading
Loading
@@ -270,4 +288,7 @@ typedef struct FindContext {
// Returns the position at the end of the buffer
- (int) lastPos;
 
// Set the position of the find context to the end of the buffer.
- (void)setFindContextPositionToEnd:(FindContext *)context;
@end
Loading
Loading
@@ -1555,5 +1555,21 @@ static int RawNumLines(LineBuffer* buffer, int width) {
return position;
}
 
- (void)setFindContextPositionToEnd:(FindContext *)context
{
if (![blocks count]) {
context->absBlockNum = 0;
context->offset = 0;
return;
}
context->absBlockNum = num_dropped_blocks + [blocks count] - 1;
if ([blocks count] > num_dropped_blocks) {
LineBlock* block = [blocks lastObject];
context->offset = [block rawSpaceUsed] - 1;
} else {
context->offset = 0;
}
}
 
@end
Loading
Loading
@@ -116,12 +116,17 @@ static NSString* SESSION_ARRANGEMENT_WORKING_DIRECTORY = @"Working Directory";
selector:@selector(coprocessChanged)
name:@"kCoprocessStatusChangeNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(sessionContentsChanged:)
name:@"iTermTabContentsChanged"
object:nil];
 
return self;
}
 
- (void)dealloc
{
[self stopTailFind]; // This frees the substring in the tail find context, if needed.
[triggerLine_ release];
[triggers_ release];
[pasteboard_ release];
Loading
Loading
@@ -2787,6 +2792,10 @@ static long long timeInTenthsOfSeconds(struct timeval t)
[updateTimer release];
updateTimer = nil;
}
if (tailFindTimer_ && [[[view findViewController] view] isHidden]) {
[self stopTailFind];
}
timerRunning_ = NO;
}
 
Loading
Loading
@@ -3164,6 +3173,16 @@ static long long timeInTenthsOfSeconds(struct timeval t)
}
}
 
- (BOOL)wantsContentChangedNotification
{
// We want a content change notification if it's worth doing a tail find.
// That means the find window is open, we're not already doing a tail find,
// and a search was performed in the find window (vs select+cmd-e+cmd-f).
return !tailFindTimer_ &&
![[[view findViewController] view] isHidden] &&
[TEXTVIEW initialFindContext]->substring != nil;
}
@end
 
@implementation PTYSession (ScriptingSupport)
Loading
Loading
@@ -3373,4 +3392,70 @@ static long long timeInTenthsOfSeconds(struct timeval t)
[[[self tab] realParentWindow] setWindowTitle];
}
 
- (void)continueTailFind
{
NSMutableArray *results = [NSMutableArray array];
BOOL more;
more = [SCREEN continueFindAllResults:results
inContext:&tailFindContext_];
for (SearchResult *r in results) {
[TEXTVIEW addResultFromX:r->startX
absY:r->absStartY
toX:r->endX
toAbsY:r->absEndY];
}
if ([results count]) {
[TEXTVIEW setNeedsDisplay:YES];
}
if (more) {
tailFindTimer_ = [NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:@selector(continueTailFind)
userInfo:nil
repeats:NO];
} else {
tailFindTimer_ = nil;
}
}
- (void)beginTailFind
{
FindContext *initialFindContext = [TEXTVIEW initialFindContext];
if (!initialFindContext->substring) {
return;
}
[SCREEN initFindString:initialFindContext->substring
forwardDirection:YES
ignoringCase:!!(initialFindContext->options & FindOptCaseInsensitive)
regex:!!(initialFindContext->options & FindOptRegex)
startingAtX:0
startingAtY:0
withOffset:0
inContext:&tailFindContext_
multipleResults:YES];
// Set the starting position to the block & offset that the backward search
// began at. Do a forward search from that location.
tailFindContext_.absBlockNum = initialFindContext->absBlockNum;
tailFindContext_.offset = initialFindContext->offset;
[self continueTailFind];
}
- (void)sessionContentsChanged:(NSNotification *)notification
{
if (!tailFindTimer_) {
[self beginTailFind];
}
}
- (void)stopTailFind
{
if (tailFindTimer_) {
[SCREEN cancelFindInContext:&tailFindContext_];
[tailFindTimer_ invalidate];
tailFindTimer_ = nil;
}
}
@end
Loading
Loading
@@ -407,6 +407,7 @@ static CGFloat PerceivedBrightness(CGFloat r, CGFloat g, CGFloat b) {
 
[workingDirectoryAtLines release];
[trouter release];
[initialFindContext_.substring release];
 
[super dealloc];
}
Loading
Loading
@@ -4116,7 +4117,7 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
}
 
// Add a match to resultMap_
- (void)_addResultFromX:(int)resStartX absY:(long long)absStartY toX:(int)resEndX toAbsY:(long long)absEndY
- (void)addResultFromX:(int)resStartX absY:(long long)absStartY toX:(int)resEndX toAbsY:(long long)absEndY
{
int width = [dataSource width];
for (long long y = absStartY; y <= absEndY; y++) {
Loading
Loading
@@ -4243,6 +4244,11 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
return found;
}
 
- (FindContext *)initialFindContext
{
return &initialFindContext_;
}
// continueFind is called by a timer in the client until it returns NO. It does
// two things:
// 1. If _findInProgress is true, search for more results in the dataSource and
Loading
Loading
@@ -4266,7 +4272,7 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
// Add new results to map.
for (int i = nextOffset_; i < [findResults_ count]; i++) {
SearchResult* r = [findResults_ objectAtIndex:i];
[self _addResultFromX:r->startX absY:r->absStartY toX:r->endX toAbsY:r->absEndY];
[self addResultFromX:r->startX absY:r->absStartY toX:r->endX toAbsY:r->absEndY];
redraw = YES;
}
nextOffset_ = [findResults_ count];
Loading
Loading
@@ -4330,6 +4336,12 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
withOffset:0
inContext:[dataSource findContext]
multipleResults:YES];
[initialFindContext_.substring release];
initialFindContext_ = *[dataSource findContext];
initialFindContext_.results = nil;
initialFindContext_.substring = [initialFindContext_.substring copy];
_findInProgress = YES;
 
// Reset every bit of state.
Loading
Loading
@@ -7411,7 +7423,7 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
}
 
 
if (foundDirty && [[iTermExpose sharedInstance] isVisible]) {
if (foundDirty && [dataSource shouldSendContentsChangedNotification]) {
changedSinceLastExpose_ = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:@"iTermTabContentsChanged"
object:nil
Loading
Loading
Loading
Loading
@@ -52,6 +52,7 @@
#import "DVRBuffer.h"
#import "PTYTab.h"
#import "ITAddressBookMgr.h"
#import "iTermExpose.h"
 
#define MAX_SCROLLBACK_LINES 1000000
#define DIRTY_MAGIC 0x76 // Used to ensure we don't go off end of dirty array
Loading
Loading
@@ -3477,6 +3478,11 @@ void DumpBuf(screen_char_t* p, int n) {
maxTime:0.1];
}
 
- (void)setFindContextPositionToEnd:(FindContext *)context
{
[linebuffer setFindContextPositionToEnd:context];
}
- (void)saveToDvr
{
if (!dvr || ![[PreferencePanel sharedInstance] instantReplay]) {
Loading
Loading
@@ -3577,6 +3583,11 @@ void DumpBuf(screen_char_t* p, int n) {
return dvr;
}
 
- (BOOL)shouldSendContentsChangedNotification
{
return [[iTermExpose sharedInstance] isVisible] ||
[SESSION wantsContentChangedNotification];
}
 
@end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment