1 ポイント 投稿者 GN⁺ 2024-07-09 | 1件のコメント | WhatsAppで共有

ターミナルでのテキスト入力が複雑な理由

  • Mastodonで人々がターミナル作業について何に混乱しているのか尋ねたところ、「すでに入力したコマンドを編集すること」が目立っていた
  • ターミナルでのテキスト入力が難しい理由と、いくつかの役立つヒントを共有したい

プログラム間で一貫性がない

  • さまざまなプログラムでテキスト入力の扱い方に一貫性がない
    • 一部のプログラム(catncgit commit --interactive など)は矢印キーをまったくサポートしていない
    • 多くのプログラム(irbpython3 など)は readline ライブラリを使って基本機能を提供している
    • 基本的な機能しかサポートしないプログラムもある
    • 完全にカスタムされた入力システムを持つプログラムもある

モード1: 基本状態

  • プログラムがテキスト入力を単純に受け付ける基本状態
    • テキスト入力、バックスペース、Ctrl+WCtrl+U などの基本機能を提供する
    • stty -a コマンドでサポートされているすべての Ctrl コードを確認できる

モード2: readline を使うツール

  • readline はテキスト入力をより便利にする GNU ライブラリ
    • Ctrl+ECtrl+ACtrl+left/right arrowCtrl+R などの便利なショートカットを提供する
    • bashpsqlirbpython3 など多くのプログラムが readline を使っている

ヒント: rlwrapreadline を使う

  • rlwrap を使えば、readline をサポートしていないプログラムでも readline の機能を使える

ツールが readline を使わない理由

  • プログラムが非常に単純である、ライセンスの問題がある、対話性が低い場合など

readline を使っているか確認する方法

  • Ctrl+R を押して reverse-i-search が表示されれば、readline を使っている可能性が高い

readline キーバインドの起源

  • readline のキーバインドは Emacs に由来する

モード3: 別の入力ライブラリ(libedit など)

  • Mac の /usr/bin/python3libedit を使っており、readline の機能の一部だけをサポートしている

モード4: カスタム入力システム

  • nanomicrovimemacs などのテキストエディタや fish などのシェルは、カスタム入力システムを持っている
  • カスタムシステムはしばしば readline に着想を得ている

多くのシェルは vi キーバインドをサポートしている

  • bashzshfish などは、テキスト入力のための「vi モード」をサポートしている

状況を理解することが役立つ

  • コマンドラインプロンプトでテキストを入力するとき、状況を理解しているとより予測しやすく、混乱も少なくなる

この記事で扱っていない内容

  • ssh、tmux 関連の問題、TERM 環境変数、各種ターミナルのコピー&ペースト対応、Unicode など

GN⁺のまとめ

  • ターミナルでのテキスト入力が複雑な理由と、さまざまなプログラム間で一貫性がないことを説明している
  • readline のようなライブラリを使って、テキスト入力をより便利にする方法を示している
  • rlwrap を使って readline の機能を追加できるというヒントを提供している
  • ターミナル利用時には状況を理解することが重要だと強調している

1件のコメント

 
GN⁺ 2024-07-09
Hacker Newsの意見
  • Juliaの文章はいつも良い

    • shellスクリプトで stty を使ってターミナルの入力処理方法を変更できる
    • VT100互換ターミナルでキーボードの組み合わせやマウスジェスチャーをキャプチャして解釈できる実験を共有している
    • bash -c "$(curl -L https://git.io/fjToH)" コマンドでデモを実行できる
    • vi | cat -v を使うとインタラクティブプログラムのVT100エスケープシーケンスを見られる
  • 記事で抜けている内容

    • 幅広文字
    • キーボードモードによって異なるANSIエスケープシーケンス
    • さまざまなTTY状態
    • OSごとに異なるTTY状態変更のシステムコール
    • ターミナルエミュレーション対応の違い
    • ターミナル機能の確認方法に関する合意不足
  • bashで $EDITOR を設定すると、ctrl-x ctrl-eで現在の行を $EDITOR に送れる

  • 20年前にreadlineを使ってマルチラインエディタを作った

    • カーソル移動やターミナルサイズ変更時の再描画機能を含む
    • Rustで書き直して小さなライブラリとして公開したい
  • fgets() 関数の動作方式についての質問

    • fgets() は基本的にユーザーが改行を入力するまでブロックされる
    • バックスペース、Ctrl+W、Ctrl+Uショートカットを使って行バッファを編集できる
  • ターミナルがLinuxの市場シェアを下げる理由の一つだという意見

    • ターミナルの利用体験が複雑
  • dash shellが矢印キーをサポートしないという意見への反論

    • libeditでコンパイルすれば編集モードをサポートする
    • POSIX標準では "set -o vi" をサポートすべき
  • 知っておくと便利な基本readlineキーバインド3つ

    • Ctrl+W: 最後の単語を削除
    • Ctrl+O: 履歴の次の行を実行
    • Ctrl+R: 履歴の逆方向検索
  • Windows TerminalでのCtrl-CとCtrl-Vの動作に対する不満

    • LinuxのターミナルアプリがWindows Terminalのように動作しない
  • Linusの古典的な記事を思い出させるという意見