diff --git a/go.mod b/go.mod index fe734a9acb..23bf88074e 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbletea v1.1.2 github.com/charmbracelet/lipgloss v0.13.1 + github.com/charmbracelet/x/ansi v0.4.0 github.com/charmbracelet/x/exp/teatest v0.0.0-20240408110044-525ba71bb562 github.com/dimchansky/utfbom v1.1.1 github.com/fatih/color v1.18.0 @@ -111,7 +112,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/charmbracelet/x/ansi v0.4.0 // indirect github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b // indirect github.com/charmbracelet/x/term v0.2.0 // indirect github.com/containerd/errdefs v0.3.0 // indirect diff --git a/pkg/cli/cmd/radinit/display.go b/pkg/cli/cmd/radinit/display.go index 5237117b78..9bfcc88eeb 100644 --- a/pkg/cli/cmd/radinit/display.go +++ b/pkg/cli/cmd/radinit/display.go @@ -26,6 +26,7 @@ import ( "github.com/charmbracelet/bubbles/spinner" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/x/ansi" "github.com/radius-project/radius/pkg/cli/aws" "github.com/radius-project/radius/pkg/cli/azure" "github.com/radius-project/radius/pkg/cli/prompt" @@ -134,6 +135,7 @@ type summaryModel struct { style lipgloss.Style result summaryResult options initOptions + width int } // NewSummaryModel creates a new model for the options summary shown during 'rad init'. @@ -163,6 +165,8 @@ func (m *summaryModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // This function handles messages and state transitions. We don't need to update // any UI here, just return the next model and command. switch msg := msg.(type) { + case tea.WindowSizeMsg: + m.width = msg.Width case tea.KeyMsg: if msg.Type == tea.KeyCtrlC { // User is quitting @@ -260,7 +264,7 @@ func (m *summaryModel) View() string { message.WriteString(summaryFooter) - return m.style.Render(message.String()) + return m.style.Render(ansi.Hardwrap(message.String(), m.width, true)) } var _ tea.Model = &progressModel{} @@ -285,6 +289,7 @@ type progressModel struct { // suppressSpinner is used to suppress the ticking of the spinner for testing. suppressSpinner bool + width int } // Init implements the init function for tea.Model. This will be called when the model is started, before View or @@ -307,7 +312,9 @@ func (m *progressModel) Init() tea.Cmd { // and returns a tea.Cmd to quit the program if the progress is complete. func (m *progressModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { - + case tea.WindowSizeMsg: + m.width = msg.Width + return m, nil // Update our internal state when we receive a progress update message. case progressMsg: m.progress = msg @@ -400,7 +407,7 @@ func (m *progressModel) View() string { message.WriteString(progressCompleteFooter) } - return m.style.Render(message.String()) + return m.style.Render(ansi.Hardwrap(message.String(), m.width, true)) } func (m *progressModel) isComplete() bool { diff --git a/pkg/cli/prompt/list/list.go b/pkg/cli/prompt/list/list.go index 7959d5e6c8..dbf30d8116 100644 --- a/pkg/cli/prompt/list/list.go +++ b/pkg/cli/prompt/list/list.go @@ -23,6 +23,7 @@ import ( "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/x/ansi" ) const listHeight = 14 @@ -116,6 +117,7 @@ type ListModel struct { // Style configures the style applied to all rendering for the list. This can be used to apply padding and borders. Style lipgloss.Style Quitting bool + width int } // Init used for creating an initial tea command if needed. @@ -130,7 +132,8 @@ func (m ListModel) Init() tea.Cmd { // the list and quit the application. func (m ListModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { - + case tea.WindowSizeMsg: + m.width = msg.Width case tea.KeyMsg: switch keypress := msg.String(); keypress { case "ctrl+c", "q": @@ -159,5 +162,5 @@ func (m ListModel) View() string { return "" } - return m.Style.Render(m.List.View()) + return m.Style.Render(ansi.Hardwrap(m.List.View(), m.width, true)) } diff --git a/pkg/cli/prompt/text/text.go b/pkg/cli/prompt/text/text.go index 023e546205..55d9a6724a 100644 --- a/pkg/cli/prompt/text/text.go +++ b/pkg/cli/prompt/text/text.go @@ -22,6 +22,7 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/x/ansi" ) var ( @@ -58,6 +59,7 @@ type Model struct { prompt string textInput textinput.Model valueEntered bool + width int } // NewTextModel returns a new text model with prompt message. @@ -74,7 +76,6 @@ func NewTextModel(prompt string, options TextModelOptions) Model { // so it will be blocked. This means you can't type `prod-aws` which is a valid name. ti := textinput.New() ti.Focus() - ti.Width = 40 ti.Placeholder = options.Placeholder ti.EchoMode = options.EchoMode @@ -101,6 +102,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd switch msg := msg.(type) { + case tea.WindowSizeMsg: + m.width = msg.Width case tea.KeyMsg: switch msg.Type { case tea.KeyEnter: @@ -157,7 +160,7 @@ func (m Model) View() string { view.WriteString(m.ErrStyle.Render(m.textInput.Err.Error())) } - return m.Style.Render(view.String()) + return m.Style.Render(ansi.Hardwrap(view.String(), m.width, true)) } // GetValue returns the input from the user, or the default value if the user did not enter anything.