readlineのバグだった
注意: この記事の内容は間違っています。 こちらを参照してください。
この記事 で Bash のプロンプトが壊れるとか いろいろ言っていたが、いまさらながら調査した。
その結果、プロンプトにエスケープシーケンスが含まれていると、その文字数だけ履歴が残ったり 行の途中で折り返してしたりすることが分かった。 たぶんプロンプトから残りの文字数を計算する部分でエスケープシーケンスが処理されていない?
以下 PoC。
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
int main(void) {
for (;;) {
char *line = readline("\033[1mfoobar\033[0m");
if (line == NULL) {
break;
}
add_history(line);
}
}
これで 22222...
の行まで入れたあとに 2 つ履歴を遡るとこれになる。
特に騒がれてないということはロケールとかフォント依存だったりするのかな……。 コード読んたりするのは明日以降に…。
というか今日プロンプトを2行にしてワークアラウンドしたんだけど、 2 行のプロンプト見にくくてあんまり好きじゃないのでなんとか解消したいんだよなぁ。 まあ太字にするのやめればいいんだけど。