diff --git a/internal/tui/util/shell.go b/internal/tui/util/shell.go index 43690c8aaacd6a396b02220536d022c674f16111..7bf30e2640e79a80291077faa5134a9eea28a87b 100644 --- a/internal/tui/util/shell.go +++ b/internal/tui/util/shell.go @@ -2,25 +2,14 @@ package util import ( "context" - "errors" - "os/exec" tea "charm.land/bubbletea/v2" - "mvdan.cc/sh/v3/shell" + "github.com/charmbracelet/crush/internal/uiutil" ) // 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) + return uiutil.ExecShell(ctx, cmdStr, callback) } diff --git a/internal/uiutil/uiutil.go b/internal/uiutil/uiutil.go index 2a05f95a3a142c55673f19a303b4f1b2cbeea65b..efd89dda69f780b354777916b459675154780372 100644 --- a/internal/uiutil/uiutil.go +++ b/internal/uiutil/uiutil.go @@ -4,10 +4,14 @@ package uiutil import ( + "context" + "errors" "log/slog" + "os/exec" "time" tea "charm.land/bubbletea/v2" + "mvdan.cc/sh/v3/shell" ) type Cursor interface { @@ -60,3 +64,19 @@ type ( } ClearStatusMsg struct{} ) + +// 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) +}