1

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 replace os.Stdin while still being able to read from stdin?
  • How can I pipe data and still have the prompt work?
securisec
  • 3,435
  • 6
  • 36
  • 63

0 Answers0