2カラムのエディタ

http://homepage3.nifty.com/mogami/diary/d0901.html#162 に反応して。

ありますよ。
あと私が知ってる範囲では VimVisual Studio 6 がその系統です。

Vim は完全に分割し放題で、2 カラムだろうが 3 カラムだろうができますし、さらにそのうちの1 カラムを上下に三分割とかもいけます。そんなに細かくは使いませんけど。でも縦横二分割で同時に4ファイルぐらいはしょっちゅう開いてます。

VS6 のは sash window っていうのかな、エディタ画面の隅っこをドラッグすると区切りが出てきて二画面になりました。縦横に一本ずつあって最大4ペイン同時表示できたはず。

そういえば Emacs はよく上下で分割してるのを見るけど、縦で2カラムになるのは見たことないなあ。

予言 (別名: Firefox のプラグイン入れるのめんどすぎて妄想が膨らむ)

FirefoxEmacs には Subversion が組み込まれます


嘘です。でも、カスタマイズ性の高いアプリケーション (プラグインという概念があるもの) は、バージョン管理システム的なものを内包するようになります。


現在の大概のwebブラウザには、お気に入りのエクスポート/インポートする機能がありますが、まずあれが発展していきます。インストール直後の状態から、加えられた変更(プラグインのインストール、設定の変更、etc.)とそのデータを全て維持し、現在の状態までの差分をダンプして出力できるようになります。

これにより環境の移行がすばらしく楽になります。移行元でアプリケーションを立ち上げてダンプを出力して、移行先でダンプから復元するだけ。ボタン一発。


そうすると次の流れとして「アプリそのものをサーバ上に置いておけばいちいちダンプしたデータを持って回らなくてもいいじゃん」という話になります。この時、アプリケーションのデータは、バージョン管理システムの一レポジトリと化します。


ただしこの試みは、すべてのアプリケーションで成功するわけではありません。プラグインが環境に依存する場合があるためです。あるプラグインが別の環境で動かないと、ダンプからの復元中にそこで停止することになります。そのプラグインだけ無視することはできますが、そのプラグインにまた別のプラグインが依存している場合、その後の復元結果が動く保証ができなくなるためです。


しかしそれでも FirefoxEmacs, Vim のような

のアプリケーションは、レポジトリ化していくでしょう。


またこの過程で、現在のバージョン管理システムからスピンアウトした、バージョン管理ライブラリが出現、それなりに広く利用されるようになります。同時に、既存のアプリケーションの変更を監視して、外部から変更を記録していきダンプを作成する汎用のツールも出現します (非汎用では、Firefoxプラグインをダンプするプラグインなんかが既にあるはず)。EmacsVim など、大規模でありつつも現在既に普及してしまっているものは、初期の段階ではこの種のツールに頼ることになります。

この流れが加速していくと OS はレポジトリの集合になり、バージョン管理システムを統合した OS が出現します。

Vim を覚えるために最低限知っておきたいこと

Emacs のチュートリアルを書かれている方を見かけたので、誰にも頼まれてませんが Vim の話をしたいと思います(なんだそれ)。といっても最低限の操作は先人が素晴らしいチュートリアルを書いておられるので、僕はリンクするだけなんですけど。

素晴らしい解説です。ほんと。僕も Vim 覚えるときにこの解説が読みたかった。


ともあれ。
それで最低限はいいとして。触発されて、以下「最低限」とその先を覚えていくために、知っておくととっかかりになること、意外と教わる機会のなさそうなことを並べてみます。

困ったときの終わり方
  • ESC を数回連打して :q! と入力して Enter キーを押す

おさらい的に。なんかドツボにはまっても、これだけ知ってれば Vim は終われます。保存してないファイルは消えますが、とにかく訳わかんなくなったときのリーサルウェポンてことで。

GUI 版の場合は、まずウィンドウを閉じるボタンがあるので関係ない話かもしれません。

チュートリアルの開き方
  • :Tutorial (と入力して Enter)

ある意味これがすべてです。

仮に前提知識がまったくなくとも、Vim を起動して :Tutorial と叩いて Enter キーが押せれば、後は書いてあることに従うだけで最低限以上の操作ができるようになります。具体的に言うと、Vim の起動と終了、ファイルのオープン・新規作成・保存、テキストの基本的な編集法、検索と置換、オプションと設定ファイルの基本、ヘルプ(マニュアル)の開き方などが理解できます。

マニュアルの開き方と読み方
  • マニュアルを開く: :help (と入力して Enter)
  • リンク先へジャンプ: Ctrl-] (Ctrl キーを押しつつ "]" キー)
  • 前のページに戻る: Ctrl-O

Vim のマニュアルは、Vim で開くテキストとして提供されています。なので (:Tutorial 同様) 普通に j とかでスクロールして読み進められます。が、これはただのテキストではなく、HTML でいうハイパーリンクがあります。そのリンクを踏んでジャンプするのが Ctrl-] で、ジャンプした先から戻るのが Ctrl-O です (戻るのは Ctrl-T とかも OK) 。

リンクには何種類かの見え方がありますが、色が違ったり縦棒で囲まれてたり (ex. |edit-intro|) クォートで囲まれてたり (ex. 'readonly') ダブルクォートされてたり (ex. ":write") する、とにかく目立つものは大体リンクです。

まあ正直こういう説明も当然マニュアルに書いてある (:help usr_01) んですが、ともあれこれさえ知っていれば後は頭からマニュアルをごりごり読んでいくだけです。あっという間にライト Vim ユーザの出来上がり。

ESC の位置
  • ESC キー = Ctrl-[

これは上の id:ruicc さんも紹介されてますが、強調の意味で。

ESC ってマニュアルに書いてあるからって、正直に ESC キー押す奴はシロートです。っていうのはまあ暴論としても、ESC を頻用する vi 系のインターフェイスでは、馬鹿正直に ESC キーを使うと「ホームポジションから手を離さなくていい」というメリットがだいぶ薄れてしまいます。ノートPCのキーボードだと ESC の位置が変だったりして、えっらいストレスフルになりますしね。( "[" キーも幅が小さくなってたりしますが、位置が違うよりは随分マシです)

なお、この時もちろん Ctrl は a キーの左隣でないと、効果激減です。(ノート PC のあのにっくき Fn キー) はっきり言ってこれのためだけにでも CapsLock を Ctrl にする価値はあります。CapsLock キーなんてどうせ使いませんよね? とっとと潰してしまいましょう。

screen

詳細は上の素晴らしい紹介を読んでいただくとして、大雑把に。

screen は、シェル界のタブブラウザです(どんな説明だよ)。つまり screen を使うと、一つのシェルの中でシェルを同時にいくつも開いておいて好きに切り替えることができます。

これは Vim とは何の関係もない普通のツールなんですが、たぶん Vim ユーザ必携のソフトなのでここに挙げてます。というのは、VimEmacs と違って内部にシェルを持てないから。まあ厳密に言えば任意のコマンドを実行できるんですが、それは比較的「開いているファイルを編集するためにコマンドを実行する」ことに意識があります。しかし開いているファイルと全然関係ないディレクトリで作業したいときなど、普通のシェルが欲しい時は結構あって。

そういう場合に screen が重宝します。screen の中で開いたシェルで Vim を実行していれば、いつでも別のシェルを開けますし、また Vim に戻ってこれるという寸法です。っていうか screen なしで Vim を実行することのほうが稀なぐらい。

英語

最後に書きましたが実のところ大前提。
なにせマニュアルが英語です。チュートリアルには日本語版もありますが……。

付属のマニュアルを全部翻訳してwebで公開されている方もおられて、それはそれですごくありがたく参考にさせていただくのですが、ぶっちゃけブラウザ開いて検索すんのがめんどい。「foo のオプション忘れた!」と思った瞬間に「:h foo」(:h は :help の省略形です) すれば話がすむデフォルトのマニュアルは、この点で最強最速です。そうすると必然英語が要ると。


やっぱり英語は大事ですねー、というなんか常識的な結論で締める僕でありました。

いや、あの、vi と Vim を区別してもらえませんか

vi と Vim は別物です。

というか、Vim は vi のスーパーセットです。僕は Vim 以外でコーディングする気がしませんが、vi でやれって言われたら Eclipse を使うほうがまだマシだと主張するかもしれません。さすがにオリジナルの vi にはシンタックスハイライトも quickfix も vimgrep もないどころか、多段アンドゥも複数ファイル編集もウィンドウ分割もタブもないわけで……。

混乱の原因は主に Linux のデフォルト設定なわけですが、今シェルで vi って書いたら、立ち上がるのはまあ概ね Vim だと思っていいです。(いまどき UNIX 系って言ったとき、それは概ね Linux の話であるのと同程度に。FreeBSD なんかは本当に vi nvi (オリジナルにかなり近い vi クローン) が立ち上がります)

逆に言うと vi って言ったら本当に vi が立ち上がる環境もあるから、vi と Vim は区別しないと話が混乱するんですよね。いや話がっていうか、僕が。

追記 (2008-12-24 13:51)

FreeBSD の vi はオリジナルの vi ではなく nvi だそうです via id:dekaino さんのブクマコメ。ファイル名が /usr/bin/vi で、:version で「Version 1.79 (10/23/96) The CSRG, University of California, Berkley.」と出るだけなので、てっきりオリジナルなんだと思っていましたが man vi したら確かに nvi という記述が。不勉強でした。


ついでにブクマコメに反応。
> UNIXが概ねLinuxってのは今時でも正しくないと思うが。(id:NOV1975 さん)
LinuxUNIX ライクですが UNIX ではないかと。という野暮はさておき。サーバを運用しておられる皆様なんかはばりばり BSD で戦っておられたりするかと思いますが、クライアントとしての利用は Linux がずいぶん目立つように思います。まあ僕の半径 10m をサンプリングしただけなんですけど。Mac がいるからまた微妙なのかな。

余談ですが

僕が (そしておそらく多くの Vim 派が) Vim 派であるのは、あの強度にキーボード指向の、思考と密着した操作インターフェイスによるところが大きいので、どういう機能を足されても挙動が超軽くなっても普通のエディタである限り Eclipse は遠い存在だという気もします。

Eclipse から秀丸に戻れない理由とかじゃなくて

ぜひ Vim とか Emacs に戻れない理由が知りたいです!


いや、Eclipseからテキストエディタに戻れない10の理由を読んだ感想なんですが。


秀丸とか (あと Tera なんとかとか Em なんとかとか K2 なんとかとか) まあそういう普通のエディタと IDE を比べたら、IDE の方が優れていて当たり前というか、優れてなかったら IDE の存在ってなんなんだというか、まあそういう感じですが。こと VimEmacs になると、Eclipse とどっちがいいのかわからんのですよ。いや本当に。

以下 Eclipse についてライト Vim ユーザがなんとなく雑感。


1. ぶっちゃけ、Vim でも困らないことは結構あります。

  • 入力補完 → Ctrl-N と Ctrl-P で足りてます。(Intellisense 並みの水準でなくても困ってない)
  • メソッドの宣言場所の表示 → ctags と連携でできます。
  • メソッドの参照箇所の把握と巡回 → :vimgrep と :cnext でできます。
  • TODO/FIXME の一覧管理 → :vimgrep と :cnext で(ry
  • オートフォーマット → や、シェルと連携できるのは前提なんで……できない理由がありません。
  • バージョン管理ツールと連携 → や、シェルと連携できるのは(ry
  • ブレークポイントによるデバッグ → シェル(ry


2. でも多分便利なとこは便利なんでしょう。

Vim にできなそうで便利そうなものは確かにあります。
構文解析した上でのリファクタリングとか、setter, getter の自動補完とか。マウスオーバーで javadoc 表示も地味に捨てがたいんじゃないかな。


3. でもそれ、できるべきなんでしょうか。

  • setter, getter の自動生成とか。

    自動生成しないとやってられないほどアクセサ書くのが面倒な Java っていう言語はなんなの? っていう。生成を楽にしても可読性は別に上がらないというか、そういうのは言語仕様を変えていくべき話なんじゃないでしょうか。まあ、そんなこと現場で言ってもどうにもならんのは事実なんでしょうけど、かといって胸張られてもなあというか。

  • import 文の自動挿入もそう。

    自動挿入しないとやってられないようなものを書かせる Java っていう言語はなんなの? っていう。IDE に自動挿入ができるというなら、それはコンパイラが勝手にやってソースには何も書かせない、っていうのがあるべき形なんじゃないんでしょうか。もちろんモジュール名が衝突する場合に、明示的に利用するモジュールを指定する記述は必要ですが。

  • 構文解析を伴う高度なシンタックスハイライトも同様。

    はい、Vim にはできません (し、多分やりません) 。でもこれも、裏で一生懸命構文解析を走らせなくても、例えば Ruby ならローカル変数は local ですし、インスタンスフィールドは @instance_field ですし static フィールドは @@static_field で グローバル変数は $global ですよ。色つけなくても見えますし、その色づけだって秀丸にすらできるでしょう。

結局、その素晴らしいシンタックスハイライトとかは、本当に本質的な「Eclipse の」メリットなんでしょうか。「アレな言語だけど一生懸命高性能なツール作って使えるようにしましたわーい」っていうのは、今ひとつ賛成できません。言語の発達を阻害します。ツールでどうにかするんなら、Java という言語を拡張するぐらいの勢いでやらないと「現場の小手先の知恵」以上に意味があるものにはならないと思うんですよね。(C のプリプロセッサは、ずいぶん奇形ではありますがこのアプローチです。Lisp のマクロや OCaml の camlp4 (今もう p5 か) はその究極形。)

機械化でソースレビューがラクになったとか、大事なことだと思いますけど、ぶっちゃけ Eclipse を推す文章を読んだ感想は大体「Eclipse いいなー」じゃなくて「Java やだなー」なんですよね……

Cの文法のダサさとかっこよさ

プログラミング言語の文法のデザインにおいて(と大上段で語る僕。)最も重要な記号は、たぶん空白文字です。これ → " " 。


これは空白文字が、他のどのキーよりも入力しやすく、かつ他のどのキーより視覚的負荷が小さいことによります。

何せスペースキーといえば、まず普通の日本語 QWERTY キーボードでは Enter キーに次ぐ大きさ。しかも Enter キーと違い、ほとんどスペースキーにしか使わない親指が存在します。これ以上入力しやすい、入力ミスの起きない文字はありません。他方、視覚的負荷という意味ではもっとすごくて、真っ白なので当然負荷ゼロです。皆無。負荷がなさすぎて逆に見落とすということは考えられますが、普通コーディングで使う等幅フォントなら問題にならないでしょう。


最も入力しやすく、かつ邪魔にならない記号——は、当然ですが最も高い頻度で用いられるものであるべきです。入力コストと認知負荷に対するハフマン符号化です (おおなんかそれっぽい言い回しだ)。現実、空白文字は英文で最も出現頻度の高い記号でしょうし、一般的な日本語入力ではスペースキーをかな漢字変換に使うわけで、これもかなりの頻度ですよね。


で、そうすると「空白文字を何に使うか」という点は、プログラミング言語の文法を大きく特徴づけます。
必然それは、その言語において最も高い頻度で使う機能は何か、ということを表すからです。つまり、

a b c

と空白区切りの列を書いた時、それの意味するところが、設計者が最も重要だと見なした機能・処理であるといえます。ざっと一例を挙げれば、

  • シェル → プログラムの実行 (プログラム a を引数 b c を渡して起動)
  • 関数型言語の ML, Haskell → 関数の呼び出し (関数 a に引数 b を適用し c を適用)
  • List Processor こと Lisp → リスト (a b c の 3 要素からなるリスト(括弧が要りますが))
  • 数式の処理を意識した Mathematica → 乗算 (a * b * c)
  • プロトタイプベースオブジェクト指向言語の Io → オブジェクトのメンバ参照(オブジェクト a のメンバ b のメンバ c)

と言った具合。いずれもチューリング完全で等価なはずのプログラミング言語に、それでもなお好き嫌いが発生するのは、一つにはこんな形でプログラマの入力と認知を、ひいては思考を束縛するからではないかと思います。


んで。

そこで我らが母国語 mother tongue であるところの C なわけですが、空白文字を使う機能は何かというと……


ありません。


ないんですよ。ないですよね? 空白区切りでずらずら並べる表記。そりゃ register volatile unsigned long long int とか書けますけど、そりゃそういう型の予約語作ればいいだけの話であって。(でも register volatile って無理かも) 可変長の要素を空白区切りで並べられる文法が、思いつく範囲にありません。思いつかないというのはつまり仮にあったとしても使用頻度の高い機能ではなく……。換言すると、C という言語にとって「最も重要な機能」なんてない、ってことなんですよね、これ。

それはなにかとんでもなくダサい文法のような気がしたわけですが、しかしよくよく考えると、文法的に何か一つのパラダイムを強要しない言語であるとも言えます。C が「汎用」の言語としてやたら普及した理由の一つは、もしかするとその、何も優先しない文法ゆえかなあ、と。

追記 (2009-01-04 02:09)

ブクマコメに反応。
>Cにおける"空白"は人間のためのコメント用という重要な意味を持ってると思うのだが。言語で使ってしまったらコメント用に使えないわけで (id:titton さん)

えっと。ここで書いているのは "空白文字を(二項の)演算子として使う時" 話で、言い換えると(これは不適当な記述でした。コメント欄参照) 「空白区切りの列を書いた時、それの意味するところ」を問題にしているので、ご指摘の点とは違う話のような。上で挙げた言語 (HaskellLispMathematica も Io も) だって人間の可読性のために (「コメント用に」) 空白文字を使うことはもちろんできますよ。下は構文的には妥当な Haskell プログラムです。

f a b c          -- ← c の後にたくさん空白文字がありますが影響ありません。