I am trying to write a simple cli using promptui
and everything is working as expected; till I try to pipe data to it. After some debugging and digging around, I realized that this is so because stdin
is being used already when piping so that stdin is being interpreted and any control characters from the pipe is breaking the prompt. (with control+d) in this case.
Example:
package main
import (
"fmt"
"os"
"strings"
"github.com/manifoldco/promptui"
)
var items = []string{"some", "thing"}
func main() {
fmt.Printf("Is from pipe %t\n", isFromPipe())
// read data from pipe and do something
// ... doesnt effect this prompt
prompt := promptui.Select{
Stdout: os.Stderr,
// Stdin: os.Stderr, // testing to see if stdin is what is breaking
StartInSearchMode: true,
Label: "pick something",
Items: items,
Searcher: func(input string, index int) bool {
d := items[index]
name := strings.Replace(strings.ToLower(d), " ", "", -1)
input = strings.Replace(strings.ToLower(input), " ", "", -1)
return strings.Contains(name, input)
},
}
_, result, err := prompt.Run()
if err != nil {
fmt.Printf("Prompt failed %v\n", err)
return
}
fmt.Printf("You choose %q\n", result)
}
func isFromPipe() bool {
fi, _ := os.Stdin.Stat()
return fi.Mode()&os.ModeCharDevice == 0
}
When I uncomment StdIn
, the prompt will work, but input will not work.
So my question is:
- Can I use a different
io.ReaderCloser
to replaceos.Stdin
while still being able to read from stdin? - How can I pipe data and still have the prompt work?