過去のブックマークの消化をしていると、次のようなページを確認しました。
これで目をひいたのが Reline のトコ。Unicode の曖昧文字幅:環境によって文字の幅が2セルか1セルか分からない文字の幅を計測するコードです。
行頭へ移動してから、▽ (U+25BD) を表示した後、カーソル位置を ESC[6n
で取得して幅を計測するという方式を使っているとあります。
カーソル位置を取得するANSIエスケープシーケンス ESC[6n
の存在は一応知っていたんですが、大掛かりすぎて実用にならないと勝手に思い込んでいました。おもしろいなーと思って、自分も Go言語で書いてみました。
文字幅を得る関数 AmbiguousWidth を提供するとともに、その過程でカーソル位置を得る処理も Request という関数にしました。パッケージは汎用性のある Request の方を主役にしましたが。
ちょっと迷った点:
ESC[6n
を送信する先を標準エラーにするか、パラメーターにするか?
→ パラメータにしたESC[6n
を送信した後、ESC[(行位置);(桁位置)R
を受信するため、端末を RAWモードにするコードを含めるか否か。含める場合 "golang.org/x/term" を使うか、それのラッパーの"github.com/hymkor/go-windows1x-virtualterminal/keyin" にするか?
→ 含めないようにした ( Example で、呼び出し元で RAW モードにするコード例を出した )
これ ESC[(行位置);(桁位置)R
に加え、改行コードも端末側から出してくれたら、RAW モードに切り替えなくても済むのに、なんでそういう仕様にしたんでしょうねぇ > VT100