1package util
2
3import (
4 "context"
5 "errors"
6 "os/exec"
7
8 tea "charm.land/bubbletea/v2"
9 "mvdan.cc/sh/v3/shell"
10)
11
12// ExecShell parses a shell command string and executes it with exec.Command.
13// Uses shell.Fields for proper handling of shell syntax like quotes and
14// arguments while preserving TTY handling for terminal editors.
15func ExecShell(ctx context.Context, cmdStr string, callback tea.ExecCallback) tea.Cmd {
16 fields, err := shell.Fields(cmdStr, nil)
17 if err != nil {
18 return ReportError(err)
19 }
20 if len(fields) == 0 {
21 return ReportError(errors.New("empty command"))
22 }
23
24 cmd := exec.CommandContext(ctx, fields[0], fields[1:]...)
25 return tea.ExecProcess(cmd, callback)
26}