a suddenly farewell #4

それにしても、なぜ突然 ipv6 の問題が出てきたのか。と思って調べてみると、うちのルータはフレッツ光の PR-400NE だが、ファーム自動更新によって ipv6 PPPoE に対応しました的なニュースとおかしくなった日付が重なる。

うん。確かに怪しい。こいつだ。

そして、実は Windows 7 マシンも似たような現象が起きていた。こちらは Opera だけではなく、あらゆるブラウザの動作がおかしい。おかしいというか、表示までに恐ろしく時間がかかったり、タイムアウトになったり、ping がロスしまくったりする。これはつまりかつて話題になった、フレッツ光の ipv6 フォールバック問題ということなのかしらん。

はて、どうしたものか…。

allow resizing from wasavi

issue #36 への対応。

wasavi が持つオプションの中に、[cci]columns[/cci] と [cci]lines[/cci] というものがある。これは、wasavi の実行時におけるあるタイミングでの桁数(正確に言うと、wasavi のスクロール領域のピクセル幅を、選択されたフォントで文字 [cci]0[/cci] を描画した際のピクセル数で割った整数部分)、および行数(正確に言うと以下略)を示している。

そもそも、wasavi のサイズは、寄生元の textarea のサイズに依存していて、そこには明確な主従関係がある。つまりまず textarea のサイズがあり、wasavi はそれに従うのみなのである。したがって、[cci]columns[/cci] と [cci]lines[/cci] は実質的に読み込み専用であり、新たな値を上書きすることはできるが、意味を持たない。何の副作用も起こさない。

件の issue は、これを書き込み可能にして、書き込んだときはその値で wasavi のサイズを更新してほしいというものだ。これは、一見簡単そうなのだが、しかしよく考えてみると前述の主従関係を根本的に破壊する変更なのでかなり困ったのである。

しかしただ拒絶するのもどうか。textarea のサイズによらず、常に同じサイズで wasavi を起動したいという要件も確かにあり得るのだ。

a suddenly farewell #3

-debugsocket 5 で出てくるログをよく見てみると、ipv6 のアドレスに接続しようとしていてことごとく失敗している。

ということはシステムから ipv6 を切り離せばいいのか? [cci]/etc/sysctl.conf[/cci] に以下を追加:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1



$ sudo sysctl -p

で、起動。
あ。動いた。
でもなんで突然こうなるのかな!

a suddenly farewell #2

情弱らしく 12.16 の deb を Ubuntu ソフトウェアセンターに食わせ再インストールを行ったところ、よくわからないけど、直った。つまるところ、ライブラリの依存関係等々が修復されたということなのか? 情弱なのでわからない。

ということで、この際 12.16 は捨てるか! という気分になりつつあったのが、必要なくなった。ある意味では残念だ。

 * * *

などと書いている先からまた同じ現象が発生した。

わからない…。

a suddenly farewell

まさに「何もしていないのにパソコンがこわれた」という現象を経験している。xubuntu 上の Opera 12.16 の調子が恐ろしく悪くなった。

  • *.2chan.net、*.google.com などいくつかのドメインへのアクセスが必ず失敗する: URL を開くと「リモートサーバーに接続できませんでした」的なエラーページになる
  • ~/.opera/cache/ を全削除したりしてもダメ
  • 全く新しいプロファイルで試してみてもダメ
  • -debugsocket 5 などのオプションを付加してみると、やたらエラーが発生している。実際にネットワークとのやりとりが発生する以前の、ソケットを開くレベルで失敗しているような気がする(確証なしの勘)。実際に dragonfly から確認してみると、ネットワークやりとり自体が発生していない(ただし dragonfly のそのへんのパネルはかなりバギーなので信用は出来ないのだが)
  • Opera 12.16 以外のブラウザでは特に問題はない
  • /var/log/ あたりに特に関係のありそうなログはない

はて。どうしたものか…。

refreSh! #2

ゼロ幅マッチがありうる正規表現への行末の特別扱い、確かに vim では存在するのだけど、nvi では存在しない。おそらく正規表現レベルの話ではなく、バッファの保持の仕方に起因するのだと思う。vim では [cci]regexpengine[/cci] オプションの値によらず同じ動作をするので。
:s/a*/!/g
は nvi 1.81.6 で実行すると行末にも ! が付加される。

また、POSIX の仕様にはその辺りは特に定義されていない。

ということで、wasavi では vim には合わせないことにした。

lunatic

開発に従って readme の内容も改めることがある。

改めてできるだけ客観的に wasavi の readme を読んでみたのだけど、気が狂ってるレベルで vi を実装していてちょっと作った人頭おかしいと思った。

refreSh!

ex コマンド [cci]s[/cci] について、とあるバグを直そうとしたら根本的に書き直さないとダメっぽかったので、根本的に書きなおした。

s コマンドの内部は、javascript の global と multiline フラグを立てた RegExp のインスタンスについて exec() を連続して呼び出すという処理がコアになっている。exec() を呼び出しながら、マッチした箇所について置換を行い、lastIndex プロパティを適宜調整し、次に備えるという 1 パスの処理になっている。

大体の場合はこれで上手く行くのだけど、ゼロ幅にマッチする正規表現の場合に上手く行かない。そして、それを直そうとすると、今まで上手く動いてた部分がこぞっておかしくなるという排他的な状態になってしまうのであった。

これを根本的に直すために、まず exec() のループと置換ループを別に分ける 2 パスの処理にすることにした。exec() で得た各マッチ位置の情報を配列に押し込んで覚えておく必要があるので、若干富豪的ではあるのだが、まあ、だいじょうぶだいじょうぶ。

その他見つけた細々としたバグも直した。

たとえばゼロ幅でマッチする正規表現、たとえば [cci]:s/a\?/!/g[/cci] というコマンドを実行すると、カーソル行の各文字の前後に [cci]![/cci] が挿入されるが、行末には挿入されない。少なくとも vim では挿入されない。これは割と奇妙な動作だ。

つまり、
0123
とある行に前述のコマンドを実行すると、本来ならば
!0!1!2!3!
となっておかしくないはずであるが、少なくとも vim では
!0!1!2!3
となる。行末の [cci]![/cci] がない。

この通りに動作させるには、マッチした位置が改行で、かつマッチした正規表現にメタ文字 [cci]$[/cci] が含まれない場合は置換を行わない、という例外を加えればいい。いいのだけど、後者はとても難しい。javascript ではとても難しい。マッチに使用された正規表現のパスを得る方法が javascript の RegExp にはない。

Up and Low

issue 41 で、gu/gU オペレータの実装が要望された。

これは vim の機能だ。そして、2 文字ではあるが、y/d/c といったオペレータと同様の動作をする。つまり、オペレータに後続するモーションとセットとなり、オペレータを入力したカーソル位置から、モーションによって移動したカーソル位置までの領域に対して、gu は小文字化、gU は大文字化を行う。

実は issue で指摘されるまで vim にそんな機能があることを知らなかったのだけど、たしかに便利そうなので、wasavi にも移植することにした。

すでに g プリフィクスの機構は(あんまり素敵なものではないにしても、とりあえず)移植済みである。特に g プリフィクスのオペレータとしては gq がすでにある。その仕組みに合わせて実装すればいい。素敵ではない点と言うのは、つまり g プリフィクスが付いているかどうかの判断を現時点では各オペレータのハンドラで行っているということだ。これは将来的には修正されなければならない。

それはそれとして、まあ gu/gU の実装をした。

CAPITAL REGISTERS

vi は a から z の名前付きレジスタを持っていて、ユーザは自由にそれを使うことができる。

vim はこれを拡張し、A から Z までのレジスタの指定も許す。これは新しいレジスタが 26 個増えるわけではなく、[a-z] レジスタに対する特別な別名として振る舞う。たとえばレジスタ A を指定してヤンクした場合、それは a レジスタがもともと持っていた内容への追記を表す。これは有用な機能なので、wasavi でもそういうふうに動作する。

では、A から Z までのレジスタを指定しつつ、それを読み出す動作を行わせた場合どうなるんでしたっけ?

とりあえず、vim では読み出しの場合は A レジスタは単に a レジスタの内容を返すようである。書き込み時のような特別扱いはない。しかしこの透過性って必要なんだろうか? 読み出し時にも特別扱いしていいのではないか。

というわけで、wasavi では、[A-Z] レジスタからの読み出しにおいては、以下のように振る舞うようにした。

  • B レジスタ: ブラウザのユーザーエージェント文字列を返す
  • D レジスタ: 現在の日付時刻の文字列を返す
  • T レジスタ: wasavi が属するページのタイトルを返す
  • U レジスタ: wasavi が属するページの URL を返す
  • W レジスタ: wasavi のバージョン文字列を返す

これ以外の [A-Z] レジスタは、単に空文字列を返す。