brushing up, input mode #2

まず backspace、つまりコントロールコード \u0008 を考える。キーボードから “ifoa^Ho^[” と打つと:

  • 入力テキストは “foa^Ho”
  • 入力コマンドは “ifoa^Ho^[“
  • undo ログは 3 つのアイテムを含んだクラスタ: “桁 0 へ ‘foa’ の挿入”, “桁 3 から後方に 1 文字削除”, “桁 2 へ ‘o’ の挿入”

また、キーボードから “i^H^H^[” と打った場合は:

  • 入力テキストは “^H^H”
  • 入力コマンドは “i^H^H^[“
  • undo ログは “桁 0 から後方に 2 文字削除”

となる。なお vim の場合、^H と backspace を内部的に区別しているのだが wasavi ではそこまではしない。どちらも \u0008 として扱う。

追記: カーソルが 1 行 1 桁、つまりバッファの先頭にあった場合に上記ストロークを打った場合は、

  • 入力テキストは “”
  • 入力コマンドは “i^[“
  • undo ログは生成されない

となる。この状態で . コマンドを実行するとカーソルが左に 1 文字移動するように見えるのは、つまり “i^[” の副作用だ。

次に delete。これに対応するコントロールコードは、wasavi においては ^_、つまり 0x7f だ。”d” の上にカーソルがある状態でキーボードから “i^_b^[” と打てば:

  • 入力テキストは “^_b”
  • 入力コマンドは “i^_b^[“
  • undo ログは 2 つのアイテムを含んだクラスタ: “桁 0 から前方に 1 文字削除”, “桁 0 へ ‘b’ の挿入”

となる。考え方は backspace と同じ。

一方、特殊キーはどうか。input モードにおける特殊キーというのはつまり、カーソルを移動させるキー: 矢印キー、Home、End、PageUp、PageDn のことだ。そして input モード中のカーソル移動というのは、実はいったん command モードへ抜け、vi コマンドによりカーソルを移動させ、再度 input モードに入るという手順と意味は同じなのだ。したがって最初の input モードで入力した文字列と次の input モードで入力した文字列はそれぞれ独立したものとなる。これは undo ログも同じ。”ifoo” 左矢印 “bar^[” と入力した場合、左矢印キーを押した時点でまず

  • 入力テキスト: “foo”
  • 入力コマンド: “ifoo”
  • undo ログ: “桁 0 から ‘foo’ を挿入”

という結果が生成されるが、直後に新しい input モードのセッションが開始する。undo ログはリスト構造であり、独立した 2 つのログが最終的に生成されるが、入力テキストと入力コマンドはそうではないため上書きされ、最後のセッションの結果が残る。つまり最終的に

  • 入力テキスト: “bar”
  • 入力コマンド: “ibar^[“
  • undo ログ: 2 つのクラスタ
    1. “桁 0 へ ‘foo’ を挿入”
    2. “桁 2 へ ‘bar’ を挿入”

となる。undo ログが独立しているというのは、u を押すとまず bar が削除され、さらに u を押すと foo が削除されるということだ。なお、undo ログで桁位置も記録しているが、挿入系と削除系で意味合いが違う。前者は入力を開始した位置、後者は現在のカーソル位置だ。入力開始位置は input モードのセッション中は不変だが、backspace / delete で新規セッションが強制開始した場合は入力テキスト・コマンドと共に初期化する必要がある。

Leave a Reply

Your email address will not be published. Required fields are marked *