標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

ターミナル用CSVエディタ Csvi:大躍進の裏で起きた入力キーシーケンス分断問題

Csvi の大躍進

20〜30 あたりだった、GitHub の Stars が 2025年末時点で 88 、2026年2月には171 まで上がりました。宣伝が効を奏したようです。

特に Reddit 投稿が大きかったようです。これは mattn 先生の

https://x.com/mattn_jp/status/2010536235459362883:

某ブログサービスの翻訳のデフォルト設定の是非の話は別の話として置いとくとして、昔からずっと海外 OSS に関わって来た隅っこの1人としては、日本人が発してる技術情報や OSS には優秀な物も沢山あるのに、海外勢から読まれずに使われずに消えてく物が多すぎるんですよ。読み流されるならまだしも、そもそも読まれもしてない。
僕はよくOSS 作ったら Reddit に宣伝ポストするけど、アレやるとやらんのでは海外勢からのリーチが全然違う
もっと読まれる流れを作るべきだと思うし、もし SNS で逆張りして文句言ってるだけなのであれば(そうではなく信念がある人や自分で英訳したい人は別として)、今一度考えたほうがいいんじゃないかと個人的に思ってる。(前述の通りデフォ設定の話はしていない)

という御発言を踏まえたものでしたが、いざやってみたら「ほんまや…」という有様でした。

この手の投稿はやり直しが多分できませんので(嫌われたらリカバリが難しい)、慎重に行いました。ChatGPT に助けてもらいましたが、あくまでアドバイスや英語の支援とし、内容の決定・判断は自分で主体的に行うことに努めました。

(AI を使ったことは伏せるべきではないかとも思ったのですが、気を付けるべき点をどうやって知ったかを記すとなると避けては通れません。「丸投げ」ではなく自分の意思がきっちりと入っていることを強調すれば理解が得られることを期待し、その上で正直に書くようにしました)

  1. Reddit に対して、ツールの宣伝を、どこに、どうすべきか、ChatGPT にガイドしてもらう。曰く
    • Csvi のようなコマンドラインツールの宣伝ならば r/commandline がよい
    • r/commandline はツール紹介の場なので、くどくどと自己紹介や経緯など書かず、まずは端的にツールの特徴一覧とスクリーンショット、GitHub の URL だけを書けばよい。URL は GitHub Pages よりは GitHub 本体の方がよい
  2. 投稿内容は慎重に作成
    • まずは自分で投稿内容の素案を作る。いきなり英語はしんどいので、日本語で箇条書き
    • それを ChatGPT に英語化してもらう
    • その英語を読んで、自分の意図どおりかチェック
      • どういう意味か分からないものは GPT 自身に聞く
      • GPT は油断をすると冗長だったり、ズレた表現をしがちなので、違っていたら直してもらう
      • アポストロフィーやダッシュ、絵文字など GPT が使いがちな文字は他の表現に置き替える ( 使うなと言っても忘れた頃に使われ気味なので、チェックは欠かせない)
  3. 投稿後は反応すべてに対して誠実に返信
    • ニュアンスの解釈がたいへんだが、そこは GPT にいちいち解説してもらう。
    • 返信内容づくりは投稿内容作成と同様に GPT とのキャッチボール

結果は Upvotes 158, Downvotes 0, Comments 22 と期待以上のものとなりました。

これの反響か、Untitled Linux Show: More Time to Bake という、Linux の動画ニュースでも取り上げられました(238回;1月18日分)。00:53:04 のあたりですね (AI による文書おこし)

入力キーシーケンスの分断問題

ところで、00:54:20 からRob Campell さんから、このような指摘があります。

I'm not sure if I found a bug. But when I navigate around with the arrows, every once in a while, when I push the back arrow, it was deleting the whole line. So I'm going to dig into that and maybe submit a bug for that if I figure out. Because I don't know why it was doing that for me. So if you use this right now, use the HJKL to navigate around.

(機械翻訳) バグを見つけたかどうかはわかりません。しかし、矢印を使って移動するとき、時々、戻る矢印を押すと、行全体が削除されてしまいました。それで、私はそれを掘り下げて、もしわかったらバグを提出するつもりです。なぜなら、なぜそれが私にそのようなことをしたのかわからないからです。したがって、今これを使用する場合は、HJKL を使用して移動してください )

左矢印キーのキーは\x1B[D という複数バイトのシーケンスなんですが、入力に遅延が発生すると、読み切れなかった D を行削除と誤認してしまうという問題でした。

これに対し、v1.21.1 で次のような対応を行いました。

さて、この入力キーシーケンスが分断されて誤認識してしまうという問題は以前に NYAGOS + ConEmu でも時折、ヒストリ参照で「なぜか[A が入力される」という形で報告がありました。

つまり、事は Csvi 単体ではなく、自分の nyaosorg エコシステム全体にもあったということです。そこで、一文字キー入力のアダプターパッケージ go-ttyadapter にメスを入れることにしました。

"go-ttyadapter" は以下のようなサブパッケージを提供しています。

  • "tty8" - "github.com/mattn/go-tty" のラッパー (Windows 7,8 でも動く)
  • "tty10" - "golang.org/x/term" のラッパー
  • "auto" - オートパイロット機能を提供する。主にテスト用途

これらのラッパーは3種類の一文字キー入力パッケージに対して、同一の共通 interface を提供するものです。

type Tty interface {
    Open(onResize func(int, int)) error // 初期化: 引数は画面サイズが変った時に呼び出すコールバック関数。nil可能
    GetKey() (string, error) // 1文字キー入力
    Size() (int, int, error) // 画面サイズを取得
    Close() error
}

既存動作を替えるのはよくないので、今回は新パッケージを二つ加えました。

  • "tty8pe"
  • "tty10pe"

これらは tty8, tty10 に対して、\x1B などを受信したら後続するデータを必ず待つという動作を加えたものです。副作用として

  • Esc キー単品入力が受信不可になる
  • Esc + 1文字と、Alt + 1文字が等価になる

という変化を及ぼすため、キー入力体系全体の見直しが発生します。それはプログラムコードだけでなく、README などドキュメントなどにも及びます。

  • go get github.com/nyaosorg/go-ttyadapter を実行する
  • import 先を "github.com/nyaosorg/go-ttyadapter/tty8" → "github.com/nyaosorg/go-ttyadapter/tty8pe" に切り替え
  • できなくなった、Esc キー単体入力を Ctrl+G など別のキーにふりなおす
  • README.md , README_ja.md などの記載を改める
  • バージョンを更新する
  • go-ttyadapter を利用しているパッケージを import していたら、それも更新する

これを全部のパッケージでやります。うへぇ

こうして、1月13日の Reddit 投稿にはじまったフィーバーは 2月14日にようやく終わったのです…長かった(まぁ、フィーバーいうても、ほとんど独りで踊っていた感じなんですけどね)