From 1ad127782c2af4c772565c2892d472300a395d43 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Mon, 21 Aug 2023 11:41:38 -0400 Subject: [PATCH] feat(textinput): example for autocompletion with charmbracelet repositories (#803) * feat: autocompletion with charmbracelet repositories * chore(deps): bump bubbles --- examples/autocomplete/main.go | 104 ++++++++++++++++++++++++++++++++++ examples/go.mod | 6 +- examples/go.sum | 8 +-- 3 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 examples/autocomplete/main.go diff --git a/examples/autocomplete/main.go b/examples/autocomplete/main.go new file mode 100644 index 0000000000..55795883f9 --- /dev/null +++ b/examples/autocomplete/main.go @@ -0,0 +1,104 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" +) + +func main() { + p := tea.NewProgram(initialModel()) + if _, err := p.Run(); err != nil { + log.Fatal(err) + } +} + +type gotReposSuccessMsg []repo +type gotReposErrMsg error + +type repo struct { + Name string `json:"name"` +} + +const reposURL = "https://api.github.com/orgs/charmbracelet/repos" + +func getRepos() tea.Msg { + req, err := http.NewRequest(http.MethodGet, reposURL, nil) + if err != nil { + return gotReposErrMsg(err) + } + + req.Header.Add("Accept", "application/vnd.github+json") + req.Header.Add("X-GitHub-Api-Version", "2022-11-28") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return gotReposErrMsg(err) + } + defer resp.Body.Close() // nolint: errcheck + + data, err := io.ReadAll(resp.Body) + if err != nil { + return gotReposErrMsg(err) + } + + var repos []repo + + err = json.Unmarshal(data, &repos) + if err != nil { + return gotReposErrMsg(err) + } + + return gotReposSuccessMsg(repos) +} + +type model struct { + textInput textinput.Model +} + +func initialModel() model { + ti := textinput.New() + ti.Placeholder = "Bubbletea" + ti.Focus() + ti.CharLimit = 50 + ti.Width = 20 + ti.ShowSuggestions = true + return model{textInput: ti} +} + +func (m model) Init() tea.Cmd { + return tea.Batch(getRepos, textinput.Blink) +} + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyEnter, tea.KeyCtrlC, tea.KeyEsc: + return m, tea.Quit + } + case gotReposSuccessMsg: + var suggestions []string + for _, r := range msg { + suggestions = append(suggestions, r.Name) + } + m.textInput.SetSuggestions(suggestions) + } + + var cmd tea.Cmd + m.textInput, cmd = m.textInput.Update(msg) + return m, cmd +} + +func (m model) View() string { + return fmt.Sprintf( + "What’s your favorite Charm repository?\n\n%s\n\n%s\n", + m.textInput.View(), + "(esc to quit)", + ) +} diff --git a/examples/go.mod b/examples/go.mod index 9de58ea074..ab5d792b53 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -3,8 +3,8 @@ module examples go 1.17 require ( - github.com/charmbracelet/bubbles v0.16.1 - github.com/charmbracelet/bubbletea v0.24.1 + github.com/charmbracelet/bubbles v0.16.2-0.20230821152602-eda891258c02 + github.com/charmbracelet/bubbletea v0.24.2 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/harmonica v0.2.0 github.com/charmbracelet/lipgloss v0.7.1 @@ -33,7 +33,7 @@ require ( github.com/muesli/cancelreader v0.2.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/sahilm/fuzzy v0.1.0 // indirect + github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect github.com/yuin/goldmark v1.5.2 // indirect github.com/yuin/goldmark-emoji v1.0.1 // indirect golang.org/x/net v0.7.0 // indirect diff --git a/examples/go.sum b/examples/go.sum index 7b504cd64c..725fddf586 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -11,8 +11,8 @@ github.com/aymanbagabas/go-udiff v0.1.0 h1:9Dpklm2oBBhMxIFbMffmPvDaF7vOYfv9B5HXV github.com/aymanbagabas/go-udiff v0.1.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= -github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= +github.com/charmbracelet/bubbles v0.16.2-0.20230821152602-eda891258c02 h1:MruS04uPbUJHF0MQzwOlh9yco1pHwPDLI7qGMu25IME= +github.com/charmbracelet/bubbles v0.16.2-0.20230821152602-eda891258c02/go.mod h1:XUdibuVUiMfcfKTRla58bmY3TWsdjgF+Rp8pvimQLck= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= @@ -68,8 +68,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= -github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= +github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=