「Inside the Editor」を読んで
Visual Studio 2010のテキストエディタモジュールがどういう作りになっているのかを説明している「Inside the Editor」を読んだ。このドキュメントに書かれているモデルは非常に良くできていると思う … 続きを読む 「Inside the Editor」を読んで
Visual Studio 2010のテキストエディタモジュールがどういう作りになっているのかを説明している「Inside the Editor」を読んだ。このドキュメントに書かれているモデルは非常に良くできていると思う … 続きを読む 「Inside the Editor」を読んで
Azuki 1.7.6をリリースしました。Azuki自体は基本的にバグ修正。AnnにはMRU(最近使ったファイル)機能を追加したので、日常的にAnnを使う人には嬉しいアップデートだと思います。つまり、自分にとって。 しか … 続きを読む Azuki 1.7.6リリース
C#という言語を使い始めて7年ぐらいは経つわけですが、Azukiの実装中に長いこと不満に思っていたコトが一つ解決しましたので備忘録。 Azukiは一応最初からプラットフォームを抽象化して作ってあります。そのため、現在はW … 続きを読む (C#)internal interfaceとinterfaceを組み合わせて、DLL外に公開しないメンバを定義する
最近いろいろな意味でヤル気が無くなっていたけれど、久しぶりに更新。一年以上何もか書かなかったか。まあそれもまたよし。今日はテキストエディタの「選択範囲」という概念について、2点書いておこう。さすがにTwitterにはつぶ … 続きを読む テキストエディタの「選択範囲」という概念について、2点
Azukiの開発が始まって以来おそらく一番難しい、セーブ時点の状態を基準に行ごとに編集状態を管理・表示する機能の実装ですが、あまりにも難しいのであきらめることにしました。 とにもかくにも、テキスト全体が1つのギャップバッ … 続きを読む 行ごとの編集状態、その3
本日「.NETでドラッグ&ドロップ」という記事を公開しました。 「.NETでドラッグ&ドロップ」HTML版 「.NETでドラッグ&ドロップ」PDF版 この記事には名前の通り.NET上でドラッグ … 続きを読む 「一太郎2011 創」の初使用
本日Azukiの不具合修正版1.6.2をリリースしました。一応当日のブログなので一言触れておきます 🙂 ここのところ悩んでいるのは3/13にも本ブログで記した「行ごとの編集状態」です。もともと想定していた範囲を超える仕様 … 続きを読む 行ごとの編集状態、その2
(2011/4/6追記。本件はMicrosoftから将来のリリースで修正するとの回答がありました)
(2011/8/27追記。最新版のVisual Studio 2010+最新の.NET Framework 4で試したところ、まだ修正されていないようです。)
本日、各言語での正規表現エンジンを使って「^」記号(文字列または行の先頭を示す、アンカーあるいはゼロ幅アサーション…と呼ぶらしい)に関する動作を調査しました。背景にあるのはAzukiが内蔵している正規表現検索で行頭マッチングが行われないというユーザ報告の不具合(に近いが対策できず黙認していた動作仕様)です。過去に検索機能を実装した際の調査結果では.NETの正規表現エンジンで「Multilineモード」を有効にしても各行の先頭でない位置でマッチする現象が起こり、使えないと判断しました。今回は、この問題を改めて少し掘り下げて調査した結果報告(?)となります。
調査結果のポイントです。
ポイント1および2です。Regex.Match( string, int )のオーバーロードを使ってマッチング開始点だけを指定した場合には、行頭でも文字列先頭でもない位置がマッチング範囲の開始点であっても「^」記号は該当位置にマッチしません。しかしRegex.Match( string, int, int )のオーバーロードを使うと、マッチします。したがってオーバーロード引数を追加するだけで動作仕様が変化してしまうため、不自然な印象を受けます。次に例を記します。
string text = "abc";
new Regex( "^[a-z]" ).Match( text, 1 ); // どこにもマッチしない
new Regex( "^[a-z]" ).Match( text, 1, text.Length ); // 1文字目のbでマッチする
ポイント3です。Javaの正規表現エンジンでは「Anchoring Bounds」という概念があり、「^」記号の扱いをカスタマイズできます。Anchoring Boundsを使うよう設定すると、「^」記号および「$」記号のマッチング時にマッチング範囲の前後が考慮されない — つまり問答無用でマッチング範囲の始点に「^」記号がマッチするようになります。そしてAnchoring Boundsを使わないよう設定すると、マッチング範囲の開始点が文字列先頭あるいは行頭でない限り、「^」記号はマッチング範囲の開始点にマッチしません。このように「^」記号のマッチング動作を明示的に指定できる機構があれば、それを使うことで問題回避できますが、残念ながら.NETにはありません。
ポイント4です。どうやら.NETの正規表現エンジンではJavaでいう「Anchoring Bounds」の扱いがRegex.Matchのオーバーロードごとに異なっており、Regex.Match(string,int)はAnchoring Boundsを使わず、Regex.Match(string,int,int)はAnchoring Boundsを使う動作となっています。ここで、もしAnchoring Boundsを「常に使いたい」場合は外部でマッチング対象の文字列をSubstringすることで代替できます。しかしAnchoring Boundsを「常に使いたくない」場合、Regexクラスの外部でこれを実現する方法は無いように思われます。
この仕様はAPIからもドキュメントの記述内容からも想定できるものでなく、また統一が取れていないという点も考えると、意図的な設計結果とは思えません。本件は、改めてMicrosoft社に報告と確認をしておこうと考えています。
以下、各言語・環境での検証コードおよび検証結果を記します。なお言うべきことはすでに記したので、細かい説明はしません。興味のある方や再現してみたい気分になった方へ向けた情報です。
Azukiでは行ごとに3種類の編集状態を定義し、管理しています。具体的には未編集、編集済み、保存済み(一度以上編集されたが最後に保存された状態から変化していない)の3状態です。Azukiで3状態を扱うようにした背景は安直 … 続きを読む 行ごとの編集状態
本日は駄投稿です 🙂 何となくAzukiのソースコードの「ステップ数」を計測してみようという気分になったので計測してみました。計測に使わせていただいたのはコロ助というフリーソフトです。また計測したソース一式は2011/0 … 続きを読む Azukiのステップ数を数えてみた