行折り返し

2008/06/29

例によって例のごとく、「主筆」の新バージョンを公開したから、今後やりたい事リストを書き連ねてみることにしようか。

最近、俺の中で気になっているのは、「主筆」は行を折り返して表示することができないということだ。ウインドウの右端で折り返して表示することができないのはもとより、一定文字数の単位で折り返して表示することもできない。それどころか、一行の長さはは最大10239文字までで、この制限はロジック中に定数値で書かれていて変更することもできない。

この制約は元々、「主筆」開発当初、すなわち2004年10月頃における決定事項に由来する。すなわち、最初から余り高度な機能を実現しようとすると、途中でモチベーションが維持できなくなるから、ある程度機能を絞って多少所しょぼい代物であっても構わないから、とりあえず動く物を作って公開することにしよう、という事だ。

この決定事項に基づき、俺は一行は最大10239文字(つまり10K文字)までと決めてしまい、かつ、行折り返しの機能は完全に諦めたのである。行を折り返して表示できるようにするとなると、明らかにテキストを描画するロジックが複雑になる。しかし、絶対に行を折り返して表示することはしないとすると、一行が極端に長いテキストを読み込まれたときに、甚だ困ったことが起きるものと予測される。つまり、ウインドウの表示に極端に時間がかかってしまったり、あるいは何らかの内部的な制約に引っかかったりするのではないかと、心配になったのだ。だから俺は、(1)面倒だから行折り返し機能は実装しない、(2)予測されうる問題を回避するために、一行の長さを制限する、という決定を下したのだ。

だが、ここに来てそろそろその決定を覆そうと考えている。すなわち、行の長さの制約を取り除き、行を折り返して表示する機能を実装するということだ。

行を折り返して表示すると言っても、いくつかのパターンが考えられる。まず第一に、一行がある程度以上の長さになったら、そこで強制的に折り返して表示するというものだ。テキストを描画する上で、やはり極端に横に長いといろいろと不都合が生じる危険性がある。だから、ある程度長くなったら自分自身を護るためにも、そこで強制的に折り返して表示するようにしてしまう必要があると考えられる。また、ユーザによってはある一定のところで折り返したいという欲求もあるかも知れない。それと二点目は、ウインドウの右端に来たら折り返して表示するという奴だ。これがいわゆる一般にに言うところの、行折り返し機能と言える奴だろう。

実装上及び機能上、この二つには共通部分もあるが共通しない部分もある。共通する部分としては、結局いかなるところで折り返そうとも一行が複数行として表示されるようになると言うことだ。現在の「主筆」は、一行のテキスト(つまり改行コードから次の改行コードまで)は、必ず一行で表示されることを前提として作成されている。その前提が崩れるのだから、内部的なロジックにはかなり甚大な影響が出るものと予測される。

共通しない部分としては、行を折り返して表示するタイミングの問題がある。まず、ある一定文字数以上になったら折り返すというのであれば、どこで折り返すのかを求めるのは存外容易である。つまり、テキスト中に含まれる文字数だけで、何行になって表示されるのかとか、どこの文字で折り返されるのかが容易に計算できる。更に、選択された文字がどの行に含まれるのかを計算するのも、比較的容易である。それに対して、ウインドウの右端で折り返すとなると、事態は一変する。つまり、どこで折り返すのかとか、結果として何行になるのかといったことは、各文字が描画されるときの幅を取得して、一行がウインドウの幅を超えるか超えないかという判断を行わなければならないのだ。これが固定ピッチフォントであれば、それもそれ程難しいことではないのだが、プロポーショナルフォントを表示する場合には、純粋に各文字の表示位置を計算してウインドウ幅と比較するという処理を行わなければならない。

ウインドウ幅で折り返す機能を実装するためには、各文字の幅を取得して、文字が表示される位置を計算しなければならない。そうしなければ、全体としての行数も判らないため、スクロールバーを表示することもできない。すなわち、テキストファイルを読み込んだタイミングで、一旦全てのテキストの表示幅を算出してやらねばならないということを意味している。そしてそれには時間がかかることが予測される。

そういった諸々を考えると、行折り返し機能は何かと大変なのではないかと思われる。

とりあえず、今現在特に対応したいと思っているのはそれぐらいだろうか。手元に転がっているMafefileやIniファイルの構文強調表示機能は、適当に時間を見繕って組み込めば良さそうだし、印刷機能の拡張(例えばカラー表示やプリンタ依存の拡張機能の利用など)は、今のところ余り必要性を感じていない。ツールバーはもとより実装する気はないし、ログを出力させる機能も個人的には欲しいところだが使う側としてはありがたみがない。プラグインやコマンド周辺の機能拡張もいくつか欲しいところだが、これはおそらく適当に気分が乗ってきたときにやることになるだろう。

そういうことで、第21版に搭載されるかどうかは判らない、というか今までの例からするとおそらくもっと後になるのだろうが、とりあえず行折り返し機能を実装する方法について、いろいろと考えを巡らしてみることにしよう。

20

2008/06/28

とりあえず、「主筆」の第20版を公開しておいた。本当なら、まだまだ細かいところを調整したかったのだが、きりがないから現時点で一旦打ち切ることにしておいた。

第19版からの変更点で、最も大きいものはエンコードの自動認識機能を搭載したことだろう。長年必要だろうと思いつつも実装できていなかった機能だが、これでようやく対応することができた。また、世の中一般ではごく当たり前に存在するMRUリストを管理・表示する機能も搭載しておいた。俺的には余り必要だとは思わないのだが、あると見てくれが派手になるから、一応入れておいた。

また、検索・置換ダイアログも少しだけ機能を拡張した。今までは、検索・置換ダイアログが表示されたとき、フォーカスが「OK」ボタンに来ていたのだが、それだと使いにくい。やはり、検索はキーボードだけで操作できるようにしたいものだ。ということで、検索・置換ダイアログが表示されたときには、検索文字列を入力するテキストボックスにフォーカスを合わせるよう変更した。また、テキストが選択された状態で検索・置換ダイアログが表示された場合には、選択されたテキストを検索対象の文字列としてデフォルトで設定するようにもした。後は、検索・置換対称の文字列の履歴を保持・表示する機能や、正規表現の入力を補助するような機能があれば、より便利になるのではないかと考えている。

これは俺だけかも知れないのだが、Windowsではフォーカスをどのコントロールに設定するのか、というのを制御するのはそれ程難しいことではない。だが、なぜだか知らないがMotifだとそれが以外と難しい。難しいと言うよりも、なんだか判らないが直感的にできない。思った通りに行かないのだ。検索・置換ダイアログのフォーカスの問題も、「初めからそうしておけばよかったじゃないか」という突っ込みが入りそうなのだが、実を言うと、「しなかった」でのはなく「できなかった」だけなのだ。だが、それもとうとう第20版で解決した。体育会系的方法論で。

全く役に立たないし、おそらく俺自身も動作確認をするとき以外は絶対に触らないであろう、バージョン情報を表示する機能も追加しておいた。世の中一般のソフトウェアでは、大概「ヘルプ」メニューがあり、その中には何の役に立つのか知らないが、バージョン情報を表示する機能がある。だから、「主筆」でもそれに倣ってこの機能を追加しておいた。まぁ、さしたる手間がかかるわけでもないし。もっとも、本当であれば「ヘルプ」メニューにはヘルプを表示する機能を搭載するべきなのだろうが、それはまだ実装できていない。

「主筆」のマニュアルはすべてPDFである。その都合上、プログラムから表示できるようにするのは何かと面倒だ。まぁ、不可能ではないし、表示するようにしても良いのだが、ユーザがPDFファイルのビューアとして何を使っているのか判らないとか、Solaris 8ではデフォルトではAcrobat Readerが入ってないとかいう問題があるから、やりたくないのだ。

CDEの場合(というべきかMotifの場合と言うべきかは知らないが)、古いWindowsのヘルプのようなヘルプを表示する機能が無くはないようなのだが、正直言って、あれは使いにくいような気がする。もし、「主筆」にまともなヘルプ機能を実装するのであれば、WindowsのHTMLヘルプのようなものを提供できるようにしたいものだ。そうすると、それはそれでかなりの作り込みになってしまうだろうが。

実を言うと、第20版を公開してしまった直後に、プラグイン開発ガイドの英訳に手を付けてしまった。現時点では第19版として公開していた分の英作文は終了し、後は20版に追加された分と、マニュアルとして整形する処理が残っているだけだ。あと一日ぐらい時間があれば、Plugin Development Guideとして公開できるようになるだろう。更に、手元にはMakefileとINIファイルの構文強調表示処理を行うモジュールも存在していたりもする。このタイミングなら、第20版として一緒に公開してしまいたかったのだが、それをやるとまたずるずると公開できなくなるから、それは諦めてしまった。マニュアルは適当な時期に独立してHPにアップロードすることにしよう。構文強調表示機能の拡張は、第21版からということになるだろう。

もっとも、第21版が公開されることになるのかどうかは、判らないが。

旧居

2008/06/08

主筆」のエンコードの自動認識機能・MRUリスト表示機能・プラグインへ提供するAPIの強化などが終わり、そろそろ第20版として公開しようかどうか考えている。もうちょっといくつか細かい機能を実装したい気もするが、そんなことを言っていたら、いつになってもキリがつかないから、そろそろ潮時ではないかと思う。

しかし、公開するとなると一つ問題がある。それは、Solarisの互換性の問題だ。Solarisの場合、新しいバージョンのOS上でコンパイルされたバイナリは、古いバージョンのOSの上では動作しない。たとえば、Solaris 10でコンパイルしたバイナリはSolaris 8では動かない。だから、実行バイナリを公開するのであれば、動作対象とするOSの内でもっとも古いものの上でコンパイルして、公開するバイナリを生成しなければならないということになる。

「主筆」は、以前からSolaris 8以上をターゲットとしてきた。そして、それはこれからも変えるつもりはない。たとえSunがどのような意思を持とうとも、俺はSolaris 8を見捨てるつもりはない。そのために俺は、今でもわざわざSolaris 8の環境を整えて維持し続けている(まぁ、要はSolaris 8を入れたマシンを転がしてあるだけなのだが)。

また、現在「主筆」はSun Studio 12で開発を行っている。強いてそれでなければならない理由はないのだが、とりあえずSun Studio 12に移行してしまったのだから仕方がない。Sun Studioは、特にX-Designerは、一度新しいバージョンのもので編集してしまったら、二度と古いバージョンには戻れないと言う、嫌がらせのような機能が実装されている。そのため、たとえ俺がどれほど心から後悔し、懺悔し、神に祈り許しを請うても、二度とsun Studio 11などの古いバージョンに戻ることは許されない。

ここで素直にSun Studio 12がSolaris 8の上で動作するならば、世は事も無しなのだが、しかしそうはいかない。Sun Studio 12はSolaris 9以上のOSで動作すると言うことになっている。Sun Studio 11はSolaris 8以上で動作するようになっていたのだが、ここにきてSunはとうとうSolaris 8を切り捨ててしまったようなのだ。

そうすると、俺はかなり困ったことになる。すなわち、「主筆」がsolaris 8をサポートし続けるのであれば、なんとしてもSolaris 8上でコンパイルしなくてはならない。しかし、肝心のコンパイラはSolaris 8では動作しない。

どうすればいいのか。

大きく分けて対応策は二つある。まず第一に、Solaris 8のサポートをやめてしまえばいいという方法が考えられる。要は、古いOSにいつまでの拘泥しているのがすべての原因なのだから、ここは世の流れに身を任して、思い切ってサポート対象をSolaris 10だけに限定してしまえばいいという発想。だが、これは俺が許さない。俺の個人的感情から、なにが何でも、当面はSolaris 8をサポート対象に含めたいと考えている。

そうすると、もう一つの方法としては、Sun Studio 11以前の古いコンパイラを用いて、Solaris 8上でバイナリを生成する方法がある。というか、ほとんどこれしかない。

だが、どうやってそれをやるのか。神に祈ろうが悪魔と契約しようが、Sun Studio 11には戻れないのではなかったのか。

実を言うと、いくつかの要点を押さえれば、C++のコード自体にバージョン依存の記述がない限りコンパイラのバージョンを落とすことは不可能ではない。その要点とは、X-Designerである。

結局、古いバージョンに戻れないのはX-Designerだけであり、かつ、それはX-Designerにより生成されたファイルを入力して、Cのソースコードを出力するまでの問題なのである。逆に言えば、C/C++のソースコードをコンパイルし終わってリンクする時点では、X-Designerに互換性がない問題は関係無いのである。

つまりこういうことだ。一旦Solaris 10上のSun Studio 12に含まれるX-Designerを用いてCのソースコードまでは出力しておく。そして、得られたソースコードをSolaris 8に持ってきて、sun Studio 11でコンパイルしてやればいい。そうすれば、目的のSolaris 8用バイナリを得ることが可能となる。

だが、ここで一点気をつけなければならないことがある。それは、Solaris 10とSolaris 8とで環境を同じようにしておくということだ。少なくとも、Sun Studio 12とSun Studio 11をインストールするパスは同一でなければならない。なぜならば、コンパイル時にX-Designerが生成するソース中には、Sun Studio 12のインストール先パスを含むパス名を固定的に保持しているのだ。そのため、ソースを生成するときと、それ以降のコンパイルの段階とで、参照先のパスが変わっていたりしたら、まともにコンパイルが通らなくなってしまうのだ。

とりあえず、その一点に気をつければ、Solaris 10で、かつ、X-Designerの新しいバージョンを用いてソースコードを生成を行わせた後も、Solaris 8に持ってきて古いコンパイラでコンパイルすることが可能となるはずだ。

一応、今もまさにSolaris 8/Sun Studio 11の環境で「主筆」をコンパイルしている最中である。もしこれでうまくいかなかったら、なんか別の手を考えよう。