制御コード
# format
Esc[xxxx
\ `--- Sequences
`--- Escape
# Set Graphics Mode:
Esc[Value;Value;Valuem
`--- TextAttribute: 0-8
ForegroundColor: 0-255
BackgroundColor: 0-255
※ 8, 16, 256 色の指定方法で変わる
# Cursor:
Esc[ValueA/B/C/D
\ `- A CursorUp/B CursorDown
\ /C CursorForward/D CursorBackward
`--- numboer of line or column
色と装飾
256色
// ForegroundColor
print(fmt.Sprintf("\u001b[38;5;%dm %-4d", code, code))
// BackgroundColor
print(fmt.Sprintf("\u001b[48;5;%dm %-4d", code, code))
装飾
println("\u001b[1m BOLD \u001b[0m\u001b[4m Underline \u001b[0m\u001b[7m Reversed \u001b[0m")
import "fmt"
func main() {
colors := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
println("\u001b[31mHelloWorld")
println("\u001b[31mForeground")
for _, n := range colors {
for _, m := range colors {
code := 16 * n + m
print(fmt.Sprintf("\u001b[38;5;%dm %-4d", code, code))
}
Println("\u001b[0m")
}
println("\u001b[31mHelloWorld")
for _, n := range colors {
for _, m := range colors {
code := 16 * n + m
print(fmt.Sprintf("\u001b[48;5;%dm %-4d", code, code))
}
println("\u001b[0m")
}
println("Text Decoration")
println("\u001b[1m BOLD \u001b[0m\u001b[4m Underline \u001b[0m\u001b[7m Reversed \u001b[0m")
}
Cursor
数字
func loading(inc, max int) {
num := 0
for num <= max {
print("\u001b[1000D")
time.Sleep(500 * time.Millisecond)
print(" ", num, "%")
num += inc
}
}
プログレスバー
func barLoading(inc, max int) {
num := 0
charWidth := 25
barSize := 4
for num < max {
time.Sleep(100 * time.Millisecond)
width := (num + 1) / barSize
bar := "[" + strings.Repeat("#", width) + strings.Repeat(" ", (charWidth-width)) + "]"
print("\u001b[1000D" + bar)
num += inc
}
}
複数行
type Progress struct {
Percent int
Max int
}
func (p *Progress) Up(n int) {
if p.Done() {
return
}
p.Percent = int(math.Min(float64(p.Percent+n), float64(p.Max)))
}
func (p *Progress) Done() bool { return p.Percent >= p.Max }
func (p *Progress) Bar(charWidth int) string {
width := int(math.Min(float64(p.Percent)/float64(p.Max)*float64(charWidth), float64(p.Max)))
//print("Max>>", p.Max, ",Per:", p.Percent, ",Width>>", width)
return "[" + strings.Repeat("#", width) + strings.Repeat(" ", (charWidth-width)) + "]"
}
type RunProgress []*Progress
func (p RunProgress) Unfinished() RunProgress {
var rp RunProgress
for _, ps := range p {
if !ps.Done() {
rp = append(rp, ps)
}
}
return rp
}
func (p RunProgress) Done() bool { return len(p.Unfinished()) == 0 }
func (p RunProgress) Bar(charWidth int) {
for _, ps := range p {
println("\u001b[1000D" + ps.Bar(charWidth))
}
}
func barsLoading(count, max int) {
charWidth := 25
inc := 10
rps := make(RunProgress, count)
for i, _ := range rps {
rps[i] = &Progress{0, max}
}
rand.Seed(time.Now().UnixNano())
println("Count:", count)
rps.Bar(charWidth)
for !rps.Done() {
time.Sleep(100 * time.Millisecond)
for _, ps := range rps.Unfinished() {
ps.Up(rand.Intn(inc))
}
// move cursor
print("\u001b[1000D")
print(fmt.Sprintf("\u001b[%dA", count))
// write
rps.Bar(charWidth)
}
}
レコード
上記のgif は ttyrec, termrec で作っているのでここはasciinema を貼り付ける
※ script タグだと左にプレビューしないので気をつけよう
ttyrec
# record
$ ttyrec record.file.name
# play
$ ttyplay record.file.name
# to gif
$ ttygif -in record.file.name -out record.gif
asciinema
# record
$ asciinema rec command.cast
# play
$ asciinema rec command.cast
# publish to asciinema (before run asciinema auth)
$ asciinema upload command.cast
termrec
# record
$ termrec -f ttyrec rec.filename
# play
$ termplay -f ttycec rec.filename
# to git
$ ttygif -in rec.filename -out command.gif
画像表示
Terminal で解決する
Terminology
# tycat <image file>
$ tycat free.png
※ terminal の recorder では無理
iTerm2
macOS じゃないとだめなので省略
Sixel
セットアップなどはSixel 情報 - ダメ出し Blogから深堀してください
動作確認
# img2sixel <file name>
$ img2sixel free.png
動作確認では xterm は動いている様子だが img2sixel
では表示されず
Recap
- Windows 10 を買おうっと
Reference
制御コード関連
レコード関連
ターミナルで画像表示関連