/ 最近 .rdf 追記 設定 本棚

脳log[SakuraEditor: 2011-06-12~]



2011年06月12日 (日) ユニコード戦記─文字符号の国際標準化バトル」(小林龍生) なんだウニコードじゃないのか(せめて UNICODEにしてよね)。

最終更新: 2013-11-24T02:49+0900

[SakuraEditor] 選択範囲の復元。

GreenPad, Alphaは復元されない。復元する派にもいろいろある。

 メモ帳「UNDOで挿入された文字が選択状態になる」「キャレットは常に選択範囲末尾」

選択状態の復元ではない。キャレットの直前/直後の文字の削除を UNDOしても選択状態になる。

 Mery「UNDOで(入力や削除時点での)選択範囲が復元される」「キャレットの位置も復元される」

これ理想。(@2013-11-23 2.1.6から 2.2現在まで、矩形選択後文字入力をアンドゥすると矩形で再現すべき選択が線形の選択になってる。これは理想ではない)

 Firefox4のテキストエリア「UNDOで(入力や削除時点での)選択範囲が復元される」「キャレットの位置は常に選択範囲末尾」

惜しい。キャレットの位置が復元されないということは、選択範囲を延長できる方向が問答無用に決まってしまうということ。

 SakuraEditorと TeraPad「選択範囲は復元されない」「キャレットの位置は復元される」

最初はメモ帳の動作をまねて CDeleteOpeの UNDOと CInsertOpeの REDOに文字列選択処理を付け加えたらいいかと思ったが、メモ帳と違い挿入や削除の連続した操作がひとまとめにされないのと UNDOバッファが無制限なせいで、連続する一文字削除(入力)操作の UNDO(REDO)がすごくくどい。CDeleteOpeと CInsertOpeの直前に CSelectOpe(新設するクラス)を挿入するのが Meryと同じ挙動になって使いやすそう。(前にも Meryが選択範囲を復元してくれるのが良いと書いた>20091117)


とりあえずこんな感じ。>undo_selectarea.rev1.patch(4.5KiB, 2011-06-11, trunk2@1923ベース)


view/CEditViewへの依存を COpe.cppから view/CEditView_Command_New.cppへ移した。>undo_selectarea.rev2.patch(4.2KiB, 2011-06-12, trunk2@1923ベース)

COpe派生クラスの実装と再生は同じ場所で行ったほうがいいような気がするが確たる考えはない*。view/CEditViewと COpeは COpeの機能から考えたら必然的に仲良しさんだから依存関係なんて気にする必要ないぜ、というなごみんの声も聞こえたが現状はそうでもないのでためらう。今 COpe属はただの構造体として扱われてるので、それに従ってロジックをコンストラクタの中から呼び出し側に移した。呼び出しごとにコピペしてね。

削除し忘れたけど「CSelectOpeがあれば CMoveCaretOpeはいらないかもね。」というコメントは正しくない。CSelectOpeは今のところキャレット位置を保存せず、その場所には適当に選択終点を代入してる。Ctrl+Aで全選択したときにキャレットが動かないので、選択始点・終点とは別にキャレット位置を覚えておかなければいけないが、今はそうしてないので CMoveCaretOpeが必要。


不要にした。>undo_selectarea.rev3.patch(4.9KiB, 2011-06-12, trunk2@1923ベース)


 @2011-06-15 矩形選択範囲の削除をアンドゥしたとき

復元された選択範囲が正しくない。文字がない部分に選択範囲を広げられないためだ。それは、COpe属がすべてロジック単位(wchar_t列に対するインデックス)で情報を保存してるからで、その理由はたぶん、折り返し方法が変わっても対応できるようにだろう。TeraPadの readmeか何かで折り返しを変更するとアンドゥ情報がリセットされると読んだことからの類推。どうしようか。選択範囲なんてクリティカルな情報じゃないから、矩形選択時はレイアウト座標で情報を持っておくことにすれば大体はうまくいく、ってことで済ませていいんじゃないだろうか。

CLogicRangeや CLayoutRangeはコピーコンストラクタがあるから共用体のメンバになれない(C++98では)。CLogicRangeを CLayoutRangeに置き換えただけのコピペクラスを作るのか……。上のパラグラフで書いたことだけど、どっちを選んでも一長一短なのだし、矩形選択だからっていつでも選択終点がフリーカーソル状態ってわけでもない。できるだけ余計なことはしない方向で(やめとこ)。でもでも

 @2011-06-15 あれ?「常時選択範囲」って何だ?

選択始点の型がどうして CLayoutPointでなく CLayoutRangeなのか。答えがここにある。

 @2013-10-18 矩形選択文字入力のUNDO

矩形選択して選択した全ての行に文字を挿入するということをよくする。ABDと入力・挿入していって、間違えた、Ctrl+Z、Cと操作したいのだけど、Ctrl+Zした時点で矩形選択が解除されてるのでその後の Cはキャレットのある行にしか挿入されない。残念だ。


「残念だ」と他人事(ひとごと)のような気のない素振りを見せることでやる気をひねり出す天の邪鬼メソッド。似たようなものに「要望を書いて次の日になんとかするセルフサービス」メソッド。

矩形選択挿入/インデントを UNDO/REDOしたときにも選択状態を復元する>undo_selectarea.rev5.patch(13.1KiB, 2013-10-18, trunk2@1923ベース)

テストはしていない(キリッ でも自分用の sakuraW.exeには取り込んだので今日から使用中。

「呼び出しごとにコピペしてね」とは上の方で書いたが、CSelectOpe(ロジック単位の方)を作成するヘルパー関数をやっぱり用意した方がいいかもしれない。座標変換が煩雑なので。CEditViewに依存するので COpe.{h|cpp}に置くことはできないが、CViewCommander_New.cppと CEditView_Command_New.cppから利用したい。どこに置けるだろう。CViewCommander_New.cppには Command_INDENTがある。CEditView_Command_New.cppには CEditView::DeleteDataと CEditView::InsertData_CEditViewがある。Command_INDENTから呼び出される CEditView::InsertData_CEditViewで選択範囲の記録ができれば、ヘルパー関数の設置と利用は CEditView_Command_New.cppだけで完結する。それができないのは CEditView::InsertData_CEditViewがお節介にも選択範囲内のテキストを削除してくれるから、インデントを実現するために Command_INDENTが選択範囲をクリアしたり再設定したり小細工を弄する必要があって、Command_INDENT内でしか選択範囲を記録できないからだ。飛躍。エディタ(ドキュメント+ビュー)はプリミティブな操作と情報(検索、置換、選択、キャレット、ステータスバー、ダイアログなどなど)だけを提供して、各種コマンド(インデントとか検索とか)はそれらの操作を組み合わせるスクリプト(カスタマイズしやすい。オプションや好みを反映しやすい。依存されない(されにくい))であってほしかった。という感想は、CEditView::InsertData_CEditViewのようなフルスペックで融通の利かない大きな関数を、一部の機能を無理矢理引き算して利用するような状況から生まれてくる。


UNDO/REDOコマンド関数が Command_CANCEL_MODEを呼び出す部分に書いたコメント

Command_CANCEL_MODE()は主に範囲選択のクリアと選択ロックの解除を行う。
範囲選択のクリア(再描画あり)を行うと CSelect(L)Opeで範囲選択を復元したときにちらつく。
かといって、CSelect(L)Opeが含まれていないときは従来通りクリアを行いたい。
どうするか。再描画なしでクリアする。方法は Command_CANCEL_MODEに redrawフラグを渡すこともできるが
Command_CANCEL_MODEの中身をコピペしてフラグだけ書き換えることにする。

範囲選択を解除する必要があるのは挿入/削除操作(CInsertOpe/CDeleteOpe)の都合かも知れない。それらの Opeの再生部分に Command_CANCEL_MODEを移動するのが3番目の方法(選択のキャンセルに伴ってキャレットが移動させられないか注意)。そもそも(出た!)、Viewに挿入/削除を行う範囲を指示するパラメータが、独立した CViewSelectなり CLayoutRangeのインスタンスではなく、ユーザーから可視の選択範囲を意味する Viewのメンバ変数でもあるから、描画のフラグをオンオフしながら選択範囲をあれこれ操作しなければいけないってのが面倒の根本。Viewにはユーザーから呼ばれるものとしてそういうメンバ変数と結びついた関数があってもいいが(※)、その関数が利用するものとしてもう少し粒度の細かい汎用性のある関数が欲しい。※良くない。そういう、メンバと結びついたコンテクストフルな関数をコマンダーに置いて、汎用性のある関数を Viewに置こうという方向で分離が進んでいたのかもしれない。

COpeで一番に改善が必要なのはメモリ確保の戦略だという気もする。1単位の UNDO/REDOのためにひとつの COpeBlkとひとつ以上(4以下くらい。CSelect(L)Opeでサンドイッチすると+2)の C*Opeのインスタンスが newされるという現実をなんとか。

COpe派生クラス(CInsertOpe/CDeleteOpeとか)の再生の前後でキャレット位置を復元するのは COpe共通のタスクとして実装されている。前後の選択範囲の復元も COpe共通のタスクにしてしまってよいかも。そうすると選択範囲のクリア、範囲の設定、テキストの挿入/削除、範囲のクリアという CInsertOpe/CDeleteOpeの手順と CSelect(L)Opeサンドイッチがひとまとめになって、空間効率も処理手順も無駄がなくなる。派生クラスの種類が減ってサイズが同じになるならメモリ戦略の実体も一本化できそう(まあ、やらないんだけど)。

 @2013-10-20 選択モード(SelectingLock)も復元すべき?

そういうのはまとめて CViewSelectのコピーコンストラクタと代入演算子の仕事ではなかろうか。できるかな。そして、もしそういう操作が Viewの外に公開されてるなら CViewSelectのインスタンスを通して Viewの選択状態を変更できる setterの存在が期待されるわけだ(Viewのメンバの CViewSelectのメンバの m_sSelectを直接書き換えるとか主権侵害言語道断)。

* @2013-10-18 COpeに本物のポリモーフィズムを導入するとかいうこと。そうすると COpeの派生クラス(CSelectOpeとか)の新規導入が UNDO/REDOの実行者から不可知のまま行えるようになる。


2011年06月05日 (日) Cannondale BAD BOYを見つけたのって、たぶん中学生のときから使ってる財布のせいだ。それを何かの折にネットで検索した。2003年頃。

最終更新: 2011-06-05T22:03+0900

[SakuraEditor] 固定長のタイプ別設定って

タイプ別設定一覧ダイアログの見せ方だけで、並べ替えたり可変長に見せかけて(実は上限は30で変わらない)削除・追加を受け付けたりできるよね。

それが行われるとファイルタイプを選択するツールバーボタン(リスト)のアイテムの並びも考えないといけなくなるけど。


2011年06月02日 (木) ATOK2009の補完はいまいち。一度入力した単語は二度と最後まで入力したくないのに、一度は候補に出てきた単語がどんどんどんどん忘れられていく。あと、最長の候補が最初から出てこない。同じ文章を再入力するときでも、末尾の一語だけしか補完できないなんてことがよくある。

最終更新: 2011-06-04T20:36+0900

[SakuraEditor] 文字の幅。代替表示。色分け・強調。

日本語文字が半角。 画像の通りに、メイリオUIをインストールしてから日本語文字(Consolasにリンクされたメイリオ)が半角になる。メモ帳もそう。素のサクラエディタでは半角表示の日本語に全角のマス目を割り当てて字間に謎の空白が表示される。画像でそうなってないのは CNativeW::GetKetaOfCharを、文字コードの範囲によらず常にフォントを通して字幅を得るようにいじったから。性能に大いに悪影響を与えるだろう。気にならないけど。で、それだけだと Deleteキーを押したときにキャレットと離れた位置の文字が消えるようなことが起こる。そういうときはキャレットの左側に□で表示された全角空白があったりする。(半角で表示される)全角空白を(半角で表示される)□と表示する view/figures/CFigure_ZenSpaceが□を描画した後にカーソルを無条件で 2進めるために CNativeW::GetKetaOfCharの返す値との間に齟齬を生じていた。文字の幅や高さをコードポイントから決めることはできない。それは代替表示や部分強調も絡めてビューが決めること。


2011年06月01日 (水) あかん。r1921をマージするのは死ねる。ファイル構成(※)が違うし名前が違うし DoChangeColorとかもうないし。※SColorStrategyInfoは CColorStrategyのインターフェイスの一部(CColorStrategy.hの中に入れるもの)ではなく、その利用者 CEditViewに属するものだと思うんだよね。本来無関係な CEditViewの一部を取り込んでおいて #include "view/CEditView.h"(※2)とか、その引きずってるものの大きさを考えたら気違い沙汰ですよ。と思ったので色分けを SHJS方式にしたときに構成を変えたのだった。※2 #includeはコメントアウトされてるように見えるけどヘッダの中で Viewのメンバを呼んでるからむしろ何でそれでOKなの? .cppに移動させてもリンクのコストが無駄に増えるのは変わりない。CColorStrategy.hをインクルードする他のファイルに無駄な依存を伝播させることはなくなるけど。### r1921のマージはアイディアを借りた再実装と同じだとわかった。だったら今はやらない。

最終更新: 2011-06-11T02:05+0900

[SakuraEditor] BugReport/82 - SakuraEditorWiki 正規表現検索の不具合

ここに犯人がいます。言い訳すると、これは見逃してもしかたがないと思うの。(補記だし存在しない機能だし)

 補記 3. Perl 5.8.0と比較して存在しない機能
 + \N{name}
 + \l,\u,\L,\U, \X, \C
 + (?{code})
 + (??{code})
 + (?(condition)yes-pat|no-pat)

 * \Q...\E
   但しONIG_SYNTAX_PERLとONIG_SYNTAX_JAVAでは有効

bregonig.dllは ONIG_SYNTAX_PERL_NGを使ってるみたいだから \Q...\Eは有効。bregexp.dllは \Q...\Eをサポートしていない。

パッチはこれ。>regex_trick_coping_with_qeescape.patch(13.3KB, 2011-06-01)

テストケースはこれから整理する。(パターン内でのコンテクスト×エスケープシークェンス×正規表現ライブラリ)


 @2011-06-02

テストマクロを書いた。>test_regex_trick.js(5.0KB, 2011-06-02)

そうすると、\c\\ みたいなパターンに対応できていないことが新たに判明した*。ちょっとだけ修正したパッチはこれ。>regex_trick_coping_with_qeescape.rev2.patch(13.3KB, 2011-06-02)

手もとでは bcc32で作成した sakura.exe(1.6.6.0 with bregonig-1.45)と VS2008EEで作成した sakura.exe(2.0.2.0 with bregonig-2.02)、ともに Revision 1922ベース、ですべてのテストに成功する。逆に、パッチなしだと期待した通りに失敗する。


 @2011-06-10

掲示板>1571

コミット>r1923

* 違った。もうシラネっていってたやつだ。たぶん。


2011年05月09日 (月) 原文を見なくてもわかる日本語訳のミス。>「グーグル社員の間でも、黄の社員証の階級はほとんど知られていない。彼らのビルは3.1459~という棟で、

最終更新: 2011-05-10T18:49+0900

[SakuraEditor] Re: 正規表現による複数行検索対応(簡易版)

 GetCountOfDividedStringW()はいけてない。

どういう関数?>「改行のエスケープシーケンス('\\'+'n')で区切られる文字列の個数を数える(WCHAR版)」

使われ方>「複数行指定方法の改善(正規表現パターンの行数とダイアログ設定値の大きい方を採用する)」

  • \rに対応していない。
  • LFの直書きに対応していない。(CRの貼り付けはできなかったのでとりあえず LFだけ)
  • 量指定子に対応していない。
  • \x0D\x00\x0A\x00や \x{0D}\x{0A}に対応していない。
  • [\s\S] や \s, [\w\W] や \W, . (sフラグONのドット)に対応していない。

これだけ対応していないなら「正規表現による」というより、\nというエスケープシーケンスにだけ対応した普通の検索といったほうが当たってる。正規表現ライブラリに今以上の機能(hitEnd)を求めないのなら、これが最大限度の対応なのかもしれないが……。GetCountOfDividedStringWには期待せず、ダイアログで 100とか設定しておけば大体はうまくいくのかもしれない。

 CMultiLineSearch::GetCompensationLengthには脱帽。

どういう関数?>「0文字マッチや改行文字の途中を考慮した置換文字数の補正値を取得する」

なぜ必要?>ドキュメントの操作がビュー経由でしか行えないため、ロジック単位で行った検索をレイアウト単位に変換してから置換を実行しなければいけない。置換関数の中ではレイアウト単位をロジック単位に変換して……といったことがもちろん行われるわけで……ムキー、ってなことを 20100907p01.03に書いた。

とりあえずロジック単位で置換範囲を指定できる置換関数をどこかに作ろうとして、20100709p01の複数行置換の実装は止まっている。CMultiLineSearch::GetCompensationLengthを使うアプローチはこれまでのやり方を踏襲するもので、置換範囲と置換文字列をレイアウト単位境界にそろえてから置換関数を呼び出す。計画倒れよりできあがってる方が偉い。


2011年04月20日 (水)

最終更新: 2011-04-21T03:20+0900

[SakuraEditor] Regarding: Request/359(CSV編集モード) - SakuraEditorWiki

TSVだったら、タブ幅が可変になればよさそう。列ごとにフィールドの最大幅より1文字分だけ右側にタブストップがくるようにすると表形式に整列される。ファイルを最後の行まで読んで調べないとレイアウトを決定できなくなるのがデメリット。レイアウト↔論理座標変換も工夫しないと遅くなる。この変換は検索などでやたら無駄に呼び出されるから速度低下は増幅される。CSVなら、カンマの幅を半角文字○個分扱いするのかな。一文字編集するたびに画面全体の再描画が発生するケースもあるけど気にならない程度? 列を指定してソートできる秀丸さんかっこいい。タブストップを自由に設定できるというから、タブストップの位置を配列で持ってんのかな。タブ幅だけを覚えておいてその倍数がタブストップ、という現状にくらべると記憶領域も検索コストも必要になるけど、せいぜい人間が管理できる程度の数にしかならないだろうし。桁位置(64bits)×タブストップの数(10000)=80KBで十分過ぎるくらいか。


2011年04月06日 (水) zenback を入れてみた」一点にだけ注目していた。期待は裏切られなかった。コメントの後に ZENBACKが表示されるのがイイ。そうでないと、読もうと思ったコメントが遅延ロードされた ZENBACKに押しやられて逃げていってしまうから。追記@2011-04-07:「zenbackをツッコミ欄の後ろに表示させた一件 - kayakaya日記(2011-03-28)」 突如わいてきた(ように見えた)要望の目的は最初からそこにあったのね。スクリプトを埋め込むのに tDiary本体の修正が本当に必要?って思って、danなにがしさんの(コメントが逃げる)ブログを Firebugで覗いてみたりしてたのよ。この後者のエントリを発見したのが、前のエントリの関連リンク(powered by zenback)だってんだから有用性は疑いえないな。

最終更新: 2011-04-14T01:54+0900

[SakuraEditor] BugReport/70 - SakuraEditorWiki

まったく、CViewCommander::Command_REPLACE_ALL ってのは人類の理解の範囲を超えている。

  • 通常選択範囲を置換
  • 矩形選択範囲を置換
  • ファイル全体を置換
  • 対象範囲を行単位で置換
  • 対象範囲をひとつのマッチごとに置換
  • 正規表現ライブラリを使って置換
  • クリップボードのテキストに置換
  • クリップボードの矩形テキストに置換
  • 置換ではなく前に挿入する
  • 置換ではなく後ろに挿入する

これ、あえて異なる複数の分類を一括りのリストにしてるけど、実際のコードがそうなのだ。こんな処理が一つの関数の中に、変数を共有しながら―しかも型を偽って本来とは違う使い方が特定の処理ルートではなされていたりする―、一部の処理を共有しながら、インターリーブされてる。

BugReport70.patch (1.7KiB, 2011-04-07 02:50)

submit(<commit以前)はしない。怖すぎる。


「「すべて置換」は置換の繰返し」フラグが ONのときの対策がまだ。

コミットログも読まずに軽率な修正。>BugReport70.rev2.patch (2.7KiB, 2007-04-07 06:50)

これから読む。>「SourceForge.net Repository - [sakura-editor] Revision 1049」, 「SourceForge.net: Sakura Editor: Detail: 1636751 - 行置換のオプション化&問題修正

うむ。削除したコードがなぜあえて論理座標だったのかわからない。


 @2011-04-11 「// 行単位で置換するので colDifは常に 0。」

って書いて削除したコードがパッチにあるけど、一つの行が複数のレイアウト行に分割されてることがある。一行処理して次の行……と思ったらまだ折り返された同じ行にいた、とか。前にも別件で書いてるけど、折り返しと矩形選択(+文字一括挿入/+置換)は本当にひどい組み合わせ。結果を予測できるものにするためには選択範囲の末尾の行から処理をしないといけない。そうすると文字の削除や挿入による折り返し位置の変化が後の処理に影響を与えないので。でもそうはなってない。だから、結果を維持する労力を割く必要もない「未定義」の動作だと考えてしまう。


2011年02月10日 (木) 「それは仕様です」ってそんなに嫌いではない。発言者にその宣言を遵守する意志があるのなら。言われた方はその宣言を以て、即座にその仕様(と手元の実装)に依存できる。言った方は修正の手間がないし、挙動を変えて周囲(期待と実際の違いに気付いていなかった方の集団)を騒がせるおそれもない。とはいえ一般には「仕様のわけねーだろ。バグだよ、バグ」って言いたくなるようなものに対して「これは仕様でしょうか?」ってのも嫌みったらしく聞こえそうなので控えたい。何回かやってるけど。

最終更新: 2011-02-11T00:59+0900

[SakuraEditor] SourceForge.net Repository - [sakura-editor] Revision 1887

Fix: 検索(ツールバー)を使うとプラグインコマンドが実行される(2)

検索ボックスのコードをほとんどコピーした自作ツールバーボタンもやばい気がするものの、CBN_SELCHANGEはツールバーボタンで処理してるんだよね。処理しなかったメッセージが誤った取り扱いを受ける、ということなんだろうか。わからないよん。

>>脳log[2008-06-04-p01] 現在適用されているファイルタイプを表示/変更するツールバーボタン


2011年01月29日 (土)

最終更新: 2011-04-09T19:20+0900

[SakuraEditor] サクラエディタに複数行検索を導入する際に考慮する必要がある正規表現パターンへの細工。

今のサクラエディタはユーザーが入力したパターンに細工を施している。>「正規表現を使った検索・置換で、改行の意味を LFのみから CRも含むように。

サクラエディタでは改行をまたいだ検索ができないけど、将来できるようになると問題が生じる。(その根拠は20100709p01の実験による)

  • ^(改行文字の直後にマッチ)が CR直後(かつLF直前でないことが望ましい)にマッチしないことが露見する。
  • $(?<![\r\n])(?=\r|$) に置き換える現在の細工では、連続する改行と改行の間にマッチできない。

^(?:(?<=^|\n)(?=[\s\S])|(?<=\r)(?=[^\n])) に、$(?=\r\n?|(?<!\r)\n|(?<![\r\n])$) に置き換えるのでいいかなあ。用意した入力が期待した結果になるのは確認したけど、予期しない入力が予期しない結果になる可能性はやっぱりある。

 ^ や $ を、先読みや戻り読みを使ったパターンに置き換えることの副作用

戻り読みの中に ^ や $ を置けなくなる。複数行検索ができるようになったときには、戻り読みの中で行末を検知したくなることもあるかもしれないね。でも、できないね。


2010年10月15日 (金) Adobe Readerや Quick Timeをアップデートしたくないのは、たまにしか起動しない Adobe Readerやたまにしか利用しない Quick Timeのために Windowsのスタートアップを遅くして欲しくないのと、無効化していた Firefoxの PDFプラグインをアップデート後にもう一度無効化しなければいけないのが極めて面倒だから。Quick Timeはアンインストールしたけど Adobe Readerとは手を切れそうにないのがつらい。それと、スタートアップに Flash Playerのアップデートタスクを登録しても無駄だから。再起動が必要な Windows Updateをひと月ふた月待つつもり?

最終更新: 2010-10-15T10:51+0900

[SakuraEditor] Meryの、ローカル変数の定義位置・次(前)の使用位置に飛ぶ機能(違

93 :名無しさん@お腹いっぱい。:2010/10/15(金) 01:30:28 ID:hD6Ahu8Z0 
マウスだと何が良いのかあんまりわからない気がする。 

1.マウスで文字列選択 
2.メニューで[次の文字列を検索]or [前の文字列を検索] 

がマウス操作の基本だと思うけど、Ctrl+F 同様に単語の選択が必須ではなくて 

1.検索したい文字列かその直前にカーソルを置く(マウスのダブルクリックで選択される範囲に相当) 
2.キーボードで Shift+Ctrl+↓or Shift+Ctrl+↑ 

みたいにいきなり検索&ハイライトができる。もちろん単語というか検索語句に応じて 
文字列選択はしたりしなかったりなので、必ずしも文字列を選択しなくていいという訳でもない。 

個人的には編集中に文字列をちょっと連続で参照して元の場所に戻るのが特に便利。 
直前or直後なら2アクションで参照して戻ってこられるし、連続でポンポンと参照して戻ってくるのも直感的で分かりやすいキーボード操作になる。 

次を検索[F3] では良くも悪くも、検索する文字列に縛られるのが利点ではあるものの、ちょこっと確認したいときには不便。 
というか F3 と別系統で検索が可能になるので、F3 での検索文字列を維持できるようになるのが地味に便利。 

個人的に感じているメリットはこんなところ。

すげー使いたい。そして、こういうことを実現できない(よね?)サクラエディタのマクロに幻滅。あれってただのコマンド集(しかも公開を目的としていない)だし、キャレットの位置を知る方法が Editor.ExpandParameter("$x,$y") とか、やっつけ仕様過ぎ。きちんとしたオブジェクトモデルが必要だ。

本日のツッコミ(全4件) ツッコミを入れる

名無しhttp://sakura.qp.land.to/?Macro%2F%C5%EA%B9%C6%2F153

名無し「Wiki Macro/投稿/153」がまさに相当するマクロだと思うけど。 他にも関連マクロで「Wiki Macr..

名無しVisual Studioが本元かな? 調べてみたらEmEditor Freeにも同じ動作の 次の文字列を検索(Ct..

ds14050おおぅ。まさしく。 「ダブルクリックで単語ハイライト」とか聞いたことがあるけど、あれの変種でしたね。図らずも VC..


2010年09月21日 (火)

最終更新: 2017-10-13T21:42+0900

[SakuraEditor] (2ch) 選択領域の描画が反転に固定されてるのが嫌だ、半透明がいいというが。

半透明選択 反転選択

眠たくないですか? ラスタオペレーションをセットして領域を塗りつぶすだけの操作に比べてビットマップビットを操作する手間をかける価値があるだろうか。Windowsでの標準的な描画方法は、背景を選択領域(背景色)で、文字を選択領域(文字色)で塗るだけみたいだけど。どうして半透明? それともさらに手間をかけて半透明の選択領域を単色からグラデーションパターンにするぐらいやるんだろうか。AeroGlassがそんな風に微妙なパターンを入れてる。どうやったらグラデーションが表現できるのか知らんけど、ピクセル当たり 1バイトで表現できるなら GDIブラシでパターンを塗り込めておけるかも。

 余談

  • 左の画像のステータスバーに文字が少ないのは、エディタを一回非アクティブにして再度アクティブにしたときに消えるから。バグじゃないよ。
  • 選択領域の描画は CEditView::DispTextSelected() と CViewSelect::DrawSelectAreaLine() の少なくとも二カ所で行われてる。この DRYじゃない実装や、反転の反転で元の状態に戻したりしてるのが、選択領域のかすが残る度々の不具合につながってる気がするんだけど。画像のエディタは CViewSelect::DrawSelectAreaLine() には手を付けてない使えないはりぼて。
  • 選択領域の色設定画面 「文字色」が領域の色。「背景色」が RGB各バイトのα値。透明度を上げていくと背景色は黒に近づいてみえる。色分けするかどうかのチェックが外れてるときを従来通りの反転描画に割り当てたので Windowsの標準的な描画方法を指定する方法がない。

 @2010-09-23 あるいは

テキストの背景色と XORをとったときにユーザーの指定した色になるような色を使って排他的論理和をとってみたりするとどうなるだろう。コントラストを保ちつつ選択領域の全体的な色をコントロールできるのだろか。


やってみた。

//HBRUSH hBrush    = ::CreateSolidBrush( SELECTEDAREA_RGB );
HBRUSH hBrush    = ::CreateSolidBrush( selColorSetting.GetBackColor() ^ CTypeSupport(this, COLORIDX_TEXT).GetBackColor() ); // assuming SELECTEDAREA_ROP2 == XOR

わりと文字がつぶれる。つぶれないような色を選ぶと上左の画像のような淡い色になってしまい、だったら半透明でいいじゃない? 変更が一行で済むのだけが利点。半透明の方はざっと抜き出してもこんなに。

CreateCompatibleDC( hdc );
CreateCompatibleBitmap( hdc, rcClip.right - rcClip.left, rcClip.bottom - rcClip.top );
SelectObject( hdcMem, hbmpSelected );
BitBlt( hdcMem, 0, 0, rcClip.right - rcClip.left, rcClip.bottom - rcClip.top, hdc, rcClip.left, rcClip.top, SRCCOPY );
GetObject( hbmpSelected, sizeof bmpSelected, &bmpSelected );
GetDIBits( hdcMem, hbmpSelected, 0, bmpSelected.bmHeight, pBits, &bmpinfo, DIB_RGB_COLORS );
for (RGBQUAD* pQuad = pBits; pQuad < pBits + bmpSelected.bmWidth * copiedLines; ++pQuad)
SetDIBits( hdcMem, hbmpSelected, 0, copiedLines, pBits, &bmpinfo, DIB_RGB_COLORS );
BitBlt( hdc, rcClip.left, rcClip.top, rcClip.right - rcClip.left, rcClip.bottom - rcClip.top, hdcMem, 0, 0, SRCCOPY );
DeleteObject( hbmpSelected );
DeleteDC( hdcMem );

GetDIBits, for, SetDIBitsあたりがやばいかんじ(速度的に)。


 @2010-09-25

半透明処理にすると、反転の反転で元通りみたいなことができなくなるのだよね。反転処理前のビットマップを保存しておかなければ戻せない。あと矩形選択で行っていた、リージョンを結合して差分をとって PaintRgn一発で選択解除と選択描画のできあがり、ということができない。矩形選択なんて四角を一個塗るだけで済むはずのものなのに……。クライアント領域をいくつかのレイヤーに分けたいなあ。背景<文字の後ろ(罫線など)<文字<文字の前(アンダーライン、対括弧強調など)<選択領域<キャレット みたいに。Z座標でなく更新頻度でわけるのもあり。半透明にすると他にも、左に選択範囲をのばしていくとキャレットの残像が次々増えていく問題が。くじけそう。きままにやるけど。


 @2010-09-26 transparent_selection(trunk2@1825).patch (21.8KiB)

非効率的なのを承知で CViewSelect::DrawSelectAreaLine() で行っていた処理を CEditView::OnPaint() に委譲した。それが選択描画を取り消すのに一番簡単だったから。Vistaだと確認できないけど古い Windowsだとフリッカーがひどいかもしれない。気付いたのは検索を行ったときにカーソル行アンダーラインがちらつくことが増えたこと。範囲の拡大・縮小も遅い。<追記@2010-10-15>再描画する領域を最小限にする努力が必要。でも重なった二つの矩形が作る領域をどう扱ったものか(9つに分割して、左上↘右下、左下↗右上、左上↖右下、左下↙右上で網羅できるものなのか、もっと簡単にできるのか)、悩み中。</追記>


 @2010-10-03 2chスレ見て

選択色指定(固定色or半透明)のお試し版がすでにあるとか。なんだよもう。ソース読も。

725 :名無しさん@お腹いっぱい。:2010/10/03(日) 03:45:30 ID:FVNsnn5V0
ちなみに、「下の全部」というタイトルで以下のような物も公開されている。
> 状態:アルファ
> bin/pp-disable: skrw_ext13_bgimg_100929.zip Unicode版1.6.5.0 base r1827
> bin/pp-enable: skrw_ext13_bgimgpp_100929_pp.zip Unicode版1.6.5.0 base r1827
> 背景テストデータとini: bgimage 111KB
> diff:skrw_ext12_to_ext13bgimgpp100929.zip 78KB ext12からの差分,テスト未整理コードあり
> ext+背景表示+プロポーショナル
> ClaerType対策に選択文字列の作画表示の実装を追加。OFF→従来のように反転,色指定→固定色,文字色=背景色→元の色と20%で色混合)で設定
> 改行文字の色指定を変更。ベース色<改行の指定色<検索色<選択色。
> pp-enableのほうだけプロポーショナルが使えます。その分動作はあやしいです。
>
> r1827/100929/ext13+bgimg v0.4+ppfont v0.2(バージョン情報ではext12になってます)
> 選択色指定:デフォルトで色指定になっています。色分けをOFFにすると戻ります。0幅表示未対応
> ・[ext/skrw_search_fast_v0_0]rev1827の大文字小文字変換対応。skr_toupperに切替
> ・[ext]DIFFのデフォルト設定色のRとBが反対だった(iniはBGR順でした)

プロポーショナルフォントが指定できるとメイリオが選べて嬉しい。次は Operaのようにブロック単位でフォントを指定したい。英字は Consolas、日本語はメイリオ、ひらがなは……、カタカナは……というように。


プロポーショナルフォント関連のあやしい動作を一つ発見 >skrw_ext13_bgimgpp_100929 矩形選択で文字のないところを右側に範囲を拡大していくとキャレットが 1pixelずつくらい移動するんだけど、このとき画面が横にスクロールするとルーラーが逆行する。7戻って15進むという具合につじつまは合うみたいだけど。改行の後ろの選択範囲の描画もずれる。


ソース読んだ。選択範囲の半透明処理って、「テキスト」「コメント」「URL」などなどの文字の色と背景色をずらすだけでできたらしい。なんだよもう(二度目)。

CRLFマークがはみだすことの対策もあった。3ピクセル出てるらしい。上の画像ではみだしを確認できるけど、みっともないもんね。改行マークが非表示だと選択範囲が右にちょっとはみ出して見えるのもみっともないと思ってるんだけどどうだろう。

 フェイズとレイヤー。WebKitの例。(@2014-01-18)

WEB+DB PRESS Vol.54 - WebKit Quest 第5回を読んでる。フェイズはレイヤーより細かい区分。

paint()メソッドを呼び出す側は、何度もpaint()を呼び出します。その際、指定されるPaintPhaseは背景から前景へ推移します。

WebKitはフェーズの数だけ何度も Renderツリーをトラバースし、各フェーズを重ね描きすることでページの描画を行うのです(図5)

enum PaintPhaseのメンバーはこれで全部ではないけどこんなかんじ

  • PaintPhaseBlockBackground
  • PaintPhaseFloat
  • PaintPhaseForeground
  • PaintPhaseSelection
  • PaintPhaseOutline

レイヤーが必要な場面はこれより大局的な

  • z-indexが指定されたとき
  • transformが指定されて座標変換が必要なとき
  • opacityが指定されて透過するとき
  • など

エディタ領域の描画はフェイズで十分そうね。

本日のツッコミ(全2件) ツッコミを入れる

Mocaいつもお世話になってます。 色の合成は、指定色で選択作画を書く→ここをみる→混ぜればできるのを思い出して追加の順だっ..

ds14050後半の意味がわからないと思ったら、ANSI版では改行マークの表示・非表示に関係なく改行マークの背景色が塗られていた。..


2010年09月15日 (水)

最終更新: 2013-01-11T22:45+0900

[SakuraEditor] 拡張子のないファイルにもタイプ別設定を自動適用する。

どこかに書いた気がするのに見つからないのでもう一度。

サクラエディタは拡張子を見てファイルの種類を区別し、色分けルールやタブ幅、折り返しルールなどを使い分けるが、拡張子がない makefileや ChangeLogはみんな「基本」設定になってしまう。

 案1: 「拡張子」ではなくファイル名の末尾に対するマッチングでファイルタイプを区別する。

ファイル名の末尾が .rb だったら Ruby。.js だったら JavaScriptという具合。ファイル名の末尾(といいつつ全体)が makefileだったら makefile、.htaccessだったら Apache HTTPD設定ファイル。

ところがサクラエディタが設定として持ってる、判別のための拡張子リストが

c,cpp,cxx,cc,cp,c++,h,hpp,hxx,hh,hp,h++,rc,hm

という具合に、「ドット省略必須」「スペースorカンマorセミコロン区切り(ヘルプによればカンマ区切りらしいが、「,」と「.」が紛らわしいのでスペース区切りにするのがいいよ)」のリストなもんで、この案は没。広まってしまったドット省略拡張子リストに対処することができないので。

 案2(採用): 「拡張子」がないときはファイル名を拡張子として扱う。

makefileを .makefileだとみなしてファイルタイプを判別するということ。

パッチ> guess_filetype_of_extlessfile.rev2.patch (0.9KiB)

JSという名前のファイルが拡張子が .jsの JavaScriptファイルだとみなされることになるけど、気にしないよね。

 @2012-11-04 moca_skrさんによるパッチ。

>>SourceForge.net: Sakura Editor: Detail: 3581841 - タイプ別設定の拡張子を二重・なしにも対応

0 < _tcslen が使われてないところが好み。zero fill(""での初期化)するかしないかに強い意見はない。結局呼び出した関数が null-terminateするかギリギリまで書き込むかに依存するのだから。自分に影響がありそうな部分にコメントした(試してないので勘違いかも)。


杞憂だった。恥ずかし。GetDocumentTypeOfExtはパッチだけでは全体がわからないから元のファイルにあたってみて、その後でパッチの追加部分に戻ってくるのを忘れてた(という言い訳)。


GetDocumentTypeOfPathでごちゃごちゃせずに、引数として渡されたファイルパス(pszFilePath)をたどって最後のパスセパレータの次の位置を指すポインタを GetDocumentTypeOfExtに渡すだけにしたらすっきりするのに、と思った。a...............................................b.txtみたいなファイルでスタックオーバーフローを起こすだろうか。


@2012-11-06 ちょっと臆病になってここに書くけど、二重拡張子探索のためにファイル名からピリオドを探索するときに _tcschr を使ってるけど _tcsrchr ではないのかな。_tcschr を使ってるなら、すぐ上に書いたようにバッファの確保も _tsplitpathも省いて _tcsrchr(pszFilePath, TEXT('\\'))で得たポインタ+1を GetDocumentTypeOfExtに渡すのと似た結果になりそうだが。

_tcsrchrを使うには表(Shift_JISだと2バイト目が\と同じ)のような文字対策が必要で、_tsplitpathはそういうのも隠蔽してくれてるのかな。だとしたら似た結果にはならないか。

再度考え直し。_tcsrchr が _mbsrchr にマップされる可能性。_mbsrchr はうまくやってくれるのだろうか。

こんなんだからこそ JScriptでパスを扱うときは必ず

new ActiveXObject("Scripting.FileSystemObject").GetFileName
new ActiveXObject("Scripting.FileSystemObject").BuildPath

を使って、自分で文字列処理をしないのだけど、_tsplitpath が拡張子付きのファイル名を返してくれなかったりするから自前でやるはめに。Cだから固定長バッファが前提でその長さが問題になってくるからかもしれないが、ケチるんだったらポインタで返してくれたらいいのに。引数のここからここまでがファイル名ですって。正規化したいから無理だって?


 @2012-11-13

..............................................................................................................................................................................................................................................t

というファイル名を、trunk2@2457 + skr_imp_ext_ex.patchで、試してみたけれどスタックオーバーフローは起こせませんでした。ピリオドの数よりちょっと少ないくらい GetDocumentTypeOfExtが呼ばれる(二重拡張子でなく多重拡張子をテストしてる)のは確認できたけれど。

 @2013-01-11 コミットされています。

http://sourceforge.net/p/sakura-editor/code/2565/

そういう機能が欲しいと思ったから自分でも改造してたんだし喜ばしいことなんだけど、自分でビルドするサクラエディタに反映するとコンフリクト必至なのが憂鬱。

 RUNESOFTのインストーラが、ユーザーがインストール先を変更したときに、レジストリに記録するインストールフォルダ末尾に \ を付け忘れてしまい、おそらくファイル名を連結するときに \ を補わなかったのだろう、ゲームの起動に失敗するというポカをやらかしていた。


2010年09月07日 (火)

最終更新: 2010-09-15T20:40+0900

[SakuraEditor][正規表現] 検索。置換。

Command_REPLACE(置換)や Command_REPLACE_ALL(すべて置換)が Command_SEARCH_NEXT(下検索)を呼ぶのをやめたい。連携手段がレイアウト座標を基にした選択範囲しかなく、一文字で表現される CRLFの LFだけがマッチしたときに情報が欠落するし、Command_SEARCH_NEXTが持つ検索以外の事前・事後処理が無駄になるし、正規表現検索が BMatch(検索), BSubst(検索&置換)の計二回行われるのも無駄。

wchar_t単位で検索を行う CSearchAgent::SearchWordが、検索結果をレイアウト座標に変換する際の誤差(前述)を考慮してマッチ範囲を拡大し、結果を不正確なものにするのは誤りだと思う。それより、上の層でこれを呼び出している CLayoutMgr::SearchWordがその配慮を行うべきでは。

 あったらいい操作

Match
対象文字列の対象範囲全体がパターンに一致するか調べる。
Search
対象文字列の対象範囲からパターンに一致する部分を探す。
Replace
対象文字列の対象範囲からパターンに一致する部分を探し、与えられたフォーマットの文字列に置き換えた文字列を返す。(返るのは対象文字列の対象範囲に相当する文字列)
Expand
Matchや Searchの結果を用い、マッチ全体($0)を与えられたフォーマットの文字列に置き換えた文字列を返す。
パターン
BREGEXP.DLLは m/pattern/flags/pattern/replace/flag も同じ一つのパターンとして扱うので、検索用のパターンと置換用のパターンに互換性がない。そうではなく、Search(Compile("pattern", flag), "target", startindex), Replace(Compile("pattern", flag), "target", startIndex, "replace") だったら良かった。(※ "pattern" と "target" と "replace" は実際は二つの引数で表す)

bregonig.dllや bregexp.dllを使いながらパターンの共通化や Expandの不足に対処するにはどうするか。自分で Expandを実装し、dllが用意した置換機能(置換パターン)を使わないで済ませる。でもねえ、実装の数だけ仕様がある状態を避けたいから Expand機能をライブラリに用意して欲しいわけで。(置換文字列の $$ が $に展開されなかったり、\1 が展開されたり、$1が展開されなかったり、色々あるんよね)


 @2010-09-10 悪夢のような「クリップボードから貼り付ける」置換オプション。(本当は矩形選択が)

  • CRLFの CRだけや LFだけをクリップボードの内容で置き換えることができない。
  • 正規表現検索のとき検索始点(終点)挿入オプションがきかない。
  • クリップボードの形式が矩形テキストだったときに検索条件によっては無限ループ。

    例えばクリップボードに

    789
    456
    123

    という 3行9文字(改行文字はない)がおさめられているとき、マッチと置き換えられるのは 789 であり、456 123 はそれぞれ次行、次々行に挿入される。つまり、456 123 はこれから検索対象になるということだ。検索条件が \d{3} だったり ^ だったり、矩形テキストの二行目以降にマッチするものだったら無限ループ。

置換操作が二階層潜らないとロジック単位にならないというのも悩みの種。検索はロジック単位で行えてるのに、それをレイアウト単位に変換してそれがさらにロジック単位に変換されて、一対一対応じゃないからごにょごにょしないと思い通りに置換されなくて。

 @2010-09-15

どうして最上層のレイアウトを基準にして文字列処理を行わなければいけないか。文書(wchar_t列としておく)の変更を LayoutMgrに通知する仕組みを整備するのを怠って、LayoutMgrを通して文書の変更を行うことで通知を不要にしていることが背景にあるのでは? GUIを通しての文字列操作に限ってはそれで十分だからそうなるのも仕方ないし、必要に迫られた人間(俺とか)がより汎用的な手段を整備せずにダーティハック*に頼る方が罪は重いかも。

* 挿入位置・置換範囲を文字レイアウト境界まで拡大して、挿入・置換文字列も同じだけ拡張する。