3
votes

I have an NSTextView that I'm outputting text from NSTask. Everything works as expected except the scrolling and selecting behaviors.

1: If I try to scroll up, the position of my scroll snaps back to the bottom instantly after I let go. Any ideas? I've looked through quite a bit of documentation about this and can't find anything about it.

2: If I select text, it removes it. I just want it to select so I can copy and paste. Lost on this one too.

Any tips or pointers would be most welcome. Thanks.

- (id)init
{
    [super init];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(readPipe:)
                                                 name:NSFileHandleReadCompletionNotification 
                                               object:nil];

    return self;
}

- (void)kicked
{
    task = [[NSTask alloc] init];

    [task setLaunchPath:[self.kickLocationTextField stringValue]];
    [task setArguments:kickBuild];

    NSPipe *pipe = [[NSPipe alloc] init];
    fileHandle = [pipe fileHandleForReading];
    [fileHandle readInBackgroundAndNotify];

    [task setStandardOutput:pipe];
    [task setStandardError:pipe];

    [task launch];

    [task release];
    [pipe release];
}


- (void)readPipe:(NSNotification *)notification
{
    NSData *data;
    NSString *text;

    if( [notification object] != fileHandle )
    {
        return;
    }

    data = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
    text = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

    [nsTaskOutput insertText:text];

    [text release];
    if (data != 0)
    {
        [fileHandle readInBackgroundAndNotify];
    }
}
1
Are you replacing the entire text in the text view whenever you get output from the task? Please edit the question and post the code you use to grab output from the task and add it to the text view. - user557219
Updated. According to the docs for NSTextView... if nothing is selected in the view it will append the next incoming string. If there IS selected text... it will replace it. Everything works as expected, with the exception of those previous two questions. - crewshin

1 Answers

3
votes

Try this instead of insertText::

NSScroller *scroller = nTaskOutput.enclosingScrollView.verticalScroller;
BOOL shouldScrollToBottom = scroller.doubleValue == 1.0;
NSTextStorage *ts = nTaskOutput.textStorage;
[ts replaceCharactersInRange:NSMakeRange(ts.length, 0) withString:text];
if (shouldScrollToBottom) {
    NSRect bounds = nTaskOutput.bounds;
    [nTaskOutput scrollPoint:NSMakePoint(NSMaxX(bounds), NSMaxY(bounds))];
}