{"id":18310973,"url":"https://github.com/jimschubert/answer","last_synced_at":"2025-04-09T12:10:54.339Z","repository":{"id":209342521,"uuid":"723789495","full_name":"jimschubert/answer","owner":"jimschubert","description":"Have your user answer some questions in terminal.","archived":false,"fork":false,"pushed_at":"2023-12-30T23:16:47.000Z","size":543,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-15T05:46:48.467Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/jimschubert/answer","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jimschubert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"jimschubert","patreon":"jimschubert"}},"created_at":"2023-11-26T19:07:48.000Z","updated_at":"2024-08-26T21:18:41.000Z","dependencies_parsed_at":"2023-12-10T17:27:58.959Z","dependency_job_id":"9aa121c8-b935-440e-8750-61e2aecdf078","html_url":"https://github.com/jimschubert/answer","commit_stats":null,"previous_names":["jimschubert/answer"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimschubert%2Fanswer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimschubert%2Fanswer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimschubert%2Fanswer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jimschubert%2Fanswer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jimschubert","download_url":"https://codeload.github.com/jimschubert/answer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248036066,"owners_count":21037092,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-05T16:16:04.477Z","updated_at":"2025-04-09T12:10:54.309Z","avatar_url":"https://github.com/jimschubert.png","language":"Go","funding_links":["https://github.com/sponsors/jimschubert","https://patreon.com/jimschubert"],"categories":[],"sub_categories":[],"readme":"# answer\n\nHave your user answer some questions in terminal.\n\nThis project intends to provide functionality similar to [github.com/AlecAivazis/survey](https://github.com/AlecAivazis/survey), but built on top of [bubbletea](https://github.com/charmbracelet/bubbletea).\n\n![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/jimschubert/answer?color=blue\u0026sort=semver)\n![Go Version](https://img.shields.io/github/go-mod/go-version/jimschubert/answer)\n[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue)](./LICENSE)  \n[![build](https://github.com/jimschubert/answer/actions/workflows/build.yml/badge.svg)](https://github.com/jimschubert/answer/actions/workflows/build.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/jimschubert/answer)](https://goreportcard.com/report/github.com/jimschubert/answer)\n\n## Bubbles\n\nThis library provides the following bubbles:\n\n* `input`: single-line textual input with validations\n* `selection`: multi-selection with optional single-select\n* `confirm`: a yes/no/undecided with multiple visual representations (input, horizontal/vertical selection)\n\n### input\n\nThe `input` bubble provides a minimal wrapper around `github.com/charmbracelet/bubbles/textinput`. You get all the implementation\nof the upstream textinput bubble, with a little extra \"flair\" (a prompt prefix character, validations, suggestions). This allows for styling and functionality\nmore closely to what you might have had with [github.com/AlecAivazis/survey](https://github.com/AlecAivazis/survey).\n\nSee [internal/examples/input](internal/examples/input):\n\n![](internal/examples/input/input.gif)\n\n#### Validations\n\nSimple validation functions are supported:\n\n```go\nm := input.New()\nm.Prompt = \"Please enter your name:\"\nm.Placeholder = \"(first name only)\"\nm.Validate = func(v string) error {\n    if v != \"\" \u0026\u0026 !unicode.IsUpper(rune(v[0])) {\n        return errors.New(\"name must be uppercase\")\n    }\n    return nil\n}\np := tea.NewProgram(\u0026m)\n```\n\nComplex validations defined in the `validate` package are also supported. These functions chain together via `validate.Func`, and provide\na common variadic argument for custom error messages (similar to testify's assert functions).\n\nValidation functions available include:\n\n* **MinLength**: defines the minimum rune count\n* **MaxLength**: defines the maximum rune count\n* **Matches**: defines a regex pattern to match\n* **Contains**: a wrapper around strings.Contains\n* **And**: pass a custom function to the validation chain, in which the chain and function are all evaluated (like `\u0026\u0026`)\n* **Or**: pass a custom function to the validation chain, in which the custom function is only evaluated if the preceding validation passes (like `||`)\n\nFor example:\n\n```go\nm := input.New()\nm.Prompt = \"Please enter your name:\"\nm.Placeholder = \"(first name only)\"\nm.Validate = validate.NewValidation().\n    MinLength(2, \"min: 2 characters\").\n    MaxLength(5, \"max: 8 characters\").\n    And(func(input string) error {\n        for _, r := range input {\n            if !unicode.IsLetter(r) {\n                return errors.New(\"letters only\")\n            }\n        }\n        return nil\n    }).\n    And(requireUppercase).\n    Build()\np := tea.NewProgram(\u0026m)\n```\n\n![](internal/examples/input/input-complex.gif)\n\n#### Suggestions\n\nSuggestions can be applied via a set of static data using one of the provided text suggestion functions, or via a custom function allowing retrieval from any location such as an external datasource.\n\nProvided suggestions include `suggest.LevenshteinDistance` and `suggest.StartsWith`, each with customizable options to optimize their behaviors.\n\nTo use `suggest.LevenshteinDistance` you can apply in the follow manner:\n\n```go\n\tm := input.New()\n\tm.Prompt = \"Please enter your name:\"\n\tm.Placeholder = \"(first name only)\"\n\tm.Suggest = suggest.LevenshteinDistance([]string{\"Jim\", \"James\", \"Jameson\"},\n\t\tsuggest.LevenshteinDistanceMin(0),\n\t\tsuggest.LevenshteinDistanceMax(4))\n```\n\nTo use a custom function, match the signature `func(value string) []string`. For example:\n\n```go\n\tm := input.New()\n\tm.Prompt = \"Please enter your name:\"\n\tm.Placeholder = \"(first name only)\"\n\tm.Suggest = func(value string) []string {\n\t\treturn []string{\"A\",\"B\",\"C\",\"D\"}\n\t}\n```\n\n### selection\n\nThe `selection` bubble provides a paginated list of items from which the user can select 0 or more items. This bubble defaults\nto multi-select, but can be made single-select by setting `MaxSelections` to 1. Styles, as well as indicators for prompt,\nchooser, and selection are customizable.\n\nSee [internal/examples/selection](internal/examples/selection):\n\n![](internal/examples/selection/selection.gif)\n\n### confirm\n\nThe `confirm` bubble provides a yes/no/undecided type of input. This is configurable to show the common terminal usability such as:\n\n\u003e ? Do you want to continue? y/N\n\nWhere the default value is indicated by an uppercase character. In this default rendering display, the user is able to \ntype either `y` or `n` (case insensitive) or hit enter to proceed with the default.\n\nThe confirm bubble also supports horizontal and vertical list-style selections.\n\nHorizontal selection could be presented like:\n\n\u003e ? Prompt? ➤Yes  No\n\nVertical selection could be presented like:\n\n\u003e ? Prompt?  \n\u003e ➤ Yes  \n\u003e \u0026nbsp; \u0026nbsp; No\n\nSee [internal/examples/confirm](internal/examples/confirm):\n\n![](internal/examples/confirm/confirm.gif)\n\n## Install\n\n```\ngo get -u github.com/jimschubert/answer\n```\n\n## Build/Test\n\n```shell\ngo test -v -race -cover ./...\n```\n\n## License\n\nThis project is [licensed](./LICENSE) under Apache 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjimschubert%2Fanswer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjimschubert%2Fanswer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjimschubert%2Fanswer/lists"}