Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make choose non-blocking #18

Open
andrewferrier opened this issue Jun 1, 2020 · 3 comments
Open

Make choose non-blocking #18

andrewferrier opened this issue Jun 1, 2020 · 3 comments

Comments

@andrewferrier
Copy link

choose is a great app! However, unlike (for example) fzf, it is blocking. What this means is that if you pipe to choose, it will not open until stdin closes. If, for example, you run ls -R ~ | choose - which for many people is a long operation - no results are shown until ls is complete. It would be great if choose could dynamically update like fzf does.

Thanks for your work on this great program.

@chipsenkbeil
Copy link
Owner

@andrewferrier did you have thoughts on how the program would behave when a user interacts and begins filtering while new input is being received? Do you expect it like running fzf where new input not matching the filter is discarded?

Would you be willing to contribute an enhancement to achieve what you're thinking? I'm more than happy to accept contributions. :)

@andrewferrier
Copy link
Author

@chipsenkbeil yes, basically that was my thinking; the results are dynamically updated as new input becomes available (which is, I think, how fzf works).

I'm sure that's not trivial to implement ;) I'll take a look at an enhancement if I get time, although my MacOS native dev experience is limited, I have to admit, so others who could contribute this would be great :)

@chipsenkbeil
Copy link
Owner

chipsenkbeil commented Jul 16, 2020

This might be easier than I thought to implement, gated with some flag to indicate async input.

We already have a method to read data from stdin (getInputItems), although I'm not sure if we'd need to cache the current items or if stdin on Mac will retain the existing input. Given we're advancing our pointer to the end of stdin, I'm going to assume that we'd need to combine our current list with new items.

Presently, we only assign the list of choices once upon the app finishing launching: https://github.com/chipsenkbeil/choose/blob/master/SDAppDelegate.m#L204

What we'd want to do for async instead is to either poll or enact some interrupt to know when new content is available on stdin. If we build in some event loop logic that checks stdin on some regular schedule (configure via CLI option?), we could trigger a rerun of the query with the new choices whenever there's a change. Concurrent programming doc

Potentially use the readabilityHandler to data that arrives on stdin's file handle to trigger a query update.

stdinHandle.readabilityHandler = ^( NSFileHandle *handle ) {
     NSData* data = [handle availableData];
    if ([data length] == 0) {
        // End of stream reached, so should expect no more data
        return;
    }

    NSString* newInputStrings = [[[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];

    if ([inputStrings length] == 0)
        return;

    // Assign these to an existing array by appending to end
     [inputStrings componentsSeparatedByString:@"\n"];
}

If re-assigning the choices parameter, probably need to reference self, which involves using a weak reference: https://bytes.vokal.io/objc-block-capture-weakself/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants