TL;DR
前回作ったところから。
$ mysqlsh -S /usr/mysql/8.0.28/data/mysql.sock -uroot --database d1
root@150-95-141-50 [d1] (READ_WRITE)>
root@150-95-141-50 [d1] (READ_WRITE)> SHOW TABLES;
SyntaxError: Unexpected identifier
( ゚д゚) そう、何も指定していないのでこれはJavaScriptモードなのである。
メインで使う時はSQLモードなので、「SQLモードの時はこのまま、それ以外のモードの時はなんか出したい」と思う。
$ cat ~/.mysqlsh/prompt.json
{
"variables":
{
"read_only_str":
{
"match":
{
"pattern": "OFF",
"value": "%sysvar:read_only%"
},
"if_true": "READ_WRITE",
"if_false": "READ_ONLY"
},
"base_prompt":
{
"match":
{
"pattern": "",
"value": ""
},
"if_true": "%user%@%sysvar:hostname% [%schema%] (%read_only_str%)"
},
"mode_based_prompt":
{
"match":
{
"pattern": "SQL",
"value": "%Mode%"
},
"if_true": "%base_prompt%> ",
"if_false": "%base_prompt%\n%Mode%> "
}
},
"prompt": { "text": "%mode_based_prompt%" }
}
$ mysqlsh -S /usr/mysql/8.0.28/data/mysql.sock -uroot --database d1
root@150-95-141-50 [d1] (READ_WRITE)
JS> \py
Switching to Python mode...
root@150-95-141-50 [d1] (READ_WRITE)
Py> \sql
Switching to SQL mode... Commands end with ;
Fetching table and column names from `d1` for auto-completion... Press ^C to stop.
root@150-95-141-50 [d1] (READ_WRITE)>
うん、想像通りに動いてはいそう。
はい次、 READ_ONLY の場合は赤文字とかにしたい。
$ cat ~/.mysqlsh/prompt.json
{
"variables":
{
"read_only_str":
{
"match":
{
"pattern": "OFF",
"value": "%sysvar:read_only%"
},
"if_true": "READ_WRITE",
"if_false": "READ_ONLY"
},
"read_only_color":
{
"match":
{
"pattern": "OFF",
"value": "%sysvar:read_only%"
},
"if_true": "green",
"if_false": "red"
},
"base_prompt":
{
"match":
{
"pattern": "",
"value": ""
},
"if_true": "%user%@%sysvar:hostname% [%schema%] (%read_only_str%)"
},
"mode_based_prompt":
{
"match":
{
"pattern": "SQL",
"value": "%Mode%"
},
"if_true": "%base_prompt%> ",
"if_false": "%base_prompt%\n%Mode%> "
}
},
"prompt": { "text": "%mode_based_prompt%", "fg": "%read_only_color%" }
}
長くなってきた…。
$ mysqlsh -S /usr/mysql/8.0.28/data/mysql.sock -uroot --database d1 --sqlc
Error loading prompt theme '/home/yoku0825/.mysqlsh/prompt.json': Error loading prompt theme: Invalid color value %read_only_color%
あれ、食えない…。
固定文字列で “red” とか “green” って入れると通るんだけどなあ。
色々納得はいかないけれど、何パターンかトライアンドエラーで頑張ってようやく class
と segment
の招待に行きついた。
classは俺が思っているclassとはちょっと違って text
や fg
とかの要素を全部持たせてしまうものみたいな気がする(他のサンプルを見るに)
ということは、表示用の要素がそのまま詰まった変数みたいなものってことになる。まあ、そういうものだと思うことにしよう。。
そして segments
の方は、理屈はわからないけれどどうも「 segments
に列挙されたものを順番に並べて、最後に prompt
に指定されたものを添えることでプロンプトを作る」みたいになっている。
たとえば segments
から先だけを
"segments":
[
{ "classes": ["%read_only_str%"] },
{ "text": "%mode_based_prompt%" },
{ "text": "hogehoge" },
],
"prompt": { "text": "pro" }
みたいにすると、
$ mysqlsh -S /usr/mysql/8.0.28/data/mysql.sock -uroot --database d1 --sqlc
READ_ONLY root@150-95-141-50 [d1] (READ_ONLY)> hogehogepro
みたいになる。
こういうものだとわかれば、まあ、
class
に表示したいものを詰めるsegments
にそれを列挙する- 今までさんざん頑張ってきたけど、
prompt
はたぶんおまけ
こういう風になるだろうか…。
話がひっくり返るけれど、 segments
の中で class
を展開するには
{ "classes": ["%read_only_str%"] },
こんな風にすると、カスタム変数 "class": "read_only_str"
に対応する要素が展開される、っぽい。
$ cat ~/.mysqlsh/prompt.json
{
"variables":
{
"read_only_str":
{
"match":
{
"pattern": "OFF",
"value": "%sysvar:read_only%"
},
"if_true": "READ_WRITE",
"if_false": "READ_ONLY"
},
"base_prompt":
{
"match":
{
"pattern": "",
"value": ""
},
"if_true": "%user%@%sysvar:hostname% [%schema%] "
},
"mode_based_prompt":
{
"match":
{
"pattern": "SQL",
"value": "%Mode%"
},
"if_true": "%base_prompt% ",
"if_false": "%base_prompt%\n%Mode% "
}
},
"classes":
{
"READ_ONLY":
{
"text": "(READ_ONLY)",
"fg": "red"
},
"READ_WRITE":
{
"text": "(READ_WRITE)",
"fg": "green"
}
},
"segments":
[
{ "text": "%mode_based_prompt%" },
{ "classes": ["%read_only_str%"] },
],
"prompt": { "text": "> " }
}
というわけでこうすると
こうなった。