Some purchases

そういうわけで、左右のバランスが壊れているイヤホンを破棄し、新調した。SONY MDR-XB50というやつだ。

実を言うとオーディオ機器の良し悪しというのは全然さっぱりわからないので、別にこれが欲しかったとかそういうわけではなく、単に Amazon を見てて適当に決めただけだ。

それから、万が一イヤホンではなく PC の方に問題がある可能性もあるのでiBUFFALO USBオーディオ変換ケーブルなるものも注文した。これはいわゆる USB DAC と呼ばれるもので、USB 経由で音声データを取り出すのだが D/A 変換が PC の外で行われるためにノイズが軽減されるのだそうだ。ただしこの手のデバイスのお値段は正にピンきりで、注文したのは相当下のグレードだ。

で、とりあえず直接イヤホンを PC につなげてみたところ、バランスは元に戻ったので、やっぱりイヤホンが断線していたみたいだ。そういうわけで USB DAC は別に使わなくてもいいかなということに。別にノイズが乗るわけでもないし。

ついでなので、4GB のメモリも注文した。現在の PC のメモリも 4G なので、合わせて 8G だーわっほいと思っていたのだが、開けてみたらなんと 2G+2G の構成なのだった。そういうわけで 8G ではなく 6G になってしまった。

Save to

Firefox に Save File to という素敵な拡張がある。これはリンクや、メディアファイルに対するコンテキストメニューにホームディレクトリの任意のディレクトリツリーを展開し、選択したメニュー項目のパスへ直接ダウンロードする機能を提供する。つまり、とりあえず ~/Downloads に落として、落とし終わったら適当なところに移動…という手間を省ける。

似たようなものは Chrome にはないのだろうかと探してみたのだが、ないようなので作った。

本家には保存ダイアログにまで割り込んだり、サブメニューを左右交互に展開させるような芸の細かいオプションがあるが、残念ながら Chrome の拡張にそこまでの自由度はないので勝手に移植物としてはかなり不完全。

Promise and Generator #2

そういうわけでちまちまといじっている。

とりあえず vi コマンドを回す部分に関しては修正した。これで非同期の処理だろうが同期の処理だろうが不自然なく呼べるようになった。それはいいのだが、vi コマンド群は本丸ではない。qeema が発生するキーボードイベントから、各 vi コマンドのハンドラに達するまで、せいぜい 4〜5 の関数がネストするだけであり、ただそれを Promise を使うようにすれば済む。

難しいのは ex コマンドの方なのだった。

ex コマンドは、ex コマンド列をコンパイルして中間コードの配列に落とし、それを逐一実行するという構造になっている。なので、修正するとしたら ex コマンドごとに Promise をつなげていく、ex コマンド自体はそれぞれ resolve() でコマンドの終了を通知するといった形になる。

ただいくつか面倒な点がある。

  • write、read、edit などバックグラウンドに処理を投げるファイルシステム系のコマンドは、読み書きの進捗イベントをバックグラウンドから複数回返される。従来は、この複数回返されるメッセージというのは ex コマンドのハンドラの外で処理していた。というのも非同期的な ex コマンドを実行する際は一旦そのコマンドの同期的な部分のみを実行したあと executor を一時停止し、バックグラウンドから処理完了メッセージが到着したら executor.resume() で再開するようになっていたからだ。これは処理が分散しているといえばそうなので、若干不自然ではある。

    個々の ex コマンドを Promise によって駆動するのであれば、複数回返されるメッセージの扱いというものも ex コマンドのハンドラ内で完結できるわけで、そうすべきだと思う。具体的にはハンドラ内で long-lived connection をその都度行い、コマンド完了時に閉じればいい

  • シグナルの扱い。シグナルというと若干語弊があるのだけど、つまりやはりファイルシステム系の時間がかかるコマンドの実行中、[cci]^C[/cci] が押されたらキャンセル扱いにする処理のことだ。これも Promise 化によって中身がかなり変わる。

ちなみに非同期で実行される ex コマンドとしては

  • cd
  • edit
  • read
  • c オプションが付加された s
  • 非同期とマークされたオプションの値の変更を含んだ set
  • write

となっている。また、レジスタを指定できる ex コマンドで [cci]*[/cci] レジスタが指定された場合も非同期になる。レジスタを指定できる ex コマンドは、

  • delete
  • put
  • yank
  • @
  • *

となっている。非同期とマークされたオプションは以下のとおり。

  • fullscreen
  • syncsize
  • columns
  • lines

Promise and Generator

Migemo Server for Google Chrome™ というものがある。これ自体は migemo のライブラリのように動作し、外部の拡張からのリクエストを受け入れ、適切な結果を返す。

これに対応してみようかなとコードを頭の中で組み立ててみたのだけど、すぐに行き詰まってしまった。というのも拡張から拡張への通信というものは非同期に行われるからだ。一方で wasavi がキー入力を処理する構造は同期ベースで、非同期な動作を組み入れるのはとっても大変なのだ。

この辺を、Generator と Promise を組み合わせて使うようにすればとてもすっきり書けるのだが。なぜ今までそうしなかったかと言えばすなわち Presto Opera でも動かすためだ。Opera 12 は Promise の Polyfill は動くが、Generator は無理なのだ。

しかし、もう wasavi/0.6.657 で Presto Opera のサポートは終了した。従っていよいよそのへんを書き直す頃合いだ。これは割と大掛かりな仕事になるかもしれない。

Mount a windows share folder

Windows マシンを Windows10 にした際に HDD も新調して 2T の広さになったのだが、はっきり言って全然使ってない。というか、Windows マシン自体をほとんど使ってない。

もったいないので、ファイルサーバ代わりにしたい。つまり、Linux (xubuntu) 側から samba で恒久的にマウントしたい。恒久的というのは、xubuntu のファイルマネージャである Thunar 上からも一応 Windows の共有フォルダにオンデマンドでアクセスできるのだが、どこにマウントしているのかよくわからなく、Thunar の中で閉じているのが困るので。そうではなく単純に fstab に記述する形でマウントしたい。

というわけで文書を参考にマウント。

Unicode data updated

wasavi は内部(unicode_utils.js)にいろいろと Unicode のプロパティの情報を持っている。それらの情報は、例えば f/F/t/T コマンドにおける検索対象の判別とか、textwidth オプションを介した自動的な折り返しの際に適切な折り返し位置を見つける処理とか、さまざまなところで役に立っている、なくてはならないものだ。

今までは、それらのプロパティは Unicode 6.2.0 ベースだった。6.2.0 といえば 2012 年の話であり、さすがにちょっと古くなり始めた感が否めない。そういうことで今回 9.0.0 に引き上げた。同時に、プロパティを javascript のコードに変換するスクリプトを今までは PHP で書いていたが、javascript で書き直した。これで、wasavi 本体は当然として、ビルドスクリプトも、テストスクリプトも、データ生成スクリプトもほぼ全てが javascript になった(なったからどうというものでもないが)。

ところで Unicode の各種プロパティのバージョンを引き上げて、それでおしまいというわけではない。データを使用する javascript のコードも Unicode 9.0.0 に合わせる必要がある。ということで合わせた。とても疲れた。

Unicode 絡みで言うと、unicode_utils.js 以外に Unistring というライブラリも使っている。こちらもとても重要なものだ。Unistring が文字列を grapheme cluster 単位に分解することで grapheme cluster 単位のカーソルの移動を実現している。これがなくては、テキスト中に絵文字が 1 つあっただけでカーソル移動がめちゃくちゃになってしまうのだ。

ということで Unistring が持つ内部のテーブルも 9.0.0 に合わせた。4351 件のテストにもパスする。

Unit testing

wasavi の動作の保証として Selenium を用いた機能テストを通してからリリースしているわけだが、まとまった、自動化された形でのユニットテストは行っていなかった。これはけっこうイケてないので、ユニットテストの仕組みを構築したい。

そんなわけでいくつかのユニットテストコードを追加した。特に難しいことはなく
$ mocha src/unit-tests/strftime.js
などとする。

Specifying an offset

[cci]/[/cci] および [cci]?[/cci] コマンドには、デリミタに続けてオフセットを付加することができる。オフセットには符号を先行させてもよい。つまり
/foo/+
/foo/1
/foo/+1
はいずれも、カーソル行以降の foo を検索し、その次の行にカーソルを移動させる。同様に
?foo?-
?foo?-1
はカーソル行より前の foo を検索し、その前の行にカーソルを移動させる。

オフセットを付加したとき、モーションは行志向であるとみなされる。ところでこのオフセット機能は POSIX で定義されているものなのだが、オフセットを付加した時の桁位置はどうなるのかというとなぜか記述されていない。大抵の場合、行志向のモーションはカーソルをその行の最初の非空白文字に置くので、そうした。vim もそうなっている。

ちなみに POSIX ではデリミタ以降にオフセットではない余計なものがついてたらエラーにしなさいとか、オフセットを計算した後の行位置がバッファの先頭行や最終行を超えていたらエラーにしなさいとか、オフセットの他に z コマンドも有効としなさいとか言っているのだが、その辺は実装していない。vim も実装していない(たぶん)。

Increment and Decrement #2

ノーマルモードでの [cci]^A[/cci]、[cci]^X[/cci] を作った。このコマンドは [cci].[/cci] の対象にもなる。

次に、bound モードでの動作を考える。vim では visual/visual line/visual block モードでも増減ができる。ノーマルモードではカーソルが位置する数値文字列が対象になるが、visual 系(謎)モードでは、選択された領域の各行の、最も左端にある数値文字列が対象になる。これは若干違和感がなくもない。選択された領域内のすべての数値文字列が対象になってもおかしくないのではないのか? 後で考える。

ちなみに、それを作るときにも書いたが、vim における visual 系モードは wasavi では bound/bound_line モードになっている。なぜモード名を変えたのかといえば、そもそも vi というものが ex の visual モードにほかならないからだ。命名がダブっている。

 * * *

bound モードでも動作するようにした。vim と違い、領域内の全ての数値文字列が増減の対象となるようにした。

それから、vim のように [cci]set nrformat+=octal[/cci] などという特殊な代入をできるようにするかどうかだが、とりあえず、保留。

Collapsed volume

個人的な開発マシンを新調して以来、ベンチマークは5倍になるし、画面は広くなるし、動画も祈りながら見なくても良くなったし、スリープと復帰も安定しているので言うことはないのだけど、ひとつ困ったことがある。イヤフォンを挿したとき、左右のバランスがぶっ壊れているのだ。右だけがやたら大きい。とりあえずとして設定でバランスを変えればまあ何とかなるのだが、右を思い切り下げたぶん、絶対的な全体の音量不足が発生してしまう。そんなわけで左をちょっとだけ100%からブーストすると、今度は音割れが激しいのであった。

これは何が原因なのかな。音源はチップセット(Intel Corporation 6 Series/C200 Series Chipset Family High Definition Audio Controller (rev 05)
)に組み込みのものだがこれがぶっ壊れるというのはちょっと考えられない。

それよりはソフトウェア的にぶっ壊れてる可能性の方が高いけれど、どこから調べればいいのかよく分からない。

もしかして、イヤフォンが断線してるとかのオチなのかしらん。とりあえず新しいのにしてみるかな。