mirror of
https://github.com/charmbracelet/crush.git
synced 2026-05-30 18:47:33 +00:00
97 lines
1.7 KiB
Go
97 lines
1.7 KiB
Go
// Package util provides utility functions for UI message handling.
|
|
package util
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os/exec"
|
|
"time"
|
|
|
|
tea "charm.land/bubbletea/v2"
|
|
"mvdan.cc/sh/v3/shell"
|
|
)
|
|
|
|
type Cursor interface {
|
|
Cursor() *tea.Cursor
|
|
}
|
|
|
|
func CmdHandler(msg tea.Msg) tea.Cmd {
|
|
return func() tea.Msg {
|
|
return msg
|
|
}
|
|
}
|
|
|
|
func ReportError(err error) tea.Cmd {
|
|
return CmdHandler(NewErrorMsg(err))
|
|
}
|
|
|
|
type InfoType int
|
|
|
|
const (
|
|
InfoTypeInfo InfoType = iota
|
|
InfoTypeSuccess
|
|
InfoTypeWarn
|
|
InfoTypeError
|
|
InfoTypeUpdate
|
|
)
|
|
|
|
func NewInfoMsg(info string) InfoMsg {
|
|
return InfoMsg{
|
|
Type: InfoTypeInfo,
|
|
Msg: info,
|
|
}
|
|
}
|
|
|
|
func NewWarnMsg(warn string) InfoMsg {
|
|
return InfoMsg{
|
|
Type: InfoTypeWarn,
|
|
Msg: warn,
|
|
}
|
|
}
|
|
|
|
func NewErrorMsg(err error) InfoMsg {
|
|
return InfoMsg{
|
|
Type: InfoTypeError,
|
|
Msg: err.Error(),
|
|
}
|
|
}
|
|
|
|
func ReportInfo(info string) tea.Cmd {
|
|
return CmdHandler(NewInfoMsg(info))
|
|
}
|
|
|
|
func ReportWarn(warn string) tea.Cmd {
|
|
return CmdHandler(NewWarnMsg(warn))
|
|
}
|
|
|
|
type (
|
|
InfoMsg struct {
|
|
Type InfoType
|
|
Msg string
|
|
TTL time.Duration
|
|
}
|
|
ClearStatusMsg struct{}
|
|
)
|
|
|
|
// IsEmpty checks if the [InfoMsg] is empty.
|
|
func (m InfoMsg) IsEmpty() bool {
|
|
var zero InfoMsg
|
|
return m == zero
|
|
}
|
|
|
|
// ExecShell parses a shell command string and executes it with exec.Command.
|
|
// Uses shell.Fields for proper handling of shell syntax like quotes and
|
|
// arguments while preserving TTY handling for terminal editors.
|
|
func ExecShell(ctx context.Context, cmdStr string, callback tea.ExecCallback) tea.Cmd {
|
|
fields, err := shell.Fields(cmdStr, nil)
|
|
if err != nil {
|
|
return ReportError(err)
|
|
}
|
|
if len(fields) == 0 {
|
|
return ReportError(errors.New("empty command"))
|
|
}
|
|
|
|
cmd := exec.CommandContext(ctx, fields[0], fields[1:]...)
|
|
return tea.ExecProcess(cmd, callback)
|
|
}
|