Goでエスケープシーケンスを使ってコマンドプロンプトに色を出す
Tags: go, windows
Published: 2014-05-15 16:20:00

---
title: Goでエスケープシーケンスを使ってコマンドプロンプトに色を出す
published: true
tags: Go, Windows
date: 20140515T16:20Z
canonical_url: https://qiita.com/shiena/items/1b51db47009e4b899b1e
---
# コマンドプロンプトで簡単に色を出したい

Windowsのコマンドプロンプトで色を出したいならコンソールAPIの[SetConsoleTextAttribute](http://msdn.microsoft.com/ja-jp/library/cc429756.aspx)を使えばいいのですがエスケープシーケンスと比べると手間がかかります。
そこで、エスケープシーケンスの一部をパースして色を出すGoのライブラリを作りました。

https://github.com/shiena/ansicolor

## サンプル1

使い方はとても簡単で、`ansicolor.NewAnsiColorWriter(os.Stdout)`で生成したWriterにFprintf系の関数でエスケープシーケンスの文字列を出力するだけです。
またWindows以外では引数のio.Writerに対してWrite関数を呼ぶだけのラッパーなのでOSの違いを意識する必要はありません。

```go:main.go
package main

import (
    "fmt"
    "os"

    "github.com/shiena/ansicolor"
)

func main() {
    w := ansicolor.NewAnsiColorWriter(os.Stdout)
    text := "%sforeground %sbold%s %sbackground%s\n"
    fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[22m", "\x1b[41;32m", "\x1b[0m")
    fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[22m", "\x1b[42;31m", "\x1b[0m")
    fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[22m", "\x1b[43;34m", "\x1b[0m")
    fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[22m", "\x1b[44;33m", "\x1b[0m")
    fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[22m", "\x1b[45;36m", "\x1b[0m")
    fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[22m", "\x1b[46;35m", "\x1b[0m")
    fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[22m", "\x1b[47;30m", "\x1b[0m")
}
```

## サンプル2

`github.com/wsxiaoys/terminal/color`と組合せると更に簡単になります。

```go:main.go
package main

import (
	"os"

	"github.com/shiena/ansicolor"
	"github.com/wsxiaoys/terminal/color"
)

func main() {
	w := ansicolor.NewAnsiColorWriter(os.Stdout)
	color.Fprintf(w, "@{r}foreground @{r!}bold@{|} @{gR}background@{|}\n")
	color.Fprintf(w, "@{g}foreground @{g!}bold@{|} @{rG}background@{|}\n")
	color.Fprintf(w, "@{y}foreground @{y!}bold@{|} @{bY}background@{|}\n")
	color.Fprintf(w, "@{b}foreground @{b!}bold@{|} @{yB}background@{|}\n")
	color.Fprintf(w, "@{m}foreground @{m!}bold@{|} @{cM}background@{|}\n")
	color.Fprintf(w, "@{c}foreground @{c!}bold@{|} @{mC}background@{|}\n")
	color.Fprintf(w, "@{w}foreground @{w!}bold@{|} @{kW}background@{|}\n")
}
```

## スクリーンショット

サンプルを実行したスクリーンショットです。

![screenshot](https://gist.githubusercontent.com/shiena/a1bada24b525314a7d5e/raw/c763aa7cda6e4fefaccf831e2617adc40b6151c7/main.png)

## 参考

エスケープシーケンスのパースについてANSICONとwacが参考になりました。

* https://github.com/adoxa/ansicon
* https://github.com/aslakhellesoy/wac

Goから`SetConsoleTextAttribute`やその他のコンソールAPIを呼ぶ方法はgo-colortext packageが参考になりました。

* https://github.com/daviddengcn/go-colortext

これらのソフトウェアがなければ作ることができなかったと思います。

# 2014/05/16追記
## 作成の動機はThe Platinum Searcherのissue

[The Platinum Searcher](https://github.com/monochromegane/the_platinum_searcher)の[issue#23](https://github.com/monochromegane/the_platinum_searcher/issues/23)で他のコマンドで色を出せているから対応してほしいと要望があり、興味が湧いたので調べたのがきっかけでした。
すると参考に挙げた材料が揃ってしまったので作らない訳にはいきません。
そして出来上がったものは汎用的になったので別パッケージに切り出し`ansicolor`パッケージとして、これを組み込んだ[PR](https://github.com/monochromegane/the_platinum_searcher/pull/33)で取り込んでもらえました。
そのおかげで最新版ではWindowsでもカラフルな検索結果を表示できるので皆さんも使いましょう！