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

Debounce with search() #92

Closed
noplanman opened this issue Sep 29, 2023 · 3 comments
Closed

Debounce with search() #92

noplanman opened this issue Sep 29, 2023 · 3 comments
Assignees

Comments

@noplanman
Copy link

I'm using search() to request data from an external API and it would be really cool to have some kind of debounce to not make a request on every keystroke.

Is there some smart way of doing this?

@jessarcher
Copy link
Member

Hey @noplanman,

This is a bit tricky due to the synchronous nature of this prompt. We could make it async, but that would reduce the environments that it can run in. We could make a hybrid (like the spinner), but that's a lot of extra work and more things that can break.

However, due to the synchronous nature of this prompt, it won't make two requests simultaneously. If you continue typing while a search is running, the keystrokes are buffered and received in one go once the first search is complete when it will then search again for the new current query, without having queued up multiple searches for each keystroke that occurred in between.

You also have the option of not performing the search until the search value meets a required length.

I'm open to other ideas, but at the core of it would be the need to delay a search until a certain amount of time has passed so it could be assumed the typing has "finished". Anything like that in standard PHP would be a blocking operation that would prevent re-rendering.

@noplanman
Copy link
Author

Thanks @jessarcher, I understand. Yes, I've noticed the input buffering when typing quickly (but typos and requiring to correct it make it even worse 😅)

I was also wondering if there was some way of "misusing" the validation to do the data requesting, after "selecting" my initial search, but couldn't get it to work.

Alternatively, is there a way to clear a previous promt from the terminal screen? That way, I could use a normal text() input, use the response in a suggest() field and just hide the initial text input.

Or maybe I'm overcooking this and just leave it as is. I cache every single request, which works well enough I guess.

I'll close off here, and if anybody feels inspired to explore this again when PHP is natively asynchronous, they can do that. 😉

@jessarcher
Copy link
Member

Alternatively, is there a way to clear a previous promt from the terminal screen? That way, I could use a normal text() input, use the response in a suggest() field and just hide the initial text input.

There's nothing built-in to Prompts to do this, but it should be pretty straightforward to do in your app, especially with the text input, as it is a consistent height. You'd need to familiarise yourself with ANSI escape sequences, specifically the ones for moving the cursor and erasing.

This worked for me:

$search = text('Search');

echo "\e[4A"; // Move the cursor up 4 lines.
echo "\e[J"; // Clear from the cursor to the end of the screen.

$selection = select('Select', ['your', 'results', 'here']);

This does depend on the Prompts theme not changing the number of lines used to render a text prompt, but I can't see that changing any time soon.

Also, directly echoing could be problematic if your command isn't always run in interactive mode so you may need to make it conditional.

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

3 participants