Skip to content

chore: replace AlecAivazis/survey with charmbracelet/bubbletea #14475

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Sep 4, 2024
Merged
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3934cb6
chore: replace survery library with bubbletea
DanielleMaywood Aug 29, 2024
164402b
chore: fix nolint comments
DanielleMaywood Aug 29, 2024
360fb95
chore: add message and colour to select prompts
DanielleMaywood Aug 29, 2024
7cf35d1
chore: make SelectedOptions private
DanielleMaywood Aug 29, 2024
b5092a6
chore: add filtering for multiselect, improve filtering algo
DanielleMaywood Aug 29, 2024
e4c010e
chore: allow vertical wrap on select/multiselect
DanielleMaywood Aug 29, 2024
2b6cd6e
chore: fix failing jobs
DanielleMaywood Aug 29, 2024
35fe461
chore: update charmbracelet/bubbletea to v1.0.0
DanielleMaywood Aug 29, 2024
5982185
chore: remove windows testing workaround for survey library
DanielleMaywood Aug 29, 2024
affbfbe
chore: update bubbletea to v1.1.0
DanielleMaywood Sep 2, 2024
33196cd
chore: reimplement testing workaround
DanielleMaywood Sep 2, 2024
409cec5
chore: use survey's default page size
DanielleMaywood Sep 2, 2024
52ed127
chore: ensure no underflow on page bottom
DanielleMaywood Sep 2, 2024
60c83d0
chore: remove multi-select test from cmd/cliui
DanielleMaywood Sep 3, 2024
2b621ce
chore: disable HideSearch from cmd/cliui select
DanielleMaywood Sep 3, 2024
8a3cd26
chore: use strings.Builder, fix select all logic, apply nitpicks
DanielleMaywood Sep 3, 2024
6e59ecb
chore: use strings.Builder
DanielleMaywood Sep 3, 2024
579c73b
chore: move m.search.Update out of case
DanielleMaywood Sep 3, 2024
9078242
chore: use tea.WithContext(inv.Context()) for tea program
DanielleMaywood Sep 3, 2024
f2ed4fa
chore: return nil as err already handled
DanielleMaywood Sep 3, 2024
7784110
chore: use const instead of magic number
DanielleMaywood Sep 3, 2024
f598836
chore: handle signals ourself instead of bubbletea
DanielleMaywood Sep 3, 2024
8a7f1bc
chore: update flake.nix
DanielleMaywood Sep 4, 2024
77804e0
chore: update flake.nix
DanielleMaywood Sep 4, 2024
2904b7c
chore: update flake.nix
DanielleMaywood Sep 4, 2024
0b99afe
chore: update flake.nix
DanielleMaywood Sep 4, 2024
b173fb0
chore: update flake.nix
DanielleMaywood Sep 4, 2024
966f772
chore: update flake.nix
DanielleMaywood Sep 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: handle signals ourself instead of bubbletea
  • Loading branch information
DanielleMaywood committed Sep 4, 2024
commit f5988362bfbd89ea492cd658c897739c894c23e2
72 changes: 65 additions & 7 deletions cli/cliui/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package cliui
import (
"flag"
"fmt"
"os"
"os/signal"
"strings"
"syscall"

"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
Expand All @@ -16,6 +19,36 @@ import (

const defaultSelectModelHeight = 7

type terminateMsg struct{}

func installSignalHandler(p *tea.Program) func() {
ch := make(chan struct{})

go func() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)

defer func() {
signal.Stop(sig)
close(ch)
}()

for {
select {
case <-ch:
return

case <-sig:
p.Send(terminateMsg{})
}
}
}()

return func() {
ch <- struct{}{}
}
}

type SelectOptions struct {
Options []string
// Default will be highlighted first if it's a valid option.
Expand Down Expand Up @@ -92,12 +125,18 @@ func Select(inv *serpent.Invocation, opts SelectOptions) (string, error) {
initialModel.search.Prompt = ""
initialModel.search.Focus()

m, err := tea.NewProgram(
p := tea.NewProgram(
initialModel,
tea.WithoutSignalHandler(),
tea.WithContext(inv.Context()),
tea.WithInput(inv.Stdin),
tea.WithOutput(inv.Stdout),
).Run()
)

closeSignalHandler := installSignalHandler(p)
defer closeSignalHandler()

m, err := p.Run()
if err != nil {
return "", err
}
Expand Down Expand Up @@ -126,14 +165,19 @@ type selectModel struct {
}

func (selectModel) Init() tea.Cmd {
return textinput.Blink
return nil
}

//nolint:revive // The linter complains about modifying 'm' but this is typical practice for bubbletea
func (m selectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd

if msg, ok := msg.(tea.KeyMsg); ok {
switch msg := msg.(type) {
case terminateMsg:
m.canceled = true
return m, tea.Quit

case tea.KeyMsg:
switch msg.Type {
case tea.KeyCtrlC:
m.canceled = true
Expand Down Expand Up @@ -292,12 +336,18 @@ func MultiSelect(inv *serpent.Invocation, opts MultiSelectOptions) ([]string, er
initialModel.search.Prompt = ""
initialModel.search.Focus()

m, err := tea.NewProgram(
p := tea.NewProgram(
initialModel,
tea.WithoutSignalHandler(),
tea.WithContext(inv.Context()),
tea.WithInput(inv.Stdin),
tea.WithOutput(inv.Stdout),
).Run()
)

closeSignalHandler := installSignalHandler(p)
defer closeSignalHandler()

m, err := p.Run()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -336,7 +386,12 @@ func (multiSelectModel) Init() tea.Cmd {
func (m multiSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd

if msg, ok := msg.(tea.KeyMsg); ok {
switch msg := msg.(type) {
case terminateMsg:
m.canceled = true
return m, tea.Quit

case tea.KeyMsg:
switch msg.Type {
case tea.KeyCtrlC:
m.canceled = true
Expand All @@ -353,6 +408,9 @@ func (m multiSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if len(options) != 0 {
options[m.cursor].chosen = !options[m.cursor].chosen
}
// We back out early here otherwise a space will be inserted
// into the search field.
return m, nil

case tea.KeyUp:
options := m.filteredOptions()
Expand Down