pecoをGoのプログラムからライブラリっぽく呼び出す

今の僕の暮らしの中で、ハンバーグ、オムライスの次に欠かせないのが、pecoです。pecoが何かというのはもはや説明は不要かと思いますが、通常pecoを利用する場合、下記のように利用します。

$ ls -ltr | peco

結果として、ディレクトリに存在するファイル、ディレクトリを対話的に選択できて、結果を標準出力するというものなのですが、この挙動をどうしても自分で作ったCLIの中で実現したい、そう思ったことはないでしょうか。かなり無理矢理ですが下記のように書くことで実現できます。

	out, err := exec.Command("ls", "-ltr").Output()
	if err != nil {
		panic(err)
	}

	var choice = bytes.Buffer{}
	pecoCli := peco.New()
	pecoCli.Argv = nil
	pecoCli.Stdin = out
	pecoCli.Stdout = &choice

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	if err := pecoCli.Run(ctx); err != nil {
		if reflect.TypeOf(err).Name() == "errCollectResults" {
			pecoCli.PrintResults()
		} else {
			return err
		}
	}
	fmt.Println(choice.String())

重要なのは、 pecoCli.Argv = nil でこれがない場合、自分が書いたCLIの引数をもとに、意図しない動作になるので、必ずnil代入しましょう。

utils などがちゃんとinternalで管理されており、本来作者の意図する使い方ではないのですが、こうすると利用することはできるっちゃできるくらいな、温度感で参考にしてもらえれば幸いです。また、 reflect.TypeOf(err).Name() のような記述は、避けるべきなので、使う場所にもご注意ください。

Excuseするのめちゃダサいと思って生きてきたけど、めちゃExcuseする男になってしまった。