@@ -286,7 +286,7 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy
// Strip leading newline from initial text content. This is is
// particularly important in non-interactive mode where leading
// newlines are very visible.
- if len(currentAssistant.Parts) == 0 && strings.HasPrefix(text, "\n") {
+ if len(currentAssistant.Parts) == 0 {
text = strings.TrimPrefix(text, "\n")
}
@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"log/slog"
+ "os"
"sync"
"time"
@@ -27,7 +28,11 @@ import (
"github.com/charmbracelet/crush/internal/permission"
"github.com/charmbracelet/crush/internal/pubsub"
"github.com/charmbracelet/crush/internal/session"
+ "github.com/charmbracelet/crush/internal/tui/components/anim"
+ "github.com/charmbracelet/crush/internal/tui/styles"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/charmbracelet/x/ansi"
+ "github.com/charmbracelet/x/exp/charmtone"
)
type App struct {
@@ -114,7 +119,25 @@ func (app *App) RunNonInteractive(ctx context.Context, output io.Writer, prompt
var spinner *format.Spinner
if !quiet {
- spinner = format.NewSpinner(ctx, cancel, "Generating")
+ t := styles.CurrentTheme()
+
+ // Detect background color to set the appropriate color for the
+ // spinner's 'Generating...' text. Without this, that text would be
+ // unreadable in light terminals.
+ hasDarkBG := true
+ if f, ok := output.(*os.File); ok {
+ hasDarkBG = lipgloss.HasDarkBackground(os.Stdin, f)
+ }
+ defaultFG := lipgloss.LightDark(hasDarkBG)(charmtone.Pepper, t.FgBase)
+
+ spinner = format.NewSpinner(ctx, cancel, anim.Settings{
+ Size: 10,
+ Label: "Generating",
+ LabelColor: defaultFG,
+ GradColorA: t.Primary,
+ GradColorB: t.Secondary,
+ CycleColors: true,
+ })
spinner.Start()
}
@@ -8,7 +8,6 @@ import (
tea "github.com/charmbracelet/bubbletea/v2"
"github.com/charmbracelet/crush/internal/tui/components/anim"
- "github.com/charmbracelet/crush/internal/tui/styles"
"github.com/charmbracelet/x/ansi"
)
@@ -42,28 +41,16 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
// NewSpinner creates a new spinner with the given message
-func NewSpinner(ctx context.Context, cancel context.CancelFunc, message string) *Spinner {
- t := styles.CurrentTheme()
- model := model{
- anim: anim.New(anim.Settings{
- Size: 10,
- Label: message,
- LabelColor: t.FgBase,
- GradColorA: t.Primary,
- GradColorB: t.Secondary,
- CycleColors: true,
- }),
+func NewSpinner(ctx context.Context, cancel context.CancelFunc, animSettings anim.Settings) *Spinner {
+ m := model{
+ anim: anim.New(animSettings),
cancel: cancel,
}
- prog := tea.NewProgram(
- model,
- tea.WithOutput(os.Stderr),
- tea.WithContext(ctx),
- )
+ p := tea.NewProgram(m, tea.WithOutput(os.Stderr), tea.WithContext(ctx))
return &Spinner{
- prog: prog,
+ prog: p,
done: make(chan struct{}, 1),
}
}