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

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

対話型コンソールアプリ制作初級者に教えたい「CSI」

More than 3 years have passed since last update.

はじめに

わたしはコンソールアプリ上級者ではありません
ただ色々制作していた中でたまたまCSIを知って感動したので書きました。

CSIとは

エスケープシーケンスの一種です。
エスケープと聞いて真っ先に思い浮かぶのは、\nでしょう。
\nはUnix系において改行を意味する非常に簡単なエスケープですが、今回はもう少し込み入った特殊表現を行います。

ちなみに、CSIはControl Sequence Introducerの頭文字です。

なにができるか

代表的なものは
- カーソルの移動
- 画面の消去(カーソル以前の全消去、カーソル以後の全消去も可)
- 行の消去
- 文字の消去
- 矩形単位での文字消去
- 文字スタイル(太字、文字色、背景色など)の設定
- ウィンドウ情報(サイズなど)の制御
などなど…

こちらに制御の種類と方法が全て掲載されています。

動作について

Bashは簡単にエスケープさせてくれないようです参考)。
[追記:コメント情報]
Bashでもエスケープできるようです。echo -eのように-eオプションをつけると、エスケープが適用されます。
また、上記リンクは別の議論でした。訂正させていただきます。

CSIを使ってみる

さて、先の例では改行をするための\nを示しました。
CSIは複数の制御ができるので制御コードは一通りではありませんが、CSIであることを認識させるための接頭辞があります。
それが\e[または\033[ないしは\0x1b[です。

[追記]
bashがエスケープできないと思っていた件、\e[が対応していないだけでした。\033[なら可能です。

eは文字型、033は8進数、0x1bは16進数なので本質的には変わりませんが、eの方が楽でしょう。
CSIは狭義の1エスケープシーケンスの一種です。始めに\eを挿入することでエスケープシーケンスの始まりを伝え、さらに[でCSIであることを伝えます。

この後に何を書くかによってCSIの制御が変わってきます。

CSI制御一覧(一部)

制御文字(スペースは不要) 動作
n A n行(指定がなければ1行)カーソルを上げる
n B n行(指定がなければ1行)カーソルを下げる
n C n文字(指定がなければ1文字)カーソルを進める
n D n文字(指定がなければ1文字)カーソルを戻す
n E カーソルをn行(指定がなければ1行)下の先頭に合わせる
n F カーソルをn行(指定がなければ1行)上の先頭に合わせる
n G カーソルを現在の行のn文字目(指定がなければ1文字目)に合わせる
n; m H カーソルをn行目のm文字目(指定がなければ1行1文字:左上)に合わせる
n J 画面消去(詳細は後述)
n K 行消去(詳細は後述)
n S n行(指定がなければ1行)画面をスクロールして進める
n T n行(指定がなければ1行)画面をスクロールして戻す
n L カーソルのある行の前にn行(指定がなければ1行)挿入
n M カーソルのある行からn行(指定がなければ1行)削除
n P カーソルの位置からn文字(指定がなければ1文字)削除
n P カーソルの位置からn文字(指定がなければ1文字)を空白置換
n ` カーソルを現在の行のn文字目(指定がなければ1文字目)に移動
n a カーソルをn文字(指定がなければ1文字)進める
n d カーソルを現在の位置のn行(指定がなければ1行)上げる
n m SGR(Select Graphic Rendition)パラメータを指定する(詳細は後述)
s 現在のカーソル位置を記憶する
u 記憶したカーソル位置を呼び出す
> 3; a; b; c; d J (b, a)から(d, c)まで矩形消去
> 3; a; b; K 現在の行のa文字目からb文字目まで消去

画面消去(CSI n J)と行消去(CSI n K)の挙動

n 挙動
無指定 カーソルより後ろを画面(行)先頭まで消去
0 カーソルより後ろを画面(行)先頭まで消去
1 カーソルより手前を画面(行)末尾まで消去
2 画面(行)全体を消去

SGRパラメータ(代表的なもの)

n 意味
なし パラメータリセット
0 パラメータリセット
1 太字
2 薄字(広くはサポートされていない)
3 斜体(広くはサポートされていない、反転表示(n=7)になることも)
4 下線
5 点滅:150回/分以内
6 高速点滅:150回/分以上(広くはサポートされていない)
7 反転表示:前景と背景の色が入れ替わる
8 文字を隠す(広くはサポートされていない)
9 取り消し線(広くはサポートされていない)
10 デフォルトのフォント
11–19 (n-10)番目の代替フォントを使用
20 フラクトゥールフォント(ほとんどサポートされていない)
21 太字OFF(広くはサポートされていない), 二重下線(ほとんどサポートされていない)
22 色と強調(太字・薄字)を元に戻す
23 斜体とフラクトゥールを元に戻す
24 下線を取り消す
25 点滅を取り消す
28 文字の隠蔽を取り消す
29 取り消し線を消す
30–37 前景色(要は文字色)を(n-30)番に変更させる(色番号は後述)
38 前景色設定拡張。\e[38;5;nでカラーインデックスを指定できる(0...255)。\e[38;2;r;g;bでRGBを設定できる(各0...255)。
39 前景色をリセット
40–47 背景色を(n-40)番に変更させる(色番号は後述)
48 背景景色設定拡張。\e[48;5;nでカラーインデックスを指定できる(0...255)。\e[48;2;r;g;bでRGBを設定できる(各0...255)。
49 背景色をリセット

なんだこのサポートされてない嵐…

色番号

番号
0
1
2
3
4
5 マゼンタ
6 シアン
7

ざっと各色を表示するとこのような感じです。
スクリーンショット 2016-08-05 10.39.55.png

SGRの使い方

実際にSGR設定を行うときは

echo "\e[31mred\e[m"

とやれば赤文字でredと表示してくれます。

また、

echo "\e[31;43mred&yellow\e[m"

とやれば、赤文字黄背景でred&yellowと表示してくれます。
このようにオプションを;区切りで打っていけば複数のオプションを一度に設定できます。
CSI終了後に予想外の挙動をしないように、必ず最後に\e[mまたは\e[0mでオプションを切りましょう。


  1. 厳密には\nはエスケープシーケンスではありません。狭義にはESC(0x1B)から始まる制御バイト列のことを指すそうです。 

ryoto20707
今はただのシェル芸人
https://ryotosaito.com/blog
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