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

cmdutil.ReadConsole[NoEcho]: Use bubbletea #13815

Merged
merged 2 commits into from Aug 30, 2023
Merged

Conversation

abhinav
Copy link
Contributor

@abhinav abhinav commented Aug 29, 2023

Switch the cmdutil.ReadConsole and cmdutil.ReadConsoleNoEcho functions
to use the bubbletea library to render the prompt,
using the textinput widget provided by the accompanying bubbles library.
The resulting input widgets support arrow keys, back space,
and some basic readline-style bindings including Ctrl-A, Alt-B, etc.

I went through all uses of ReadConsole or ReadConsoleNoEcho.
Only the one in new.go had a non-compliant prompt that I had to adjust.

Note: One divergence in behavior I opted for was that
password prompts will echo '*' characters as the user is typing
and then no echo once they've accepted or canceled the value.
Previously, the prompt did not echo anything in either case.

Introduction if you're unfamiliar with bubbletea

bubbletea operates by modeling the widget state as
an immutable data structure that receives messages for events.
On receiving a message (key press, e.g.) the model's Update method
returns a new model instance representing its new state.
Update may also optionally return additional commands for the program,
e.g. stop running, or print something and move on.
The model's View method returns what should be drawn in the terminal
based on the model's current state.
This programming model makes it reasonably straightforward to unit test
some of the core functionality of independent widgets
as demonstrated in this PR.

Resolves #1565


Demos:

Plain text

prompt-plain

Secret

prompt-secret

Secret prompt with padding

prompt-secret-2

@pulumi-bot
Copy link
Contributor

pulumi-bot commented Aug 29, 2023

Changelog

[uncommitted] (2023-08-30)

Miscellaneous

  • [cli] Some CLI prompts now support backspace, arrow keys, etc.
    #13815

Switch the cmdutil.ReadConsole and cmdutil.ReadConsoleNoEcho functions
to use the bubbletea library to render the prompt,
using the textinput widget provided by the accompanying bubbles library.

The resulting input widgets support arrow keys, back space,
and some basic readline-style bindings including Ctrl-A, Alt-B, etc.

I went through all uses of ReadConsole or ReadConsoleNoEcho.
Only the one in new.go had a non-compliant prompt that I had to adjust.

Quick introduction if you're unfamiliar with bubbletea:
bubbletea operates by modeling the widget state as
an immutable data structure that receives messages for events.
On receiving a message (key press, e.g.) the model's Update method
returns a new model instance representing its new state.
Update may also optionally return additional commands for the program,
e.g. stop running, or print something and move on.
The model's View method returns what should be drawn in the terminal
based on the model's current state.
This programming model makes it reasonably straightforward to unit test
some of the core functionality of independent widgets
as demonstrated in this PR.

Resolves #1565
@abhinav abhinav requested a review from a team August 29, 2023 20:00
@abhinav
Copy link
Contributor Author

abhinav commented Aug 29, 2023

I should point out that if we accept this change, this would be a commitment to migrating away from survey long-term in favor of bubbletea.

Copy link
Member

@Frassle Frassle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor comment otherwise looks sane. Happy to have bubbletea as a dep, probably a lot of other fancy UI work we can do with it.

sdk/go/common/util/cmdutil/console.go Outdated Show resolved Hide resolved
abhinav added a commit that referenced this pull request Aug 29, 2023
Switches the survey-based list picker we use to pick a template
to use bubbletea with the bubbles/list widget.
Instead of using any of the default bubbles/list renderings,
this implements a custom renderer for list items (the delegate)
that provides an experience closer in look to the 'pulumi new' today.

NOTE: This is just a PoC and not intended to be landed as is.
It hasn't been tested at all--minus some manual testing.
If y'all like this, in the future, some of the underlying components
can be generalized and re-used to replace other uses of survey.Select.

Related to #13815 in spirit.

A mergeable version of this would resolve #11812.
Mention that '205' refers to the color of the cursor.
@abhinav abhinav added this pull request to the merge queue Aug 30, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Aug 30, 2023
@abhinav abhinav added this pull request to the merge queue Aug 30, 2023
Merged via the queue into master with commit b51caa6 Aug 30, 2023
46 checks passed
@abhinav abhinav deleted the abhinav/bubbletea-prompt branch August 30, 2023 17:45
abhinav added a commit that referenced this pull request Aug 30, 2023
Switches the survey-based list picker we use to pick a template
to use bubbletea with the bubbles/list widget.
Instead of using any of the default bubbles/list renderings,
this implements a custom renderer for list items (the delegate)
that provides an experience closer in look to the 'pulumi new' today.

NOTE: This is just a PoC and not intended to be landed as is.
It hasn't been tested at all--minus some manual testing.
If y'all like this, in the future, some of the underlying components
can be generalized and re-used to replace other uses of survey.Select.

Related to #13815 in spirit.

A mergeable version of this would resolve #11812.
abhinav added a commit that referenced this pull request Aug 30, 2023
Switches the survey-based list picker we use to pick a template
to use bubbletea with the bubbles/list widget.
Instead of using any of the default bubbles/list renderings,
this implements a custom renderer for list items (the delegate)
that provides an experience closer in look to the 'pulumi new' today.

NOTE: This is just a PoC and not intended to be landed as is.
It hasn't been tested at all--minus some manual testing.
If y'all like this, in the future, some of the underlying components
can be generalized and re-used to replace other uses of survey.Select.

Related to #13815 in spirit.

A mergeable version of this would resolve #11812.
abhinav added a commit that referenced this pull request Sep 1, 2023
Switches the survey-based list picker we use to pick a template
to use bubbletea with the bubbles/list widget.
Instead of using any of the default bubbles/list renderings,
this implements a custom renderer for list items (the delegate)
that provides an experience closer in look to the 'pulumi new' today.

NOTE: This is just a PoC and not intended to be landed as is.
It hasn't been tested at all--minus some manual testing.
If y'all like this, in the future, some of the underlying components
can be generalized and re-used to replace other uses of survey.Select.

Related to #13815 in spirit.

A mergeable version of this would resolve #11812.
dixler pushed a commit that referenced this pull request Sep 14, 2023
Switches the survey-based list picker we use to pick a template
to use bubbletea with the bubbles/list widget.
Instead of using any of the default bubbles/list renderings,
this implements a custom renderer for list items (the delegate)
that provides an experience closer in look to the 'pulumi new' today.

NOTE: This is just a PoC and not intended to be landed as is.
It hasn't been tested at all--minus some manual testing.
If y'all like this, in the future, some of the underlying components
can be generalized and re-used to replace other uses of survey.Select.

Related to #13815 in spirit.

A mergeable version of this would resolve #11812.
github-merge-queue bot pushed a commit that referenced this pull request Sep 14, 2023
Switches the survey-based list picker we use to pick a template
to use bubbletea with the bubbles/list widget.
Instead of using any of the default bubbles/list renderings,
this implements a custom renderer for list items (the delegate)
that provides an experience closer in look to the 'pulumi new' today.

Related to #13815 in spirit.

Fixes #11812
Fixes #8169

---

Demos

<details>
<summary>Basic usage</summary>


[![asciicast](https://asciinema.org/a/NeecyanZP2iyzlrAOKRiKckJZ.svg)](https://asciinema.org/a/NeecyanZP2iyzlrAOKRiKckJZ)

</details>

<details>
<summary>Handling of really small terminals</summary>


[![asciicast](https://asciinema.org/a/RZW3NfX5SQ8rL4mR1iRLQ6yi1.svg)](https://asciinema.org/a/RZW3NfX5SQ8rL4mR1iRLQ6yi1)

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

Successfully merging this pull request may close these issues.

ReadLine type functions insert escape codes for common terminal types
3 participants