{"id":13410729,"url":"https://github.com/dixonwille/wmenu","last_synced_at":"2025-05-16T02:05:15.896Z","repository":{"id":57490271,"uuid":"56687748","full_name":"dixonwille/wmenu","owner":"dixonwille","description":"An easy to use menu structure for cli applications that prompts users to make choices.","archived":false,"fork":false,"pushed_at":"2024-11-25T23:48:27.000Z","size":102,"stargazers_count":223,"open_issues_count":3,"forks_count":24,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-08T12:08:37.583Z","etag":null,"topics":["awesome-go","cli","golang","golang-package","menu"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dixonwille.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,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"dixonwille"}},"created_at":"2016-04-20T13:09:44.000Z","updated_at":"2025-03-24T20:47:55.000Z","dependencies_parsed_at":"2023-12-12T06:23:46.089Z","dependency_job_id":"a6a5e437-5257-4912-9ede-22b5f76a7be2","html_url":"https://github.com/dixonwille/wmenu","commit_stats":{"total_commits":79,"total_committers":14,"mean_commits":5.642857142857143,"dds":0.5822784810126582,"last_synced_commit":"67b507ce85842a8ea305efbca1884515e8199368"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixonwille%2Fwmenu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixonwille%2Fwmenu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixonwille%2Fwmenu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dixonwille%2Fwmenu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dixonwille","download_url":"https://codeload.github.com/dixonwille/wmenu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453646,"owners_count":22073616,"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":["awesome-go","cli","golang","golang-package","menu"],"created_at":"2024-07-30T20:01:08.724Z","updated_at":"2025-05-16T02:05:15.864Z","avatar_url":"https://github.com/dixonwille.png","language":"Go","funding_links":["https://github.com/sponsors/dixonwille"],"categories":["Command Line","\u003cspan id=\"命令行-command-line\"\u003e命令行 Command Line\u003c/span\u003e","命令行","命令行工具","Build Automation","命令行工具### 标准 CLI`用于创建一个标准命令行应用程序的库`"],"sub_categories":["Standard CLI","标准CLI","标准 CLI","标准命令行交互","標準命令行交互"],"readme":"# WMenu[![Pull Requests](https://github.com/dixonwille/wmenu/actions/workflows/pullRequests.yaml/badge.svg?event=push)](https://github.com/dixonwille/wmenu/actions/workflows/pullRequests.yaml)\n\nPackage wmenu creates menus for cli programs. It uses wlog for its interface\nwith the command line. It uses os.Stdin, os.Stdout, and os.Stderr with\nconcurrency by default. wmenu allows you to change the color of the different\nparts of the menu. This package also creates it's own error structure so you can\ntype assert if you need to. wmenu will validate all responses before calling any function. It will also figure out which function should be called so you don't have to.\n\n[![Watch example](https://asciinema.org/a/4lv3ash3ubtnsclindvzdf320.png)](https://asciinema.org/a/4lv3ash3ubtnsclindvzdf320)\n\n## Import\n\n### Post Go1.11\n\n```go\nimport \"github.com/dixonwille/wmenu/v5\"\n```\n\n### Pre Go1.11\n\nI try and keep up with my tags. To use the version and stable it is recommended to use `govendor` or another vendoring tool that allows you to build your project for specific tags.\n\n```sh\ngovendor fetch github.com/dixonwille/wmenu@v4\n```\n\nThe above will grab the latest v4 at that time and mark it. It will then be stable for you to use.\n\nI will try to support as many versions as possable but please be patient.\n\n### V1.0.0 - Major Release [![Go Report Card](https://goreportcard.com/badge/gopkg.in/dixonwille/wmenu.v1)](https://goreportcard.com/report/gopkg.in/dixonwille/wmenu.v1) [![GoDoc](https://godoc.org/https://godoc.org/gopkg.in/dixonwille/wmenu.v1?status.svg)](https://godoc.org/gopkg.in/dixonwille/wmenu.v1)\n\n### V2.0.0 - Allowing an interface to be passed in for options [![Go Report Card](https://goreportcard.com/badge/gopkg.in/dixonwille/wmenu.v2)](https://goreportcard.com/report/gopkg.in/dixonwille/wmenu.v2) [![GoDoc](https://godoc.org/https://godoc.org/gopkg.in/dixonwille/wmenu.v2?status.svg)](https://godoc.org/gopkg.in/dixonwille/wmenu.v2)\n\n### V3.0.0 - Pass in the option to that option's function [![Go Report Card](https://goreportcard.com/badge/gopkg.in/dixonwille/wmenu.v3)](https://goreportcard.com/report/gopkg.in/dixonwille/wmenu.v3) [![GoDoc](https://godoc.org/https://godoc.org/gopkg.in/dixonwille/wmenu.v3?status.svg)](https://godoc.org/gopkg.in/dixonwille/wmenu.v3)\n\n### V4.0.0 - Now have an Action that supports multiple options [![Go Report Card](https://goreportcard.com/badge/gopkg.in/dixonwille/wmenu.v4)](https://goreportcard.com/report/gopkg.in/dixonwille/wmenu.v4) [![GoDoc](https://godoc.org/https://godoc.org/gopkg.in/dixonwille/wmenu.v4?status.svg)](https://godoc.org/gopkg.in/dixonwille/wmenu.v4)\n\n### v5.0.0 - Support Go Mods\n\nhttps://pkg.go.dev/github.com/dixonwille/wmenu/v5\n\n## Features\n\n- Force single selection\n- Allow multiple selection\n- Change the delimiter\n- Change the color of different parts of the menu\n- Easily see which option(s) are default\n- Change the symbol used for default option(s)\n- Ask simple yes and no questions\n- Validate all responses before calling any functions\n- With yes and no can accept:\n  - yes, Yes, YES, y, Y\n  - no, No, NO, n, N\n- Figure out which Action should be called (Options, Default, or Multiple Action)\n- Re-ask question if invalid response up to a certain number of times\n- Can change max number of times to ask before failing output\n- Change reader and writer\n- Clear the screen whenever the menu is brought up\n- Has its own error structure so you can type assert menu errors\n\n### V2 - Adds these Features\n\n- Allowing any interface to be passed through for the options.\n\n### V3 - Adds these Features\n\n- Pass the option chosen to that options function\n\n### V4 - Adds these Features\n\n- Have one function for both single and multiple select. Allowing the user to an easier way of handeling the request.\n\n### v5 - Support Go Mods\n\n- No other change except you should import with the following now\n\n```go\nimport \"github.com/dixonwille/wmenu/v5\"\n```\n\n## Usage\n\nThis is a simple use of the package. (**NOTE: THIS IS A V4 SAMPLE**)\n\n```go\nmenu := wmenu.NewMenu(\"What is your favorite food?\")\nmenu.Action(func (opts []wmenu.Opt) error {fmt.Printf(opts[0].Text + \" is your favorite food.\"); return nil})\nmenu.Option(\"Pizza\", nil, true, nil)\nmenu.Option(\"Ice Cream\", nil, false, nil)\nmenu.Option(\"Tacos\", nil, false, func(opt wmenu.Opt) error {\n  fmt.Printf(\"Tacos are great\")\n  return nil\n})\nerr := menu.Run()\nif err != nil{\n  log.Fatal(err)\n}\n```\n\nThe output would look like this:\n\n```\n1) *Pizza\n2) Ice Cream\n3) Tacos\nWhat is your favorite food?\n```\n\nIf the user just presses `[Enter]` then the option(s) with the `*` will be selected. This indicates that it is a default function. If they choose `1` then they would see `Ice Cream is your favorite food.`. This used the Action's function because the option selected didn't have a function along with it. But if they choose `2` they would see `Tacos are great`. That option did have a function with it which take precedence over Action.\n\nYou can you also use:\n\n```go\nmenu.AllowMultiple()\n```\n\nThis will allow the user to select multiple options. The default delimiter is a `[space]`, but can be changed by using:\n\n```go\nmenu.SetSeperator(\"some string\")\n```\n\nAnother feature is the ability to ask yes or no questions.\n\n```go\nmenu.IsYesNo(0)\n```\n\nThis will remove any options previously added options and hide the ones used for the menu. It will simply just ask yes or no. Menu will parse and validate the response for you. This option will always call the Action's function and pass in the option that was selected.\n\n## V3+ - Release\n\nAllows the user to pass anything for the value so it can be retrieved later in the function. The following is to show case the power of this.\n\n\u003e The following was written in V3 but the concept holds for V4. V4 just changed `actFunc` to be `func([]wmenu.Opt) error` instead.\n\n```go\ntype NameEntity struct {\n  FirstName string\n  LastName  string\n}\n\noptFunc := func(opt wmenu.Opt) error {\n  fmt.Println(\"Option 1 was chosen.\")\n  return nil\n}\nactFunc := func(opt wmenu.Opt) error {\n  name, ok := opt.Value.(NameEntity)\n  if !ok {\n    log.Fatal(\"Could not cast option's value to NameEntity\")\n  }\n  fmt.Printf(\"%s has an id of %d.\\n\", opt.Text, opt.ID)\n  fmt.Printf(\"Hello, %s %s.\\n\", name.FirstName, name.LastName)\n  return nil\n}\nmenu := NewMenu(\"Choose an option.\")\nmenu.ChangeReaderWriter(reader, os.Stdout, os.Stderr)\nmenu.Action(actFunc)\nmenu.Option(\"Option 1\", NameEntity{\"Bill\", \"Bob\"}, true, optFunc)\nmenu.Option(\"Option 2\", NameEntity{\"John\", \"Doe\"}, false, nil)\nmenu.Option(\"Option 3\", NameEntity{\"Jane\", \"Doe\"}, false, nil)\nerr := menu.Run()\nif err != nil {\n  log.Fatal(err)\n}\n```\n\nThe immediate output would be:\n\n```\nOutput:\n1) *Option 1\n2) Option 2\n3) Option 3\nChoose an option.\n```\n\nNow if the user pushes `[ENTER]` the output would be `Options 0 was chosen.`. But now if either option 1 or 2 were chosen it would cast the options value to a NameEntity allowing the function to be able to gather both the first name and last name of the NameEntity. If you want though you can just pass in `nil` as the value or even a string (`\"hello\"`) since both of these implement the empty interface required by value. Just make sure to cast the values so you can use them appropriately.\n\n## Further Reading\n\nThis whole package has been documented and has a few examples in:\n\n- [godocs V1](https://godoc.org/gopkg.in/dixonwille/wmenu.v1)\n- [godocs V2](https://godoc.org/gopkg.in/dixonwille/wmenu.v2)\n- [godocs V3](https://godoc.org/gopkg.in/dixonwille/wmenu.v3)\n- [godocs V4](https://godoc.org/gopkg.in/dixonwille/wmenu.v4)\n- [pkg.go.dev V5](https://pkg.go.dev/github.com/dixonwille/wmenu/v5)\n\nYou should read the docs to find all functions and structures at your finger tips.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdixonwille%2Fwmenu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdixonwille%2Fwmenu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdixonwille%2Fwmenu/lists"}