« 2012年11月 | トップページ | 2013年1月 »

2012年12月

2012年12月27日 (木)

viにおいてbackspaceが効かないのはどうしてか?

viにおいてbackspaceが効かないのはどうしてか?

Time-stamp: "Sat Feb 25 13:03:28 JST 2012"

viのコマンドモードにおけるbackspaceはカーソルを前(左)方向に一文字す つ遡る方向に動かす。なお、spaceはスペースを書き込むのではなくカーソ ルを後ろ(右)方向に一文字ずつ動かす。手動式タイプライターにおけるス ペースバーは印字位置を右に一文字分だけ進める働きをする。紙に印字する のであるから活字(スペース)を仕込んだアームを叩きつける必要はない。紙 を一文字分だけ右にずらせばよい。また、backspaceは既に印字した直前の 文字の上に印字位置を戻すだけである。手動式タイプライターにおける backspaceには前の文字を消すという機能はない。

spaceもbackspaceも手動式タイプライターの時代から存在するキーである。 ただし、キードップにbackspaceという刻印はなくて左向きな矢印が刻まれ ていた。left arrowキーと呼ばれたらしい。windowsなパソコンにおいて、 カーソルの後ろ(直下)の文字を消すdeleteキーは、手動式タイプライターに 存在しない。紙に印字したものをキー操作で消すことはできない。電動式タ イプライターではインクリボンを修整テープで置き換えて訂正できる機種が あったらしい。

unixの機械におけるdeleteはカーソルの前の文字を消すeraseキーとして使 われることが多い。昔の機械は、コマンドラインへの打ち込み文字を編集す ることができない仕様であった。カーソルを、既に打ち込み済みの文字の上 を通り越して遡る方向に動かすことができない。末尾の文字から一文字ずつ 前方向に消すことしかできない。

windowsのパソコンを使う人にとってbackspaceはカーソルの前の文字を削除 するものと思うのが普通である。viにはこの常識が通用しない。奇妙なのは viのインサートモードにおけるbackspaceの働きである。打ち込み途中で改 行文字を入れる前ならbackspaceでカーソルの前の文字を消すことができ る。既に打ち込み済みの行にカーソルを戻したときのbackspaceは無効であ る。ただし、移動したカーソル位置から書き加える文字にはbackspaceが効 く。また打ち込み中の行頭までは消せるけれど、それより前の行は消せな い。

なお、deleteキーはviのコマンドモードでもインサートモードでもカーソル の後ろ(直下)の文字を消す。ただし、改行文字は消せない。viの元祖はライ ンエディターであり行単位で編集する流儀が残っている。改行文字を消して 二つの行を連結することができない。二つの行の連結にはコマンドモードで J(joint)コマンドを使う。

windowsに慣れた者には使いにくいviにおけるbackspaceを、windowsと同じ 使い勝手に変更する方法はネット上でみつかる。どうしてviのbackspaceが そのようになっているかの情報がない。そうなったには訳があるはずであ る。それを知りたい。

viのインサートモードにおけるbackspaceが、windowsパソコンの使い勝手と 同じ働きをしないのは、そもそもviはbackspaceやdeleteを使わない設計に なっているのではないかと思い付く。viのバイブル的存在であるオライリー 刊の「入門vi」(Learning the vi Editor)の初めのほうを読んでも backspaceやdeleteは出てこない。viのコマンドモードで小文字の「x」を押 すとカーソルの(後に)ある文字を消し、大文字の「X」ならカーソルの(前 に)ある文字を消すとある。ならばbacspaceやdeleteは不要ということにな る。

昔のviではbackspaceとdeleteが効かなかったという記事をネットで見つけ た。うーん、やっぱりそうなのかと思う。

私がviを使い始めたころ、文字の削除に「Backspace」キーや「Delete」 キーは使えなかったと記憶しています(実際、「Windowsでviを動かす」で 紹介した「JVim for Windows」ではそれらのキーが使えません)。

viのインサートモードではカーソルの前後の文字を消すために「x」や「X」 は使えない。エックスの文字そのものが入力されてしまう。それがインサー トモードというものである。一文字消すためにescによりコマンドモードに 移行して「x」や「X」を使い、再びインサートモードに復帰するのは面倒で ある。そのためインサートモードではdeleteやbackspaceが使えるように してあるのだろう。

手元にあるwindowsパソコンにインストールしたvimのコマンドモードで backspaceを押すとカーソルが行の左(前)方向に動き、spaceで行の後(右)方 向に動く。これは手動式タイプライターと同じ動きである。コマンドモード のdeleteではカーソル下の文字が消える。元に戻すにはただちに「u」 (undo)を打つ。

手動式タイプライターにおいて、spaceは何も印字せずに印字位置を右に一 つだけ進める。そしてbackspaceは何も印字せずに印字位置を左に一つだけ 戻す。それらはタイプ用紙に文字を印字するものではない。何も印字しない ことはスペースを印字したことになる。backspaceはspaceによって印字位置 を進めすぎたのを戻す場合か、または既に印字した文字の上まで戻すために 使う。もし印字済みの文字に誤りであったとき「x」を重ね打ちしてキャン セルの表示とする。見栄えは悪くて正式文書にはならないが下書きなら許せ る。そのようなためにもbackspaceを使う。これら二つのspaceとbackspace は手動式タイプライターに備わっていた。

viのコマンドモードにおける一文字消去コマンドを「x」にしていること は、手動式タイプライターにおいて「x」の重ね打ちで誤字抹消(跡形は残 る)ことに由来するものである。

その昔のパソコン通信の時代に会議室のログを読むソフトのpageupと pagedownにそれぞれbackspaceとspaceが割り当ててあった。読み進めるには キーボードの手前の押しやすい位置にあるスペースキーでよかったのが便利 だった。巻き戻すbackspaceは画面上の文字を消してしまいそうな気がして 押すのをためらう。文字キー操作が直接に画面への入力に結びつかないソフ ト(あるいはそのような状態にある場合、例えばviのコマンドモード)では進 める、戻す操作にこれら二つのキーを割り当てることがある。

電動タイプライターでは印字用の黒色インクリボンとは別に白色の訂正用の インクリボンを備えてインクリボンを切り替えできたらしい。誤字の上へ backspaceで印字位置を戻し誤字と同じ文字を再び打つことで消すことがで きる。そのあとで正しい文字を同じ位置に打ち込む。

viにおけるbackspaceキーの挙動に関しては「:help 'backspace'」に解説が ある(クォートなしでは有用な情報がない。option.txtに書かれている)。 「:set all」でデフォルトを確認すると「backspace=」となっている(何も 設定されてない)。vi互換ということらしい。

問題は少し複雑である。インサートモードでviへ入力中の行ではbackspace が効く。しかしenterを押して次の行にカーソルが移った後で元の行にカー ソルを戻してもbackspaceは効かない。enterを押すのではなくて入力中の行 からカーソルキーを他の行に移しても元の行ではbackspaceが効かなくな る。すでに入力済みの行に他の行からカーソルを戻した状態でもbackspace は効かない。

このことはwindwowsのコマンドラインからコマンドを打ち込むとき backspaceが効くことに似ている。コマンド入力ではbackspaceで打ち込み文 字を全部消せる。enterを押してコマンドを実行したら消すことができな い。

viのコマンドモードとインサートモードを分けて観察する必要がある。コマ ンドモードでのbackspaceはカーソルを前に動かすだけである。deleteは カーソル下の文字を消す。インサートモードのdeleteはカーソル下の文字を 消す。ややこしいのはインサートモードにおけるbackspaceの働きである。

初期のテレタイプの機械にはbackspaceに相当するキーはなかったようだ。 次の時代はbackspace(left arrow)に相当するキーがrubout(ラブアウト) だったらしい。そしてコンピュータ方面ではdeleteになったのだろう。現在 のwindowsパソコンでは、カーソルの前の文字を消すのがbackspace、カーソ ルの後の文字を消すのがdeleteになっている。しかしmacのほうではdelete がカーソルの前の文字を消すunixな流儀になっていると聞く。

ところでカーソルとプロンプトはどう違うのだろうか。私は次のように考え る。カーソル(cursor)の語源はrunnerであり、古くは計算尺で使われた。左 右そしてパソコンの画面では上下にもカーソル移動キー(矢印キー)で動かせ るものを思い浮かべる。コマンドプロンプトにおけるプロンプト(prompt)は 刺激してさせる、駆り立てる、そそのかす意味がある。コマンドを入力すべ き場所を知らせるイメージになる。

コマンドラインは真っ黒な画面にポツンと例えば「c:\>_」が表示されて末 尾のアンダーラインが点滅(blink、ブリンク)している。キーボードから文 字を打ち込むとブリンクするアンダーラインの場所にその文字が表示され て、アンダーラインは打ち込んだ文字の直後に移動する。

最新のwindowsのコマンドプロンプトでは次の文字の打ち込み場所を指示す るアンダーラインをカーソルキーで「c:>」の直後の文字まで動かすことが できる。古い時代のms-dosのコマンドプロンプトではアンダーラインを動か すことはできなかった(と記憶している)。矢印キーで左右に動かせないコマ ンドラインの文字入力位置を示すアンダーライン記号をカーソルと呼ぶのは しっくりこない。

手動式のタイプライターは打ち込み誤りを修正できない。いったん紙に印字 したら消すことはできない。大昔のコンピュータのコマンドラインも一発勝 負で打ち込むものだった。もし打ち間違えてもeraseキーで直前の一文字を 消すことしかできない。相手が紙でないので最低限の敗者復活手段が用意し てあった。プロンプト記号まではご破算にできる。文字打ち込み位置を表す アンダーラインを、既に打ち込んでいる文字を通り越して遡らせることはで きないし文字列の途中を修正することもできない。

unixな世界ではeraseキーとしてdelete割り当てが普通らしい。eraseキーと はカーソルの直前の1文字を削除するキーのことである。実はmacもunix流儀 らしい。windowsのほうが特殊なのかもしれない。

コマンドラインに打ち込んだものはeraseキーで末尾から一文字ずつ消すこ としかできない。これはコンピュータがそのように(安上がりに)作られてい たからである。プロンプトへの入力文字の末尾にくっつくアンダーラインを 前に動かして編集可能にするにはそのための仕掛けを準備しなければならな い。それを処理するために機械の能力を殺ぐようではいけない。コマンドラ インでカーソルを自由に動かして編集(コマンドライン編集)したいのは人間 の都合である。初期の機械に人間の便利を考える性能的余裕がなかったので あろう。

viのインサートモードでのbackspaceが効かないのは既に入力済みの行で効 かないということである。現在打ち込み中で改行まえならカーソル直前の文 字を消すことができる。これはコマンドプロンプトにならった(真似た)もの だろう。backspaceが効く場面と効かない場合があるので頭がこんがらか る。

| | コメント (1) | トラックバック (0)

« 2012年11月 | トップページ | 2013年1月 »