Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
75
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@c-bata

go-promptを使ったリッチなコマンドラインツールの作り方

先週go-promptというGoの端末制御ライブラリを公開しました。

c-bata/go-prompt: A library for building powerful interactive prompts inspired by python-prompt-toolkit, making it easier to build cross-platform command line tools using Go.
https://github.com/c-bata/go-prompt

このライブラリを使うと kube-prompt のような強力な補完を持つツールが簡単に開発できます。
この記事ではgo-promptの使い方について解説していきます

Getting Started

それではさっそくgo-promptを使ってリッチなコマンドラインツールを作ってみましょう。

Download

$ go get github.com/c-bata/go-prompt

簡単なサンプル

package main

import (
    "fmt"

    "github.com/c-bata/go-prompt"
)

func completer(in prompt.Document) []prompt.Suggest {
    s := []prompt.Suggest{
        {Text: "users", Description: "Store the username and age"},
        {Text: "articles", Description: "Store the article text posted by user"},
        {Text: "comments", Description: "Store the text commented to articles"},
        {Text: "groups", Description: "Combine users with specific rules"},
    }
    return prompt.FilterHasPrefix(s, in.GetWordBeforeCursor(), true)
}

func main() {
    in := prompt.Input(">>> ", completer, prompt.OptionTitle("sql-prompt"))
    fmt.Println("Your input: " + in)
}

それでは実行してみましょう

simple-input.gif

上のプログラムでは、例えば 「a」と入力すると completer 関数が返す prompt.Suggest の中で「a」から始まるアイテムの一覧を返します。
prompt.Input 関数はユーザが入力した文字列をそのまま返してくれます。

オプションでカスタマイズする

go-promptには様々なオプションが用意されています。
詳細は GoDoc c-bata/go-prompt にまとまっていますが、色に関するオプションは沢山あり、紛らわしいので↓の画像を参考にしてください。

prompt-options

それでは実際にoptionをカスタマイズしてみましょう。

package main

import (
    "fmt"

    "github.com/c-bata/go-prompt"
)

func completer(in prompt.Document) []prompt.Suggest {
    s := []prompt.Suggest{
        {Text: "users", Description: "Store the username and age"},
        {Text: "articles", Description: "Store the article text posted by user"},
        {Text: "comments", Description: "Store the text commented to articles"},
        {Text: "groups", Description: "Combine users with specific rules"},
    }
    return prompt.FilterHasPrefix(s, in.GetWordBeforeCursor(), true)
}

func main() {
    in := prompt.Input(">>> ", completer,
        prompt.OptionTitle("sql-prompt"),  // Terminalのタイトルを変更
        prompt.OptionHistory([]string{"SELECT * FROM users;"}),  // 歴史を予め追加(本来はlogファイルみたいなところに書き出しておいて、起動時に読み込んだりします)
        prompt.OptionPrefixTextColor(prompt.Yellow),  // Prefix(ここでは >>>) の色を黄色に変更
        prompt.OptionPreviewSuggestionTextColor(prompt.Blue),
        prompt.OptionSelectedSuggestionBGColor(prompt.LightGray),
        prompt.OptionSuggestionBGColor(prompt.DarkGray))
    fmt.Println("Your input: " + in)
}

実行すると次のようになります。

customized.gif

kube-prompt

実際にkube-promptというKubernetesのクライアントも作成しました。
go-promptを使って何かツールを書く際は、kube-promptの実装も参考にしてみてください。

c-bata/kube-prompt: An interactive kubernetes client featuring auto-complete using go-prompt.
https://github.com/c-bata/kube-prompt

おわりに

キーバインドのカスタマイズなど、今回解説していない機能もありますが、これだけでも強力な補完が可能なコマンドラインツールの開発ができます。

ぜひ活用してみてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
75
Help us understand the problem. What are the problem?