mirror of
https://github.com/taigrr/bubbletea.git
synced 2026-04-02 02:59:09 -07:00
De-indent code blocks in the command tutorial
This commit is contained in:
@@ -19,18 +19,18 @@ We'll import a few necessary packages and put the URL we're going to check in
|
||||
a `const`.
|
||||
|
||||
```go
|
||||
package main
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
const url = "https://charm.sh/"
|
||||
const url = "https://charm.sh/"
|
||||
```
|
||||
|
||||
## The Model
|
||||
@@ -39,10 +39,10 @@ Next we'll define our model. The only things we need to store are the status
|
||||
code of the HTTP response and a possible error.
|
||||
|
||||
```go
|
||||
type model struct {
|
||||
status int
|
||||
err error
|
||||
}
|
||||
type model struct {
|
||||
status int
|
||||
err error
|
||||
}
|
||||
```
|
||||
|
||||
## Commands and Messages
|
||||
@@ -56,29 +56,29 @@ Anyway, let's write a `Cmd` that makes a request to a server and returns the
|
||||
result as a `Msg`.
|
||||
|
||||
```go
|
||||
func checkServer() tea.Msg {
|
||||
func checkServer() tea.Msg {
|
||||
|
||||
// Create an HTTP client and make a GET request.
|
||||
c := &http.Client{Timeout: 10 * time.Second}
|
||||
res, err := c.Get(url)
|
||||
// Create an HTTP client and make a GET request.
|
||||
c := &http.Client{Timeout: 10 * time.Second}
|
||||
res, err := c.Get(url)
|
||||
|
||||
if err != nil {
|
||||
// There was an error making our request. Wrap the error we received
|
||||
// in a message and return it.
|
||||
return errMsg{err}
|
||||
}
|
||||
// We received a response from the server. Return the HTTP status code
|
||||
// as a message.
|
||||
return statusMsg(res.StatusCode)
|
||||
if err != nil {
|
||||
// There was an error making our request. Wrap the error we received
|
||||
// in a message and return it.
|
||||
return errMsg{err}
|
||||
}
|
||||
// We received a response from the server. Return the HTTP status code
|
||||
// as a message.
|
||||
return statusMsg(res.StatusCode)
|
||||
}
|
||||
|
||||
type statusMsg int
|
||||
type statusMsg int
|
||||
|
||||
type errMsg struct{ err error }
|
||||
type errMsg struct{ err error }
|
||||
|
||||
// For messages that contain errors it's often handy to also implement the
|
||||
// error interface on the message.
|
||||
func (e errMsg) Error() string { return e.err.Error() }
|
||||
// For messages that contain errors it's often handy to also implement the
|
||||
// error interface on the message.
|
||||
func (e errMsg) Error() string { return e.err.Error() }
|
||||
```
|
||||
|
||||
And notice that we've defined two new `Msg` types. They can be any type, even
|
||||
@@ -92,9 +92,9 @@ the `Cmd` we made earlier. Note that we don't call the function; the Bubble Tea
|
||||
runtime will do that when the time is right.
|
||||
|
||||
```go
|
||||
func initialize() (tea.Model, tea.Cmd) {
|
||||
return model{}, checkServer
|
||||
}
|
||||
func initialize() (tea.Model, tea.Cmd) {
|
||||
return model{}, checkServer
|
||||
}
|
||||
```
|
||||
|
||||
## The Update Function
|
||||
@@ -105,37 +105,37 @@ types we made earlier when we were making the `checkServer` command? We handle
|
||||
them here. This makes dealing with many asynchronous operations very easy.
|
||||
|
||||
```go
|
||||
func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
|
||||
m, _ := mdl.(model)
|
||||
func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
|
||||
m, _ := mdl.(model)
|
||||
|
||||
switch msg := msg.(type) {
|
||||
switch msg := msg.(type) {
|
||||
|
||||
case statusMsg:
|
||||
// The server returned a status message. Save it to our model. Also
|
||||
// tell the Bubble Tea runtime we ant to exit because we have
|
||||
// nothing else to do. Don't worry, we'll still be able to render
|
||||
// a final view with our status message.
|
||||
m.status = int(msg)
|
||||
case statusMsg:
|
||||
// The server returned a status message. Save it to our model. Also
|
||||
// tell the Bubble Tea runtime we ant to exit because we have
|
||||
// nothing else to do. Don't worry, we'll still be able to render
|
||||
// a final view with our status message.
|
||||
m.status = int(msg)
|
||||
return m, tea.Quit
|
||||
|
||||
case errMsg:
|
||||
// There was an error. Note it in the model. And tell the runtime
|
||||
// we're done and want to quit.
|
||||
m.err = msg
|
||||
return m, tea.Quit
|
||||
|
||||
case tea.KeyMsg:
|
||||
// Ctrl+c exits. Even with short running programs it's good to have
|
||||
// a quit key, just incase your logic is off. Users will be very
|
||||
// annoyed if they can't exit.
|
||||
if msg.Type == tea.KeyCtrlC {
|
||||
return m, tea.Quit
|
||||
|
||||
case errMsg:
|
||||
// There was an error. Note it in the model. And tell the runtime
|
||||
// we're done and want to quit.
|
||||
m.err = msg
|
||||
return m, tea.Quit
|
||||
|
||||
case tea.KeyMsg:
|
||||
// Ctrl+c exits. Even with short running programs it's good to have
|
||||
// a quit key, just incase your logic is off. Users will be very
|
||||
// annoyed if they can't exit.
|
||||
if msg.Type == tea.KeyCtrlC {
|
||||
return m, tea.Quit
|
||||
}
|
||||
}
|
||||
|
||||
// If we happen to get any other messages, don't do anything.
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// If we happen to get any other messages, don't do anything.
|
||||
return m, nil
|
||||
}
|
||||
```
|
||||
|
||||
## The View Function
|
||||
@@ -144,25 +144,25 @@ Our view is very straightforward. We look at the current model and build a
|
||||
string accordingly:
|
||||
|
||||
```go
|
||||
func view(mdl tea.Model) string {
|
||||
m, _ := mdl.(model)
|
||||
func view(mdl tea.Model) string {
|
||||
m, _ := mdl.(model)
|
||||
|
||||
// If there's an error, print it out and don't do anything else.
|
||||
if m.err != nil {
|
||||
return fmt.Sprintf("\nWe had some trouble: %v\n\n", m.err)
|
||||
}
|
||||
|
||||
// Tell the user we're doing something.
|
||||
s := fmt.Sprintf("Checking %s ... ", url)
|
||||
|
||||
// When the server responds with a status, add it to the current line.
|
||||
if m.status > 0 {
|
||||
s += fmt.Sprintf("%d %s!", m.status, http.StatusText(m.status))
|
||||
}
|
||||
|
||||
// Send off whatever we came up with above for rendering.
|
||||
return "\n" + s + "\n\n"
|
||||
// If there's an error, print it out and don't do anything else.
|
||||
if m.err != nil {
|
||||
return fmt.Sprintf("\nWe had some trouble: %v\n\n", m.err)
|
||||
}
|
||||
|
||||
// Tell the user we're doing something.
|
||||
s := fmt.Sprintf("Checking %s ... ", url)
|
||||
|
||||
// When the server responds with a status, add it to the current line.
|
||||
if m.status > 0 {
|
||||
s += fmt.Sprintf("%d %s!", m.status, http.StatusText(m.status))
|
||||
}
|
||||
|
||||
// Send off whatever we came up with above for rendering.
|
||||
return "\n" + s + "\n\n"
|
||||
}
|
||||
```
|
||||
|
||||
## Run the program
|
||||
@@ -170,12 +170,12 @@ string accordingly:
|
||||
The only thing left to do is run the program, so let's do that!
|
||||
|
||||
```go
|
||||
func main() {
|
||||
if err := tea.NewProgram(initialize, update, view).Start(); err != nil {
|
||||
fmt.Printf("Uh oh, there was an error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
func main() {
|
||||
if err := tea.NewProgram(initialize, update, view).Start(); err != nil {
|
||||
fmt.Printf("Uh oh, there was an error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And that's that. There's one more thing you that is helpful to know about
|
||||
@@ -189,18 +189,16 @@ anything. If you need to pass arguments to a command, you just make a function
|
||||
that returns a command. For example:
|
||||
|
||||
```go
|
||||
|
||||
func checkSomeUrl(url string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
c := &http.Client{Timeout: 10 * time.Second}
|
||||
res, err := c.Get(url)
|
||||
if err != nil {
|
||||
return errMsg(err)
|
||||
}
|
||||
return statusMsg(res.StatusCode)
|
||||
func checkSomeUrl(url string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
c := &http.Client{Timeout: 10 * time.Second}
|
||||
res, err := c.Get(url)
|
||||
if err != nil {
|
||||
return errMsg(err)
|
||||
}
|
||||
return statusMsg(res.StatusCode)
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Just make sure you do as much stuff as you can in the innermost function,
|
||||
|
||||
Reference in New Issue
Block a user