去年のVimconf 2017には、雇用主のドワンゴがスポンサーをしていたので、スポンサーチケットで参加をした。
今年のVimconf 2018もドワンゴはスポンサーをしていたが、去年は私がスポンサーチケットを使ったので遠慮をして今年は別の同僚に譲った。自腹で行こうかと思ったが、チケット販売サイトはクレジットカードからの入金しか受け付けなかったので、購入を断念した。
残念、今年は参加できないか、と思っていたところ、運営スタッフから人手不足で当日のスタッフが足りないので来てくれと言われ、急遽スタッフとして受付のチケットもぎりをすることになったので、結果的に今年も参加することになった。他の運営スタッフとは違い、当日の、それも開場後前後の1,2時間程度しかスタッフらしいことはしなかったのだが、立派なスタッフ面をいて開場直後以外の発表はバックヤードから聞いていた。
Vimconfは国際カンファレンスを意識して基本的に英語で司会、発表が行われるのだが、無線イヤホン経由の英語と日本語の通訳がついている。去年のVimconf 2017ではプロの通訳ではない運営スタッフの一人が通訳を担当した。プロではないので、通訳内容はだいぶアレでソレであったと聞いている。
今回はなんとプロの通訳を手配したという。私は英語のリスニングができるので通訳の品質を確かめてくれと言われてイヤホンを聞いてみたのだが、さすがはプロだ。流暢な英語が流れてくる。英語は自然で発表内容とあっているように思われるが、本当に発表者の発言と一致しているかという検証は難しかった。というのも発表者の日本語と通訳の英語を同時に聞くのは困難だからだ。驚異的なことに、発表者の発話する日本語に対応して流れる英語の遅延が少ない。あらかじめ発表内容の台本を渡されてそれを翻訳して読み上げているのだろうかと思うぐらい遅延が少ない。さすがはプロの通訳だ。
発表はmattnさんから始まった。VimからTCP/IPのlistenできるようにするという機能の実装で、VimがNUL文字を扱えるようにBLOB型を追加するという内容だった。
いよいよBram Moolenaar本人が発表する番になった。Bram Moolenaarはあまり表に出てこない人だ。Vimconf 2018以前にBram Moolenaarに直接対面したことのある日本人は数えるほどしかいないはずだ。インターネット上でBram Moolenaarを検索すると決まって出てくる、あの有名な酒瓶を掲げたBram画像は11年前の2007年のもので、現在の本人は11年分の齢を重ねた姿になっていた。
Bram Moolenaarの発表はVimの歴史を軽く紹介したほかは、Vimが現在取り組んでいる新機能の現状についての説明があった。Vimscriptが遅いのでパース済みの中間表現を保持することで高速化するアイディアや、Vimscriptのスレッドによる並列読み込みといったアイディアが説明された。そしてプラグインの話になった。最初のプラグイン機構は単一のディレクトリにvimscriptを放り込むものであったが、最近はプラグインごとに独立したディレクトリを持つことができるようになり、だいぶ楽になった。プラグインの例として、なんとあのShougoさんのプラグインが言及され、開場からは驚きの声が上がっていた。思えば遠くまで来たものだ。その後、プラグイン間で共通のライブラリを使いたいという至極当然の欲求から、プラグインの依存関係を記述して解決するパッケージマネージャー機能のアイディアが説明された。
質疑応答では、Bram MoolenaarはLSP(Language Server Protocol)についてあまり興味がなさそうであった。しかしLSPをVimでサポートするのはなかなかよさそうなアイディアに思える。
昼になり弁当が配られた。国際会議なので様々な思想に配慮した結果、すき焼き弁当とベジタブル弁当が用意されていた。私はすき焼き弁当を取りそこねたので、余っていたベジタブル弁当を食べた。ベジタブル弁当の中身はとても品数が多く豪華であった。酒のつまみによさそうな中身だった。
昼休みの余興として、ホワイトボードに模造紙を貼って、Vimで書く言語についてのアンケートが行われた。
ありえないことにCとC++が"C/C++"とひとくくりにされていたので、分割した。
その他の欄には様々な言語が学んだ。まずMarkdownだ。当然ながらVimscriptもVimで書く。Markdownもそうだ。VimでVimを書く人もいた。これはVimでVimの開発をしているということだ。要するにC言語を書くことでもあるのだが。
Python 2を書いてみたところ、シールがいくつか貼られていた。まだPython 2を書かなければならないかわいそうな人たちも参加していたらしい。
ネタで書いたEmacs Lispにもシールが貼られていた。これはネタではなく理由のあることで、環境構築をする際にまずデフォルトで入っているVimでEmacsの設定ファイルを記述し、その後にEmacsをインストールするので、VimでEmacs Lispを実際に書くのだという。
更にわからないことに、Jupyter Notebookが追加されてた。Jupyter Notebookというのはプログラマーではなく科学者向けソフトウェアだ。科学者は頭のいい人間であり、研究に必要なコードは当然書ける。しかし彼らは本物のプログラマーではないので、プログラマーらしいコンピューターの使い方やプログラミング言語の環境構築は苦手だ。Jupyter Notebookはそういう手間を省き、科学者でも様々なプログラミング言語を使えるようにした環境だ。Jupyter Notebookというソフトウェア一つ入れれば、後は何も考えなくてもいい。そのJupyter NotebookをVimから使うとはどういうことか。聞けばVimからJupyter Notebookを操作しているのだという。それができる人間なら、Jupyter Notebookをわざわざ使わずともプログラミング言語の環境構築は簡単にできるはずなのだが、世の中はわからない。
午後の発表になった。Vimの従来のプラグインの機能は、実は今のVim標準の機能で代替可能であることを示す発表があった。Ctrl-Xから始まる各種保管の説明があったが、私は使いこなしていない。
今回の複数の発表によれば、Vimは就職活動に役立つらしい。
vim-historyレポジトリも興味深い。これは1991年にリリースされて27年の歴史を持つVimの更新履歴を単一のgitレポジトリで再現したものだ。Vimは当初、当時の慣習としてtarballで配布され、その後CVSで管理されるようになり、何度かのレポジトリの断絶を経て、今はgitで管理されている。レポジトリの全歴史をgitレポジトリで表現することにより、gitによる様々な操作が可能になる。例えば特定のコントリビューターは何件コミットしているのか。あるコントリビューターの最初のコミットはどれか。などといった、様々な変更の歴史がgitで検索できるようになる。
似たような試みはUNIXにもある。UNIXの歴史をgitレポジトリで再現するプロジェクトがある。
そして、:termdebug機能が言及された。この後の発表はあまり覚えていない。:termdebug機能のあまりの素晴らしさに発表を聞くのがおろそかになってしまったからだ。
:termdebugはVimにデフォルトで同梱されているVimによるGDBのフロントエンドを提供するプラグインだ。使い方は、":packadd termdebug"して、":Termdebug プログラム名"するだけだ。VimはGDBを起動してGDBと通信する。そして、GDBとやり取りするウインドウ、デバッグされるプログラムの標準入出力のウインドウが追加される。現在のウインドウはソースコード表示に使われる。
素晴らしいことに、マウスサポートを有効にしている場合、StepやNextといったボタンが現れ、クリックすら可能になる。そしてGDBに該当のコマンドを送る。
これがすべてVimの中で動くということは、リモートサーバーにsshして動かすことすら可能になるということだ。
しかし、使うとすぐにバグが見つかった。ブレイクポイントはソースコード上で表示されるのだが、break/deleteを繰り返すと存在しないブレイクポイントの表示が消えなくなるのだ。この問題は原因を特定したのだが、最新版のVimでは治っていることが判明した。
もう一つの問題は、Bram MoolenaarがC言語しか想定していなかったための機能不全だ。C++では複数の関数が同じ名前を持つことができる。
void f() {}
void f(int) { }
void f(long) { }
この状態で"break f"とすると、関数fすべてにブレイクポイントが設定される。termdebugはこれに対応していない。
この場合のGDBのブレイクポイント番号の付与は変わっている。"break f"とした場合、1.1(f()), 1.2(f(int)), 1.3(f(long))のようにメジャーブレイクポイント番号と関数ごとにマイナーブレイクポイント番号が付与される。結果としてブレイクポイントは3つできるが、それはすべてブレイクポイント番号1として扱われる。enableコマンドなどは"enable 1.1"のように指定できるが、deleteは指定できない。"delete 1"とするとブレイクポイント番号1に属するすべてのブレイクポイントが削除される。
termdebugはブレイクポイント番号をキーにしてmapでブレイクポイントを管理しているのだが、ひとつのbreakコマンドで複数のブレイクポイントが設定されることを想定していないし、ましてやその複数のブレイクポイントが一つのメジャーブレイクポイント番号に属することを想定していない。そもそもマイナーブレイクポイント番号があることすら想定していない。ブレイクポイント番号をキーにしてmapでブレイクポイントを管理していて、削除時にブレイクポイント番号をキーに検索して削除している。
現在のコードを大幅に変えずに関数のオーバーロードのブレイクポイント表示に対応するのは難しい。HandleNewBreakpointで"1.1", "1.2", "1.3"のようなキーで複数のブレイクポイント番号をキーにしてs:breakpointsに挿入し、HandleBreakpointDeleteで"1.1", "1.2", ...のようにマイナー番号の削除を見つからなくなるまで試みる実装が、とりあえず使えるだろうとは思う。
termdebugは素晴らしい。そして、Termdebugとそのバグのおかげで、Bram Boolenaarと会話ができたという思わぬ副産物もあった。VimconfにBram Moolenaarが来ると聞いて会話をしたいとは思っていたものの、特に話すべき内容は思いつかなかった。なるほど、私はVimを毎日使っているが、Vimの開発に参加しているわけはない。せいぜい挨拶をするのが関の山だと思っていたのだが、Termdebugの存在で会話内容ができてしまった。英語によるスピーキングは普段全くしていないので英語が口から一切出てこないのだが、不思議なことにtermdebugがC++をサポートしていないことについてとその原因についてであれば、英語で説明をすることができた。言語の利用には慣れた文脈が必要のようだ。
termdebugをなぜ今まで知らなかったのだろうと疑問に思っていたが、どうやら今年の7月にVimに入ったばかりのだいぶ新しい機能であるようだ。道理で知らないわけだ。termdebugの存在を知ることができたという理由だけでvimconf 2018のスタッフをしたかいがあった。
その後、もう一枚ホワイトボードが追加され、今度はVimに欲しい新機能のアンケートが行われた。人気の機能はVimscriptの高速化であった。私は、VimがtmuxやScreenのように、シェルからのdisownによるログアウト後の実行継続と、detach/attach機能がほしい。この機能があれば、tmuxはいらなくなる。Vimがtmuxの代わりを務めることができるのだ。リモートサーバーにsshしてvimでテキストを編集し、その編集中のvimの実行を継続したままログアウトし、後にログインして前回の続きから作業を再開したい時、今はtmuxの中でvimを実行しなければならない。これがvimだけで済むようになるのだ。
新機能では端末でエスケープシーケンスによるグラフィック表示をするSixelも人気があった。これは解せないことだ。Sixelはテキスト処理だけで完結するが、グラフィックの表現としては非効率的すぎる。効率を重視するならば、ビットマップデータを直接流し込むようなAPIがほしい。もちろんこれはNULも扱えるようにBLOB型が必要になるだろう。
Vimconf 2018は素晴らしかった。来年も開催されるだろうか。楽しみだ。