feat(form): implement WithInput#271
Conversation
|
That was quick, thanks! |
I couldn't understand what Though I am curious on how will this work. |
That was indeed quite vague. In my unit-test I created an 'answering machine' that sends strings to the 'StdIn' based on lines read from 'StdOut'. It works a little bit like this: questionsAndAnswers := map[string]string{
"How are you doing?": "I'm fine thanks!",
"Are you sure you want to do this?": "\033[C", // Right arrow key to move around in the prompt
}
// Stdout replacement
outputReader, outputWriter := io.Pipe()
defer outputReader.Close()
defer outputWriter.Close()
// Stdin replacement
inputReader, inputWriter := io.Pipe()
defer inputReader.Close()
defer inputWriter.Close()
go func() {
reader := bufio.NewScanner(outputReader)
for reader.Scan() {
line := reader.Text()
// Loop through questions and answers
// [...]
if answerFound {
inputWriter.Write([]byte(answer) + "\n\r")
}
}
}()
form := huh.NewForm().
WithOutput(outputWriter).
WithInput(inputReader).
Run()Not sure if you're looking for something like this in your documentation, but I enjoy sharing it :) |
….mod (#60) [](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [github.com/charmbracelet/huh](https://togithub.com/charmbracelet/huh) | `v0.4.2` -> `v0.5.1` | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>charmbracelet/huh (github.com/charmbracelet/huh)</summary> ### [`v0.5.1`](https://togithub.com/charmbracelet/huh/compare/v0.5.0...v0.5.1) [Compare Source](https://togithub.com/charmbracelet/huh/compare/v0.5.0...v0.5.1) ### [`v0.5.0`](https://togithub.com/charmbracelet/huh/releases/tag/v0.5.0) [Compare Source](https://togithub.com/charmbracelet/huh/compare/v0.4.2...v0.5.0) ### Dynamic Forms 🪄 <img width="600" src="https://vhs.charm.sh/vhs-6FRmBjNi2aiRb4INPXwIjo.gif" alt="Country / State form with dynamic inputs running."> `huh?` forms can now react to changes in other parts of the form. Replace properties such as `Options`, `Title`, `Description` with their dynamic counterparts: `OptionsFunc`, `TitleFunc`, and `DescriptionFunc` to recompute properties values on changes when watched variables change. Let’s build a simple state / province picker. ```go var country string var state string ``` The `country` select will be static, we’ll use this value to recompute the options and title for the next input. ```go huh.NewSelect[string](). Options(huh.NewOptions("United States", "Canada", "Mexico")...). Value(&country). Title("Country"). ``` Define your `Select` with `TitleFunc` and `OptionsFunc` and bind them to the `&country` value from the previous field. Whenever the user chooses a different country, the `TitleFunc` and `OptionsFunc` will be recomputed. > \[!IMPORTANT] > We have to pass `&country` as the binding to recompute the function only when > `country` changes, otherwise we will hit the API too often. ```go huh.NewSelect[string](). Value(&state). Height(8). TitleFunc(func() string { switch country { case "United States": return "State" case "Canada": return "Province" default: return "Territory" } }, &country). OptionsFunc(func() []huh.Option[string] { opts := fetchStatesForCountry(country) return huh.NewOptions(opts...) }, &country), ``` Lastly, run the `form` with these inputs. ```go err := form.Run() if err != nil { log.Fatal(err) } ``` ##### Other Changes #### What's Changed - Form Layouts by [@​adamdottv](https://togithub.com/adamdottv) in [https://github.com/charmbracelet/huh/pull/274](https://togithub.com/charmbracelet/huh/pull/274) - Resolve conflict between select and filter by [@​MikaelFangel](https://togithub.com/MikaelFangel) in [https://github.com/charmbracelet/huh/pull/252](https://togithub.com/charmbracelet/huh/pull/252) - Add `CursorText` style by [@​nervo](https://togithub.com/nervo) in [https://github.com/charmbracelet/huh/pull/259](https://togithub.com/charmbracelet/huh/pull/259) - Adjust input width to char limit by [@​nervo](https://togithub.com/nervo) in [https://github.com/charmbracelet/huh/pull/260](https://togithub.com/charmbracelet/huh/pull/260) - Implement `WithInput` by [@​Delta456](https://togithub.com/Delta456) in [https://github.com/charmbracelet/huh/pull/271](https://togithub.com/charmbracelet/huh/pull/271) - Implement WithTimeout by [@​Delta456](https://togithub.com/Delta456) in [https://github.com/charmbracelet/huh/pull/276](https://togithub.com/charmbracelet/huh/pull/276) - Set filtering state of select by [@​PJGaetan](https://togithub.com/PJGaetan) in [https://github.com/charmbracelet/huh/pull/179](https://togithub.com/charmbracelet/huh/pull/179) - `Filtering` on `Select` and `MultiSelect` fields by [@​maaslalani](https://togithub.com/maaslalani) in [https://github.com/charmbracelet/huh/pull/283](https://togithub.com/charmbracelet/huh/pull/283) - Introduce `accessor` by [@​nervo](https://togithub.com/nervo) in [https://github.com/charmbracelet/huh/pull/263](https://togithub.com/charmbracelet/huh/pull/263) - fix: aborting a form returning a timeout error by [@​Sculas](https://togithub.com/Sculas) in [https://github.com/charmbracelet/huh/pull/287](https://togithub.com/charmbracelet/huh/pull/287) #### New Contributors - [@​MikaelFangel](https://togithub.com/MikaelFangel) made their first contribution in [https://github.com/charmbracelet/huh/pull/252](https://togithub.com/charmbracelet/huh/pull/252) - [@​nervo](https://togithub.com/nervo) made their first contribution in [https://github.com/charmbracelet/huh/pull/253](https://togithub.com/charmbracelet/huh/pull/253) - [@​shedyfreak](https://togithub.com/shedyfreak) made their first contribution in [https://github.com/charmbracelet/huh/pull/230](https://togithub.com/charmbracelet/huh/pull/230) - [@​Delta456](https://togithub.com/Delta456) made their first contribution in [https://github.com/charmbracelet/huh/pull/271](https://togithub.com/charmbracelet/huh/pull/271) - [@​abradley2](https://togithub.com/abradley2) made their first contribution in [https://github.com/charmbracelet/huh/pull/280](https://togithub.com/charmbracelet/huh/pull/280) - [@​PJGaetan](https://togithub.com/PJGaetan) made their first contribution in [https://github.com/charmbracelet/huh/pull/179](https://togithub.com/charmbracelet/huh/pull/179) - [@​Sculas](https://togithub.com/Sculas) made their first contribution in [https://github.com/charmbracelet/huh/pull/287](https://togithub.com/charmbracelet/huh/pull/287) **Full Changelog**: charmbracelet/huh@v0.4.2...v0.5.0 *** <a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a> Thoughts? Questions? We love hearing from you. Feel free to reach out on [Twitter](https://twitter.com/charmcli), [The Fediverse](https://mastodon.technology/@​charm), or [Slack](https://charm.sh/slack). </details> --- ### Configuration 📅 **Schedule**: Branch creation - "* */8 * * *" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/jippi/dottie). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MjUuMSIsInVwZGF0ZWRJblZlciI6IjM3LjQyNS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Implements
WithInput(r io.Reader)which callstea.WithIntput(r)and also avoids usingbubbleteadirectlyCloses #270