promptui is Go library that provides a simple interface to create CLI prompts. The library has two main modes: Prompt — which provides a single line for user input, and Select — which displays a list of items to choose from. Both modes have several options for customization and take advantage of the powerful readline to support multiple terminals.
In this post we are going to create a food recipe command-line app that asks for a dish type, retrieves information from an API and displays the relevant recipes.
If you want to jump to the complete app source code, go to: https://github.com/luizbranco/promptui-demo/
Before we begin our app, we first need to get the library:
go get -u github.com/manifoldco/promptui
With that in our Go path we can start writing our `main.go` file.
If you then run the program, you should see a prompt asking to search:
go run main.go
That seems nice, but if we just press enter without entering information it still works. It would be nice if we could prevent empty searches. So lets add a validation to the prompt:
This is a very simple validation. But you can create more complex ones using regexp or govalidator, for example.
For this CLI app we are going to use the awesome RecipePuppy to search for recipes. Its API doesn’t require authentication, so it’s perfect for our experiment.
First we define how to request the data:
That’s easy! Now we have to parse the response JSON. First we need an example of the data returned:
As we can see, there is an array of results with title, link and a list of ingredients for each recipe. With that, we can define a few structures to parse the body:
Now that we have the list of recipes parsed, we can use Select to display it to the user.
<img src="https://media.giphy.com/media/xUNda0l40DDysQQ87e/giphy.gif" />
Well, that’s a bit ugly. The issue here is that promptui usually expects a slice of strings to display. But we have recipe structures instead. We have to teach promptui how to display them. That’s when templates are handy:
If you have used Go templates/html you should be familiar with the syntax. Promptui out-of-the-box supports a few template functions such as colors and styles, but you can define your own helpers.
<img src="https://media.giphy.com/media/xUNda0Ngb5qsogLsBi/giphy.gif" />
Much better! Notice the pizza unicode symbol there. Go supports UTF-8 source code 👍.
Since we also have a list of ingredients, we can show it when users are hovering an element with the Details template option. But first, lets be good CLI citizens and avoid a long list of ingredients!
This defines a custom helper function that truncates strings longer than X characters. Then we change templates to be:
Finally, lets allow users to search the list inline for either the recipe name or ingredients:
As it was with the validation example, this is a trivial string search, but you can make as complex as you need.
<img src="https://media.giphy.com/media/26FfgSKnDDjW81BoA/giphy.gif" />
promptui was part of our command-line tool Manifold in which we use mainly as a fallback when users don’t input all flags necessary for commands. This small app shows a few features of promptui, but the library has much more to offer. Make sure to check the Github project page.