package runner import ( "bytes" "io" "os" "os/exec" "strings" ) // Stream runs rg with args, streaming stdout/stderr directly to the terminal. func RgStream(args ...string) error { cmd := exec.Command("rg", args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() } // ListFiles runs rg -l (files-with-matches) and returns the list of matching file paths. func RgListFiles(pattern, path string, extraArgs ...string) ([]string, error) { args := append([]string{"-l", pattern, path}, extraArgs...) cmd := exec.Command("rg", args...) var out bytes.Buffer cmd.Stdout = &out cmd.Stderr = io.Discard if err := cmd.Run(); err != nil { // exit code 1 means no matches — not an error for our purposes if cmd.ProcessState != nil && cmd.ProcessState.ExitCode() == 1 { return nil, nil } return nil, err } return splitLines(out.String()), nil } func splitLines(s string) []string { s = strings.TrimRight(s, "\n") if s == "" { return nil } return strings.Split(s, "\n") }