最終更新: 2010-10-15T10:51+0900
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")
とか、やっつけ仕様過ぎ。きちんとしたオブジェクトモデルが必要だ。
最終更新: 2017-10-13T21:42+0900
眠たくないですか? ラスタオペレーションをセットして領域を塗りつぶすだけの操作に比べてビットマップビットを操作する手間をかける価値があるだろうか。Windowsでの標準的な描画方法は、背景を選択領域(背景色)で、文字を選択領域(文字色)で塗るだけみたいだけど。どうして半透明? それともさらに手間をかけて半透明の選択領域を単色からグラデーションパターンにするぐらいやるんだろうか。AeroGlassがそんな風に微妙なパターンを入れてる。どうやったらグラデーションが表現できるのか知らんけど、ピクセル当たり 1バイトで表現できるなら GDIブラシでパターンを塗り込めておけるかも。
テキストの背景色と 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あたりがやばいかんじ(速度的に)。
半透明処理にすると、反転の反転で元通りみたいなことができなくなるのだよね。反転処理前のビットマップを保存しておかなければ戻せない。あと矩形選択で行っていた、リージョンを結合して差分をとって PaintRgn一発で選択解除と選択描画のできあがり、ということができない。矩形選択なんて四角を一個塗るだけで済むはずのものなのに……。クライアント領域をいくつかのレイヤーに分けたいなあ。背景<文字の後ろ(罫線など)<文字<文字の前(アンダーライン、対括弧強調など)<選択領域<キャレット みたいに。Z座標でなく更新頻度でわけるのもあり。半透明にすると他にも、左に選択範囲をのばしていくとキャレットの残像が次々増えていく問題が。くじけそう。きままにやるけど。
非効率的なのを承知で CViewSelect::DrawSelectAreaLine() で行っていた処理を CEditView::OnPaint() に委譲した。それが選択描画を取り消すのに一番簡単だったから。Vistaだと確認できないけど古い Windowsだとフリッカーがひどいかもしれない。気付いたのは検索を行ったときにカーソル行アンダーラインがちらつくことが増えたこと。範囲の拡大・縮小も遅い。<追記@2010-10-15>再描画する領域を最小限にする努力が必要。でも重なった二つの矩形が作る領域をどう扱ったものか(9つに分割して、左上↘右下、左下↗右上、左上↖右下、左下↙右上で網羅できるものなのか、もっと簡単にできるのか)、悩み中。</追記>
選択色指定(固定色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ピクセル出てるらしい。上の画像ではみだしを確認できるけど、みっともないもんね。改行マークが非表示だと選択範囲が右にちょっとはみ出して見えるのもみっともないと思ってるんだけどどうだろう。
WEB+DB PRESS Vol.54 - WebKit Quest 第5回を読んでる。フェイズはレイヤーより細かい区分。
paint()メソッドを呼び出す側は、何度もpaint()を呼び出します。その際、指定されるPaintPhaseは背景から前景へ推移します。
WebKitはフェーズの数だけ何度も Renderツリーをトラバースし、各フェーズを重ね描きすることでページの描画を行うのです(図5)
enum PaintPhaseのメンバーはこれで全部ではないけどこんなかんじ
レイヤーが必要な場面はこれより大局的な
エディタ領域の描画はフェイズで十分そうね。
最終更新: 2013-01-11T22:45+0900
どこかに書いた気がするのに見つからないのでもう一度。
サクラエディタは拡張子を見てファイルの種類を区別し、色分けルールやタブ幅、折り返しルールなどを使い分けるが、拡張子がない makefileや ChangeLogはみんな「基本」設定になってしまう。
ファイル名の末尾が .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セミコロン区切り(ヘルプによればカンマ区切りらしいが、「,」と「.」が紛らわしいのでスペース区切りにするのがいいよ)」のリストなもんで、この案は没。広まってしまったドット省略拡張子リストに対処することができないので。
makefileを .makefileだとみなしてファイルタイプを判別するということ。
パッチ> guess_filetype_of_extlessfile.rev2.patch (0.9KiB)
JSという名前のファイルが拡張子が .jsの JavaScriptファイルだとみなされることになるけど、気にしないよね。
>>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だから固定長バッファが前提でその長さが問題になってくるからかもしれないが、ケチるんだったらポインタで返してくれたらいいのに。引数のここからここまでがファイル名ですって。正規化したいから無理だって?
..............................................................................................................................................................................................................................................t
というファイル名を、trunk2@2457 + skr_imp_ext_ex.patchで、試してみたけれどスタックオーバーフローは起こせませんでした。ピリオドの数よりちょっと少ないくらい GetDocumentTypeOfExtが呼ばれる(二重拡張子でなく多重拡張子をテストしてる)のは確認できたけれど。
http://sourceforge.net/p/sakura-editor/code/2565/
そういう機能が欲しいと思ったから自分でも改造してたんだし喜ばしいことなんだけど、自分でビルドするサクラエディタに反映するとコンフリクト必至なのが憂鬱。
昔 RUNESOFTのインストーラが、ユーザーがインストール先を変更したときに、レジストリに記録するインストールフォルダ末尾に \ を付け忘れてしまい、おそらくファイル名を連結するときに \ を補わなかったのだろう、ゲームの起動に失敗するというポカをやらかしていた。
最終更新: 2010-09-15T20:40+0900
Command_REPLACE(置換)や Command_REPLACE_ALL(すべて置換)が Command_SEARCH_NEXT(下検索)を呼ぶのをやめたい。連携手段がレイアウト座標を基にした選択範囲しかなく、一文字で表現される CRLFの LFだけがマッチしたときに情報が欠落するし、Command_SEARCH_NEXTが持つ検索以外の事前・事後処理が無駄になるし、正規表現検索が BMatch(検索), BSubst(検索&置換)の計二回行われるのも無駄。
wchar_t単位で検索を行う CSearchAgent::SearchWordが、検索結果をレイアウト座標に変換する際の誤差(前述)を考慮してマッチ範囲を拡大し、結果を不正確なものにするのは誤りだと思う。それより、上の層でこれを呼び出している CLayoutMgr::SearchWordがその配慮を行うべきでは。
m/pattern/flag
も s/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が展開されなかったり、色々あるんよね)
クリップボードの形式が矩形テキストだったときに検索条件によっては無限ループ。
例えばクリップボードに
789 456 123
という 3行9文字(改行文字はない)がおさめられているとき、マッチと置き換えられるのは 789
であり、456
123
はそれぞれ次行、次々行に挿入される。つまり、456
123
はこれから検索対象になるということだ。検索条件が \d{3}
だったり ^
だったり、矩形テキストの二行目以降にマッチするものだったら無限ループ。
置換操作が二階層潜らないとロジック単位にならないというのも悩みの種。検索はロジック単位で行えてるのに、それをレイアウト単位に変換してそれがさらにロジック単位に変換されて、一対一対応じゃないからごにょごにょしないと思い通りに置換されなくて。
どうして最上層のレイアウトを基準にして文字列処理を行わなければいけないか。文書(wchar_t列としておく)の変更を LayoutMgrに通知する仕組みを整備するのを怠って、LayoutMgrを通して文書の変更を行うことで通知を不要にしていることが背景にあるのでは? GUIを通しての文字列操作に限ってはそれで十分だからそうなるのも仕方ないし、必要に迫られた人間(俺とか)がより汎用的な手段を整備せずにダーティハック*に頼る方が罪は重いかも。
* 挿入位置・置換範囲を文字レイアウト境界まで拡大して、挿入・置換文字列も同じだけ拡張する。
最終更新: 2010-08-30T23:07+0900
規制で書き込めないのでここで。
583 :名無しさん@お腹いっぱい。:2010/08/25(水) 15:31:52 ID:wtW19SUb0 頭に**がある行はコメント行として緑色にする という正規表現での色分けと ABCという言葉は赤色にする という正規表現の色分けを同時にする方法はありますか? (省略) 587 :名無しさん@お腹いっぱい。:2010/08/30(月) 14:18:00 ID:yI6qoQsb0 >>584 正規表現キーワードって、設定の上下に優先度あるらしいけど(ヘルプ情報)、結局の所、先に検索で引っかかった方が優先されるらしいよ。 wiki でバグじゃないかと報告されて、誰かが仕様じゃボケぇ、なんもおかしなことないわ! と切れてた。 個人的には、キーワードに優先順位があるならそれに準拠して欲しいと思うんだけどね。 なんていうか、二つの仕事を割り振られたA君が優先順位を決めて作業した結果、端から結果だけ見ると作業をひとつしか終えていないように見えるんだよね。 言葉の意味をはき違えているように思えて、そこが気持ち悪い。
言及されてるバグ報告ってのはこれ。>>BugReport/60 - SakuraEditorWiki
587の、自分の想定した動作モデル以外を認めない姿勢がなんだかなあ。いわく「優先順位があるならそれに準拠して欲しい」いわく「言葉の意味をはき違えているように思え(る)」。バグ報告者の方は単なる理解不足だし、あんなに噛みつかれたことに同情するけど。
優先順位は確かに存在してる。使われ方が 587の期待と違うだけで。たとえに沿って説明すると、仕事は最初から一つしかない。「正規表現キーワードの色分け」これひとつ。何をキーワードとみなすかの判断基準として複数の正規表現が存在してるだけ。複数の正規表現のマッチが重なったときに最も左から始まり最も上にあるパターンが優先される。最も左が優先されるのは正規表現キーワードを含む色分け要素(文字列、コメント、URLなど)間の順序付けにも利用されてる大原則なのでわざわざヘルプに書く必要を感じなかったんでしょうよ。上の方のパターンが優先されるというのは、コメントなど他の色分けより正規表現キーワードの色分けが優先される(これもヘルプに書いてある)と言うときと、全く同じ意味で使われている。不自然なことはない。
「先に検索で引っかかった方が優先されるらしいよ」というのは嘘。「先に」(時間的な前後)ではなく「前の方で」(空間的な前後)なら間違いではないが。
バグ報告した人(たぶん 587も)の希望する動作を強調キーワードに置き換えると、「『IN』『SELECT』『EXISTS』『JOIN』というのを強調キーワード1,2,3,4にしてそれぞれ別の色に色分けするようにしている。強調キーワード1は強調キーワード4より優先されるはずだから JOINの中の INが色分けされないのはおかしい。」という内容になる。Keywordの中に別の Keywordがあるなんて想定はない方が普通でしょう。
7195の System_UPJさんのように動作を理解した上で使いこなしてる人もいる。ヘルプには改善の余地があるとしても今の動作はバグではないし変更されると困る人が(正規表現キーワードの利用者の中では、たぶん)大多数。存在しない別の機能を要望していることに気付くべき。
583へのレスとして用意した、んで規制された、文章ものせとく。
Wikiでも似たような要望がバグとして報告されてたけど、よくある要望なんかね。 手持ちの案はこげな感じ。 1.キャブチャ部分に別の色を指定できるようにする。 2.従属的な正規表現キーワードを指定できるようにしてキーワード内キーワードを 色分けできるようにする。 3.萌ディタのように色分けに状態を持たせる。 実装の難易度 1=2<3 設定の面倒さ 1=2<3 色分けの自由度 1<2<3
最終更新: 2012-11-01T13:41+0900
説明が面倒なのと誰も知りたくないだろうから適当に、備忘のためだけに。
%{literal}
の literal
部分で \{
や \}
を使う人間がいるとは思わなかった。(違う種類の括弧を使えばいいじゃない。開閉の釣り合いがとれてれば同じ種類の括弧でもエスケープ不要だし)だのに Ruby1.9の rake.rbにこんなパターンが……
%r{[*?\[\{]}
%r{余分な開き括弧{。間違いはインタープリタを通す前から目立つように}
2のは Rubyインタープリタに対するエスケープ、と同時に正規表現パターンとしてのエスケープですよ。%r[\[] と /\[/ が同じパターンになって、%r[[] がRubyのシンタックスエラー、/[/ がパターンのコンパイルエラーになるんだから。(ruby 1.8.7 (2010-01-10 patchlevel 249) [i386-mswin32] / ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-mswin32])
最終更新: 2014-01-02T18:04+0900
なんてことをこの日記の冒頭に掲げたもんだから自分でやってみた(どういうこと?)。
既存アプリに影響があるので良くないけど、bregonigへの暫定的な変更はこう。
} else { /* ERROR */ onig_err_to_bregexp_msg(err_code, NULL, msg); - return -1; + return err_code == ONIG_MISMATCH_INPUTSHORTAGE ? 0 : -1; }
入力が足りなくてマッチしなかったときは、エラーメッセージをセットするけど戻り値は負数(エラー)ではなく 0(マッチなし)。
鬼車(5.9.2)に「K.Takata's software : bregonig.dll」で手に入る onig-5.9.2-mod.diffを適用したものをさらに変更。マッチに失敗したときのエラーの種類で hitendしたかどうかを伝える。ちゃんと動くのか非常にあやしい代物。TODOもいっぱいある。
やっぱり鬼車は手に負えないかも。
なんのことはない、影響を受ける既存アプリにはサクラエディタが含まれている。正規表現のコンパイルエラーと入力不足によるマッチなしを区別するためにちょっと変更した。
一行検索(従来動作)してみて、マッチが行末まで続いていたり次の行の内容次第でマッチが成功に変わりそうなときはとりあえず二行ぶん検索してみる。それでも状況が同じなら 50MiBのバッファを埋めてから三度目の検索を行う。50MiBって大きすぎるだろうか。大きさの問題だろうか。かかか。
実装は CSearchAgent::SearchWord()に。これって単語検索専用のメソッドではなかったのですよ。CGrepAgentもこれを利用したらよかった。
バッファの実体は std::wstringで。文字列を比較するにも wmemcmpなりを使おうとして結局 std::wstring("hoge") == L"hoge"
を使ったへたれなので、str系のライブラリ関数は恐ろしくて毎回すぐに投げ出します。(あれを使いこなせる人は VBや PHPも使いこなせると思うんですよ)
[\s\S]*$
というパターン。最後の行の末尾までマッチして欲しいのに一行目の改行直前で止まってしまう。マッチに成功したときの hitEndフラグの扱い。hitEnd()の実装の参考になるか?と思ったけどそうもいかなそう。
Revision 74 hitEnd()の実装(但し仕様は満たしていない)。 Revision 85 useAnchoringBounds()及びuseTransparentBounds()に対応。→hitEnd()の実装を修正。 Revision 103 hitEnd()に@Deprecatedを追加。
/** * This method is experimentation phase, and implementation has not been completed yet. * @return * @deprecated */ @Deprecated public boolean hitEnd() { return (hasAnchoringBounds ? (range == region.end(0)) : (input.length() == end())); }
hasAnchoringBoundsが設定されてる場合は無視するとして、そうでないときは入力の長さとマッチの末尾(end())が一致してることをテストしてるだけに見える。それって hitEnd()とは違うよね。5月31日の日記で文字列 aa に対してパターン aa を適用したときに hitEnd()が falseになった事例を引用した。
そうそう。これこそが hitEnd()の使い道 >Check if string is a prefix of a Javascript RegExp - Stack Overflow コメントの最後に見たことのある名前が☺
PCRE(現在 ver. 8.10)は戻り読みも再帰も(パターンのコンパイル時の)改行指定オプションもスキャナー的に使うための hitEnd()のような機能(read pcrepartial)も、およそ欲しいものをすべて備えている。悪名高いスタックオーバーフローにも、1.スタック使用量を減らす。2.代替メモリ確保関数を使う(汎用ゆえに遅いmalloc/freeか自作)。3.pcre_exec()の代わりに pcre_dfa_exec()を使う。みたいな各種対策があるらしい。
最終更新: 2010-06-26T01:41+0900
たんなる自己弁護に終始するのでここに書くけど、
他アプリケーションを見ても、...の使い方はかなり恣意的な様です
だからこそ俺はガイドライン(を紹介するコラム)を紹介したし、MSのアプリしか参考にしてないし、俺判断が入り込まないようにできるだけ緩くガイドラインを適用⁑してはみだした部分だけを指摘したつもりだけど、それでも現状最高うぜーと思うならガイドラインに従って反論してほしいと思う(もちろんガイドライン不採用というのも一つの選択肢として残ってるけど)。
別コメントへの反応。ダイアログのモーダル/モードレスと点々には関係がないと思う。検索ダイアログがモードレスだとモーダルに比べて、ダイアログを表示してからでも検索文字列を編集テキストからコピーしてきたり、スクロールしてテキストを確認しながら検索条件を練ることができて便利、ぐらいの違いしかないのでは。
ああ、いやいや、モードレスであることで違う使い道ができる。コマンドの目的(できれば名前も)が変われば点々の必要性も変わる。
ツールパレットを表示するコマンドには点々が付かない(これは既定事項)。サクラエディタの検索画面はモードレスだし勝手に閉じないようにも設定できるので、メインウィンドウの横に置いてツールウィンドウとして利用することができる。その場合「検索...」コマンドは「検索ウィンドウ表示」コマンドとして振る舞っている。モーダルだった以前と違い多目的コマンドなのだが点々はいかがすべき?という内容だったのかも。
こうなると複数あるかもしれないコマンドの使途ではなく、コマンドの名前から主目的を一つ判断して点々の有無を決めることになるだろう。してみると「コマンド名に『アウトライン解析』を選んでいるからには、点々を付けるべきではない」と主張すべきだったかもしれない。解析結果がモーダルダイアログに表示されていたときでも同じ(点々を付けるべきではない)。
「指定行へジャンプ...」のアウトライン版に相当するコマンド名を採用したときには点々を付けるべきだが……と考えながら思い立って「指定行へジャンプ...」を実行したらメモ帳のそれより大きいダイアログが表示された(初めて見た)。場所をとってるのは PL/SQLのコンパイルエラー行を選択するためのもの。先を越された。アウトライン解析結果を参考に特定の行にジャンプするのが目的なら、こういうアプローチもありでは?(やっぱり専用画面の魅力には負ける気もするが)
アウトライン解析ってその結果をジャンプだけでなく色分けや補完にも使いたくなるから、「アウトライン解析」っていう名前のコマンドは消えてもいい。
最終更新: 2016-11-30T10:20+0900
標準では Ctrl+Shift+E。俺は Ctrl+Deleteに割り当てた。
で、使ってるとスクロール位置がずれるのが気になってくる。深いディレクトリで GREPすると表示される結果の大部分が定型のパスだけになるから、違いを見分けるためにはパス末尾のファイル名とマッチした行が見えるように右にスクロールする必要がある。そして、目当てのものではない行を Ctrl+Deleteで削除していくんだが、行削除後にキャレットの行頭からの桁位置は保たれてるんだけどスクロール位置がずれる。画面の真ん中にいたと思ったマリオが次の瞬間背景とともに右端に移動していたようなもんだ。これがうっとうしい。
削除前に一瞬、行全体が選択されるように見えるので、このときにスクロール位置が変わってしまうのかと思って「行選択->選択範囲削除」の流れを変えて、範囲選択に依存しない削除方法を採用したのがこれ>improve_delete_line.patch(5.2KiB)
実際は削除に使っている ReplaceData_CEditView()というコマンドがキャレットの位置調整を行っていたのが原因だったから、削除方法は選択範囲の削除のままでもよかったかも。ともあれ、行全体を選択する操作がちらつくのとスクロール位置がずれるのがなくなった。(ReplaceData_CEditView()がやっているように再描画の必要な範囲を求めたりせずビュー全体を再描画してるから環境によっては画面全体がちらつく可能性がなきにしもあらず。「画面キャッシュを使う」とか DWMがなんとかしてくれることに期待。どうせ 1画面50行のうち削除された行より下は元からすべて再描画対象だしー)
improve_delete_line.rev1_1.patch(5.5KiB)
フラグ自体は立ってたけど描画が行われていなかったというミス。
最終更新: 2012-10-27T00:23+0900
その一(20090808p03)がだらだら長くなったのでいったん切って、ここに続ける。
ひどい。「/*」を入力して後ろの行がコメント色一色になったとする。つづけて「*/」を入力しても後ろの行がコメント色のまま。たぶんこれが関係する。
行をまたぐ色分けに問題があって、たとえば一画面に収まらない長大な複数行文字列があったとして、何度も上下にスクロールしたり改行を入力したりするだけで色分けが変わってしまっていた
本当にそうなら、泥縄式バグ潰し無間地獄へ突入ですな。消火行為が点火に直結した効率のいいマッチポンプだもん。
まさしく > たぶんこれが関係する。
そのときの変更にこんなコメントが添えられているのを発見した。「IsInsideKeyword()から呼ばれたときは精算したらダメっぽいのでコメントアウトして様子を見る。」様子見の結果はダメでした。さあ、どうしよう。
別の場所で不必要にキャッシュを無効化している部分を厳密に処理したら直ったっぽい。キャッシュの有無で結果が変わるはずないんだけど……。(さらなる追求が必要。でもそれは問題が見つかってからにする)
変わりうる。一行の色分けは一時(いちどき)に、他の行の色分けを挟んだりせずに終わらせなければいけない。正規表現キーワードは各行の行頭がどういう状態か(コメントの中か?とか)を覚えているキャッシュの他に、ある行を中間まで処理したマッチング結果を持っており、先ほどはこれをキャッシュと呼んでいた。そいつは、次の IsStartOfKeyword()呼び出しを待っている宙ぶらりんな状態。期待していた呼び出しがくる前にクリアされたら結果がおかしくなる。マッチングを中間で止めざるをえないのは、他の色分けに先食いされた文字をマッチに利用してしまわないように。
最終更新: 2011-01-02T16:45+0900
SAKURA Development BBS (ANSI)のログが 10ページ分しか閲覧できなくて、残念な思いをしていた。検索対象のリストに古い年月が存在していたり個別リンクが機能していたりするんだから、古いログが保存されているのは間違いないんだけど。Cyclamen(掲示板CGI)に関して言えば、記法のヘルプを見つけることもソースを見て記法を確認することもできない。ま、それはおいといて、
過去ログを見つけた。>http://groups.yahoo.co.jp/group/sakura-editor/files/User/bbs-log/
Subversionが最初からあった世代には考えられない開発スタイルがそこに!差分や変更したファイルを共有エリアに置いて掲示板で報告。大きな変更をした人が他の人の小さな変更をマージして最新版を管理したり。ともあれ、お宝ざくざくなので日曜日から喜々として読み進めている次第。(ログが 2007年9月で切れてるのが残念)
S:27,*,01/02/11,10:49,, T:横スクロール時の動作 N:げんた M: 現在のこのエディタはWM_HSCROLLが来たら横スクロール量を決定して画面全体を書き直す動作を行います。もし、画面全体を書き直す代わりに新規部分のみを書き直せば高速化すると思われるかも知れませんがそうはいきません。 なぜなら、このエディタは色分け情報をメモリ上に保持していないため、描画の都度行の先頭から調べて色を決定しているからです。その際キーワードの検索も行います。たぶん、これがかなりの処理を必要としているのだと思います。 横スクロール速度を劇的に改善しようと思ったら色分けを予め行ってその情報をメモリに保持するようにしないと難しいのではないでしょうか。
gdippを使っていると無視できないほどに強調されるので横スクロールが遅いことには気付いていた。これが書かれた当時のサクラエディタ(という名前ではまだないが)の遅さは今の PCスペックでは再現できないかもしれないけど、根は昔から存在していたよう。
S:114,*,01/03/02, 2:32,, T:コントロールプロセスの起動方法 N:げんた E:genta@i.am M: 外部エディタを監視するプログラムからテキストエディタを使うとき、エディタが常駐していないと起動したプロセスは管理プロセスとなってエディタ画面は別プロセスで動作するため、編集終了の検出が正しく行えない場合があります。 自分が管理プロセスになるのではなく管理プロセスを別に起動して起動完了まで待機するような作りにできればこの問題が解決できるなぁと思いました。
タブモード(実装者は別の人)であっても 1ドキュメント 1プロセスだから Subversionのコミットメッセージをサクラエディタで編集できるんだけど、そもそもこういうことが考慮されていたからこそできるのだと確認。
S:1446,1440,02/02/01,22:27,, T:Re2:正規表現置換の振舞い N:げんた M: >..*\n$ でやってみたら削除できましたけど…??? よく見たら自分で何気なく変えたところだった. 本当に申し訳ない. 今は普通に動いています. ただ,BREGEXPのせいなのか,^.*$ には先頭から改行コード \r\n の\rの部分までがヒットして\nが残ります. ^.*\n$ だと行全体にヒット.
「改行(.と$の動作に影響する)」= LF(0x0A)の指摘がこのとき既に。セルフリンク>20090922p01
S:1475,1474,02/02/05, 0:47,, T:Re4: タイプ別設定に外部ヘルプと外部HTMLヘルプ新設パッチ N:げんた M: ちょっと考え直してみました. ▼初期の私のアイディア ・CShareDataの役割=単にDLL Sharedを得るためのクラス. ・タイプ別設定を共有メモリから追い出す. そのために,タイプ別設定のアクセスをCEditDoc::GetDocumentAttributeに集約. 追い出した後の実装はCEditDoc,またはCEditDocに含まれる新規クラスで行うつもりだった. 共有メモリからタイプ別設定を追い出したい理由は以下の通り. * タイプ別設定が足りなくなり,既に2回最大値を拡張している. * タイプ別設定の領域を予め共有メモリに確保しなくてはならないので,上限の撤廃ができない. * 初回起動時に使うかわからない領域全てを初期化するのは無駄ではないか. 追い出しのアイディア * タイプ別設定はそれぞれ外部ファイルに用意する. * 設定ファイルは必要に応じて読み込まれる. * 変更は現状通りダイアログボックスで行う. * 変更されたらすぐにファイルに保存し,設定変更Broadcastメッセージを投げる. * Broadcastを受け取ったら該当タイプを使用しているか確認. * 使用していたらファイルから再読込し,設定を更新する. >各種設定が共通設定だろうが、タイプ別設定だろうが、気にせずとりあえずCSettingMediatorに問い合わせたり、設定を依頼するだけでよくなったら便利だなぁと思っています。 なるほど.これは良いと思います.最終的には設定情報がどこに格納されているのかも意識する必要が無くなるので,これは私のアイディアと矛盾しません.CEditDoc::GetDocumentAttributeで取得するのをDLLSHAREからCSettingMediator経由に変更すればタイプ別設定のカプセル化の場所が移動します. 私の初期アイディアと組み合わせると,追い出した後の実装というのをCSettingMediatorに依頼することになるでしょう.タイプ一覧の設定,指定タイプの取得,更新などファイルへの書き出し・読み込みタイミングもCSettingMediatorが管理すれば良いような気がします. 上記内容を納得した上で私が確認した限りでは特に問題はないように思います. --- 実装に入る前に設計に対する議論を行うことは有意義だと思います.これまでは議論する相手がいなかったので...(;_;)
タイプ別設定を共有メモリから追い出すアイディアが既に出ていた。
設定の場所を隠蔽するクラスも構想されている。それのメリットとして自分が考えているのは、
の 3を、2との差分とすることで基本的な設定の共通化(基本設定による)を図りつつ、設定の読み出しを一本化できること。
S:1606,*,02/02/16, 2:26,, T:ssrc_2002-02-11_p1 N:hor M: ssrc_2002-02-11 からの変更箇所です。ご参考まで。 (省略) □その他のその他 ・[Ctrl+Home]or[Ctrl+End]後に[Down]or[Up]したときの挙動を見直し・・・以下変更個所 1.矩形選択中に[Ctrl+Home]or[Ctrl+End]して[Down]or[Up]したとき以外は普通にカーソル移動 2.選択を解除したあとは普通にカーソル移動 (省略)
ファイルの先頭へ移動するコマンド(Ctrl+Home)が「通常は、(0, 0)へ移動。ボックス選択中は、(GetCaret().GetCaretLayoutPos().GetX2(), 0)へ移動」というコメント付きで故意におかしな動作をするのはこのへんが理由だったのか。(細かいことを言うと、このときの実装は Ctrl+Homeで 0行0桁に移動した後、↓で 1行(Ctrl+Home前の)X桁に移動する、というもので、いまの実装はすこし後にでてくる)。ファイルの先頭に移動という一つの名前に異なる機能を実装するのはやめて欲しい。利用者視点の「使える」動作なんだろうけど、自分なら Alt+Ctrl+Homeを「(矩形選択)ファイルの先頭行に移動(※未実装)」に割り当てるなどして対処する。
S:1759,*,02/03/23,11:01,, T:バックアップごみ箱問題 N:みく M: ネットワークドライブまたはリムーバブルドライブのファイルを ごみ箱に放り込むとOSの仕様により消滅してしまいます。 バックアップしたつもりがされてないという現象を避けるため、 これらのドライブの場合はごみ箱に放り込まないようにしました。 次回版にでも取り込んでください。 どうしてもごみ箱に放り込みたい場合は、 「指定のフォルダに作成する」でフォルダにローカルドライブのフォルダを 指定し、さらに「バックアップをごみ箱に放り込む」を指定してください。 (指定のフォルダにごみ箱を直接指定することはできません)
最近見かけたリムーバブルメディア上のファイルのバックアップをゴミ箱に放り込めない問題が 2002年に指摘されている。
自分はバックアップは Ctrl+Sに割り当てた JScriptマクロで Subversionに保存してる。差分バックアップでありながら過去の版を ViewVCで簡単に見られるのが利点。マクロでやってることのエッセンスは以下の通り。
>Editor.FileSave(); >svn up "working copy" >copy /Y /B "filepath" "working copy/filename" ); >svn add "working copy/filename" >svn commit "working copy/filename" -m "filepath" --force-log --non-interactive'
たかだかテキストファイルなので動画より小さく、ワーキングコピーもリポジトリも数百MiBにおさまってる。NTFSの圧縮属性を付けたらさらに三分の一にもなるし。
S:1980,*,02/04/30, 1:41,, T:半角スペース表示 N:KK M: KKです。 一般掲示板の方で要望のあった 「半角スペースの表示を追加する」 パッチを書いてみました。04-27版へのパッチです。 DispSpc04-27.zip (省略)S:1982,1980,02/04/30, 2:12,, T:Re:半角スペース表示 N:げんた M: 小文字のoの下半分だけを使うという発想が何とも独創的 (^^)
いまの Unicode版も同じ実装。気付かなかった (^^) ちなみに、デフォルトの色は灰色だけど、これをテキストと同じ色にすると周りと同じ色で描画されます(コメント中の空白とかが)。
空白記号類は特に明示指定した部分以外はなるべく周辺の指定に合わせるようにしてみた // 2009.05.30 ryoji
ソースを見てないと気づかなかった。
S:2237,*,02/07/03,12:22,, T:クラス、インターフェイスの整理 N:ボロぞうきん M: (省略) 1&2 1行の文字数が3万文字を超えてくると極端に遅くなるので、 行バッファを簡易gapped buffer方式に変更したかったけど、 内部のポインタを書き換え目的に使っている場所があり、 単純にconst化出来なかった。 (省略)
でました。gapped buffer
S:2278,*,02/08/23,20:29,, T:正規表現ライブラリ N:みく M: 比較的新しそうな正規表現ライブラリとして、 こんなのもあるみたいです。 http://www.fides.dti.ne.jp/~oka-t/libraries.html
S:2959,*,03/07/21, 3:35,, T:正規表現ライブラリの不具合 N:げんた M: http://www.fides.dti.ne.jp/~oka-t/history-2001.html でPerlの正規表現の不具合について触れられていた. 試してみると確かに ::1234::5678901234567890::::1234567890:: 888: に対して ^([0-9]+|::)*$ で検索するとフリーズする.(よい子は真似をしないでください) Perl 5.8ではフリーズしなかった.
リンク先が同じ。なんちゃってではなく真っ当な雰囲気がするなあ、と思いながらそのサイトをうろうろしていたら、未訪問のはずのリンクが何カ所も閲覧済みの色になっていることに気付いた。良いものは埋もれてしまわないのだ(忘れられるのは読み手(俺)の問題)。
S:2562,2559,03/02/11, 1:19,, T:Re: マルチユーザモード(案) N:もか M: ▼ みくさん >実行ファイル名を sakuram.exe とかに改名するとマルチユーザモードになり、 実行ファイル名を 任意の文字列1.exe などにすると文字コードがその数字の文字コード(この場合EUC-JPに)固定されるという機能があるから (省略)
なんぞそれ>「実行ファイル名を 任意の文字列1.exe などにすると」
S:3140,*,03/09/15,11:53,, T:色分けHTML出力 N:wmlhq M: 強調キーワードなどを使って色分けしたソースコードをsakuraでもHTML/XMLで出力できたら、便利だろうな。「形式を指定してコピー(special copy)」で実装するとか。 <font size=10><pre>//<nobr>comment</nobr> <font color="#576447">int</font> func(); </pre></font>
これは面白そう。もちろんフォーマットは
<style> /*<![CDATA[*/ .comment { color: green; background-color: white; font-style: oblique; } /*]]>*/ </style> <span class="comment">//コメント</span>
にするけど。HTML直打ちに近いブログに投稿する以外に、正規表現キーワードによる色分けのデバッグにも使える。(思い通りの結果にならないときに、見た目では判断できない違いが classによって区別できる)
それにしてもこの wmlhq(自称)という人は……。掲示板の閲覧者はする~かが試されている(笑) 関わりたくはないけど知識とエネルギーは無視できないものがある。うまく操縦できる人がいればいいのかな。上から目線で仕切屋でイラッとする年寄り言葉を使ったりでこの人に指導される新人に同情するものの、悔しいかな、メッセージの国際化の手段に STRINGTABLE, MESSAGETABLE, gettextの三つを挙げたり、入力補完の高速化に bsearch, ハッシュ, dartsの三つを挙げたり、できないもんねえ。ちょっと前に WEB+DB PRESSで dartsっぽいのは見かけてたけども、わからなくて検索したし。
S:3300,3299,03/11/07,21:31,, T:BREGEXP.DLL N:かろと E:karoto@infoseek.jp M: ▼ もかさん > Perl Artistic License > "Freely Available" 内の 2.「バグ修正」か「移植」のための修正 > に該当しそうですが、どうでしょうか? オリジナルのPerlの関数には、行頭から文字列を渡せるようになっていて、 BMatchEx()で、その引数にも値を渡せるようにしただけなので、 変更そのものは簡単なことで、「移植」なんて言うのもおこがましい程度です。 > 微妙に気になるのは、V1.0(VB未対応)で、Exportしてる関数が少ないのと、for SAKURA になってる... V1.0とV1.1の違いって、VB対応だったんですね・・知りませんでした。 Linux版のソースをもってきた関係上、VB対応部分は入ってませんでした。 というわけで、ExportしているVB用関数もありません。 Linuxソースなので、リソース関連のファイルは同梱されてなかったので、適当に作り、 本家のBREGEXPと異なることがわかりやすいように、「for SAKURA」ってのを入れました。(笑) まずいでしょうか? > #いい感じだと欲が出てくるもので、 > #ついでに改行コード周りもDLL側でやってくれないかなぁ(実はやってる?) 実は、同じ事を考えて、内部の以前Perlの関数眺めたのですが、改行は1文字(\n)だと 決めて処理している箇所があり、難しそうだなぁと思いました。 > #UTF-16にも対応してくれないかなぁ ははは・・・さすがに対応済みのDLLを持ってきた方が早いかと・・
「改行は1文字(\n)」が「改行は1文字(\rの後ろではない\n, \r)」になるだけでも十分ではないのかなあ。
$
が行文字列末尾にマッチしたのは無視すべきだが、空パターン (?:)
が改行文字の後ろにマッチしたのは無視すべきでない。果たして両者を区別できるのか?)調子に乗って hitEnd()に相当する機能を付けたら、複数行検索も
みたいにしてできるかも。複数行検索モードの実装が面倒くさい上に BREGEXP for SAKURA限定機能なので C/Pは悪い。
BREGEXP for SAKURAのマッチ仕様変更はこんなんで検出できる。
bool dot_matches_cr() // falseになっていることを確認する。テストは sフラグOFFで行われる。 { BREGEXP* rxp = NULL; const char* const szCR = "\r"; char szErrorMsg[80] = ""; const bool retval = 0 < BMatch("/./", szCR, szCR + 1, &rxp, szErrorMsg); if(rxp != NULL) { BRegfree(rxp); } return retval; } bool dollar_matches_before_cr() // trueになっていることを確認する。テストは mフラグONで行われる。 { BREGEXP* rxp = NULL; const char* const szCR = "\r"; char szErrorMsg[80] = ""; const bool retval = 0 < BMatch("/$/m", szCR, szCR + 1, &rxp, szErrorMsg) && rxp->startp[0] == szCR; if(rxp != NULL) { BRegfree(rxp); } return retval; }
正規表現に関連して、ログからこんな URLも見つけ出してきた。
「COOLなURLは変わらない」ということを、リンク切れを発見するたびに思い出す。この二つの URLはもちろん今も有効。
S:3521,*,04/04/03, 0:28,, T:有効なカーソル位置の謎 N:もか M: あと、有効なカーソル位置ってどの範囲なのか、いまいちわかりません。 私が認識している動作は、フリーカーソルモードか、矩形選択中・終了後の位置としてEOFにまつわる位置だけに絞っても、 1. [EOF]だけの行(データの終端は改行)は行頭以外却下。 2. [EOF]だけのレイアウト行(データの終端は普通の文字)は行頭以外却下。 不思議なのは、レイアウト折り返し時はインデントされないし、カーソル座標表示も変かも。。 3. 普通の文字の後ろについた[EOF]より後ろ(正確には右側かつウィンドウ折り返し線より左側)は有効。 で次の行(EOFマークの次の行だから存在していない行)は不正。 あと、矩形選択で、折り返し位置にカーソルを移動しようとしても、行頭に飛ばされてしまって、最後の1文字が選択できません。 ただし、EOFの表示のみ折り返される場合は、選択できてしまいます。 選択できるようにすると、今度は、論理座標との双方向変換の1対1対応が保証されなくなるので、たぶんこまります。
後半はこれ(20091026p01)関連。なんかもう、ほとんどの問題は既出だという気がしてきた。その都度解決できていれば出てこないはずなのに……。
S:3752,*,04/09/27,17:34,, T:改行コードが食い違う N:もか M: 上書き保存したファイルとエディタが保持しているデータで、改行コードが異なることがあります。 1. 名前をつけて保存で、改行コードを変換する指定で保存 2. リロードされた後、入力改行コード指定により、1.で指定した改行コード以外を選択 3. 改行を入力 4. 上書き保存。このとき、2.で指定された改行コードで保存される この時点でリロードされないので、保存したファイルと、エディタ上のデータで食い違いが発生します。 同様に、Shift_JIS以外では、ファイルとエディタ上のデータで、実際には異なる(=リロードするとデータが変わる)ことがありますが、 こちらは下手にリロードすると、保存時に文字化けした場合は修正するチャンスを失うことになります。S:3753,3752,04/10/02,12:21,, T:Re: 改行コードが食い違う N:げんた M: 現象を確認しました. 要するに名前を付けて保存で指定したコード指定がその後の上書き保存でも生きているのが問題というわけですよね.そもそも保存時のコード指定がメンバ変数としてずっと保持されているのが不思議な気がします. でも改行コードなんか気にしないで,他の文書からコピーしたものを保存したときに常にコードが統一されて欲しいという人もいるかもしれない.かといって保存の都度reloadするのは無駄ですし. ・保存時のコード指定は保存しない ・毎回コードを指定して上書きしたい人はマクロで対応してもらう というのでいいように思います.
これなんかも、すでに自分で遭遇してる現象なんだけど、ずっと前に確認されていたってわけだ。
他にも、「アウトライン解析のプラグイン化」という語がログのごく初期に登場していたり、正規表現ライブラリが最初は jre32.dllであって、BREGEXP.DLLへは GPL化を目指したときに移行した*のだとか、sakura_core.dll(なにそれ?)だとか、正規表現のパターン区切りとして //k
が入力必須で面倒だったり、//k
を自動付加するようにしてみたけどまだ \
にエスケープが必要だから @
や %
などパターン中に使われていない文字をセパレータにしてみたらどうか、とか(いつ 0xFFに決まったんだろう?)、意外な発見(とどこかで見たような問題が)がざっくざく。
* BREGEXPの Bは BASP21の Bと同じ BABAの Bのはずで、BASP21は WSHから利用できるオートメーションオブジェクトとして、JScript(最初に出会った記念すべきコンピュータ言語)をいじり始めた当時から有名だった(「それ、BASP21でできるよ」)から、BREGEXP"以前"が存在するとは思ってもいなかった。
最終更新: 2011-01-12T18:23+0900
CShareData::IsPathOpened()が、起動している他のエディタプロセスに対して SendMessage()でメッセージを投げる。ファイルを重複してオープンする代わりにすでに開いているプロセスを前面に出すという処理で使われているのだが、一つでもビジーだったりハングアップしてるプロセスがあると SendMessage()が返らないので、せっかくプロセスが分かれているのに新しくファイルを開くことができない。
長々と色分けをしてるのがビジーの原因なんだけどね。
SendMessage()の怖さを語っていたのはたしか『[大型本] Raymond Chen【Windowsプログラミングの極意 歴史から学ぶ実践的Windowsプログラミング!】 アスキー』。対象が絞れてないのか玉石混淆という印象だけど、侮れない知識も埋もれている。任意のウィンドウを左右に並べる方法とか。あ、これはどうでもいい方の知識か。ダイアログプロシージャが戻り値を返す方法とかは……、いまどき Win32 SDKプログラミングもないか。古参ユーザーのためのあるあるネタがいっぱいです。
最終更新: 2011-01-02T16:57+0900
/* 現在位置より前の位置を検索する */ bool found = false; CLogicRange matchLogicRange = CLogicRange( CLogicPoint( -1, -1 ), CLogicPoint( -1, -1 ) ); CLayoutRange matchLayoutRange = CLayoutRange( CLayoutPoint( -1, -1 ), CLayoutPoint( -1, -1 ) ); const SearchPos originalSearchPos = searchPos; if( pLayout ) { bool retried = false; ///< 末尾から再検索したかどうか。 for(;;) { found = 0 != GetDocument()->m_cLayoutMgr.SearchWord( searchPos.y, searchPos.x, // 検索開始位置 m_pCommanderView->m_szCurSrchKey, // 検索条件 SEARCH_BACKWARD, // 0==前方検索 1==後方検索 m_pCommanderView->m_sCurSearchOption, // 検索オプション &matchLayoutRange, // マッチレイアウト範囲 &m_pCommanderView->m_CurRegexp // 正規表現コンパイルデータ ); if( retried ) { break; } if( ! found && GetDllShareData().m_Common.m_sSearch.m_bSearchAll ) { // From Here 2002.01.26 hor 見つからなかったので末尾から再検索する。 searchPos.y = GetDocument()->m_cLayoutMgr.GetLineCount() - 1; searchPos.x = static_cast<Int>( MAXLINEKETAS ); // とにかく大きければよい。 retried = true; continue; } if( found ) { this->GetDocument()->m_cLayoutMgr.LayoutToLogic( matchLayoutRange, &matchLogicRange ); // 検索開始位置での幅0マッチはなかったことにして一つ前から探す。 if( matchLayoutRange.GetFrom() == matchLayoutRange.GetTo() && matchLayoutRange.GetFrom().GetY2() == originalSearchPos.y && matchLogicRange.GetFrom().GetX2() == originalSearchPos.x ) { searchPos.x -= 1; found = false; continue; } } break; } }
20090808p03の @2009-10-19に書いた*結果の一部が上のコード。@2009-10-20でちらりと書いた、現在の選択範囲が幅0かどうかで検索のその場足踏み対策を行っていたのは不十分だということがわかったので、対処するために CViewCommander::Command_SEARCH_NEXT()を同じように書き換えられたら楽だけど、テストがないからそれは(私家版でしか)できないんだよね。
gotoを使っていたり、bRedoや bFlag1という名前の変数があるコードをいじるのは嫌だなあ。(だからこそ Command_SEARCH_PREV()は全面書き直しになった)
まあ、bRedoはわからなくもない。いや、使われている部分を確認しないとわからないのだが、retriedだって他人にとっては似たり寄ったりかもしれないので許容しよう(ただし、スコープが狭まったことで使用部分の確認がしやすいのは明らかに前進している)。書き換えたっていうけど、ループだって単に飼い馴らされた gotoじゃないかと言われるかもしれない。しかも上の例では繰り返しを前提としていない(一回で抜けるのが通常パスだ)から意図が不明確になったおそれもある。でもこの関数で使われていたもう一つの gotoのように、変数が初期化されない云々のエラーが出るために変数宣言を関数の頭に置くことを要求してしまう、そんな使い方はできないことが担保されている。(goto end_of_func; のことですよ)
あ、上のコード、キャレットが行頭にあるときのことを考慮してない(searchPos.x -= 1; の部分)。一応、問題なく機能してるみたいだけど。
もうひとつ問題が見つかって、現状が問題ありありならばとザックリ Command_SEARCH_PREV()と Command_SEARCH_NEXT()を書き直した。どうせ問題続出するんだろうなあ、とこっそりアップロード。
CViewSelectの修正がないと、マッチの始点と選択開始点が重なったとき(選択範囲が空になるとき)に選択ロックが外れてしまう。
範囲選択中でないときは幅0マッチなどによる検索のやり直しをしないようにした。範囲選択中かどうかというのは条件として不十分なんだけど、すくなくとも検索前と後で状態が変わるということはいえる。Command_REPLACE()が事前に選択をキャンセルしてくれているので、とりあえずは置換が一つ飛ばしになることがなくなる。
「aaaaaaa...」というテキストを、F6による選択ロックを利用して上方向に選択中に「aaa」を下検索する。3文字ずつ選択範囲が縮小していくはずのところが、1文字ずつしか縮んでいなかったのを元通りにした。
誤) SEARCH_PREV, SEARCH_NEXT
正) Command_SEARCH_PREV, Command_SEARCH_NEXT
すべて置換の無限置換対策として「m_pCommanderView->GetDrawSwitch() // 全て置換の実行中じゃない」という条件(見落としていた)を元のソースからコピってきた。
CViewSelectの変更がステータスバーメッセージの不要な表示につながっていた。メッセージ表示部にそういうチェックをさせて、カーソル位置による選択範囲変更で幅0選択を可能にする(昨日の修正)部分は残したいけど、影響範囲を延々たたいていくようなことになったらいやなので CViewSelectの変更は取り消し。
F6でロックしてキャレットを動かしまた元の位置にもどす。この状態でダイアログを出して検索をすると選択範囲の拡大縮小ではなく、マッチ結果が選択されてしまう。こんなことが起こるならやはり昨日の修正を温存したくなる。不思議なのは ANSI版も同じ挙動だったのだが、UNICODE版ではきちんと選択範囲の拡大縮小になっていたこと。<<< どうやら「カーソル位置の単語文字列をデフォルトの検索文字列にする」の設定が違っていただけみたい。
CViewSelect.IsTextSelected()には、0文字選択を含むのか含まないのかはっきりしてほしい。定義⁑からは 0文字選択を含んでいるが、IsTextSelecting()というものの存在からは、意図としては 0文字選択を含まないようにもとれる。なんにせよ CViewSelect.ChangeSelectAreaByCurrentCursorTEST()が幅0選択を特別扱いして選択解除するのは意図がわからないし、仮に目的があったとしても不適切、あるいは不完全な処置だろうと思う。問題は選択解除によって IsTextSelected()が trueから falseに変わることで、IsTextSelected()は本当にあちこちから呼ばれているので ChangeSelectAreaByCurrentCursorTEST()の変更は影響範囲が広すぎる。(ステータスバーメッセージもそのひとつ)
そもそも、keepCurrentSelectionの条件に CViewSelect.IsTextSelected()は不要に思えるのでこれを外すことで対処。元のソースをできるだけ尊重するつもりでこうしてあったんだけど。
「末尾から再検索しました」が表示されないのは、条件が「先頭から再検索しました」と同じになっていたからでした。(不等号が逆向き)
「CViewSelect.cppの修正は、幅0なら何もしないのではなく、 (略)」 else節で「pSelect->Set(ptCaretPos);」と同じことをしていたつもりです。また「m_nLastSelectedByteLen = 0; // 前回選択時の選択バイト数」の扱い方がわかっていないのですが、選択解除もしていないのに「前回選択時の~」というのはあたらないのではないかと。
コメントで指摘されて rev2で導入した sel.IsTextSelected()を sel.IsTextSelecting()に変更したのは、CViewSelectの変更を取り消したことによって、検索結果による選択範囲の拡大(縮小)の結果が幅0になったときに sel.IsTextSelected()が falseになってしまうことへの対策。(選択開始点から先へ検索が進まなくなってしまうので)
「本の虫: シンタックスシュガーとしてのlambdaの解説」
ifの条件文に && や || が 3つも 4つも連なってくると 1つの Predicateにまとめてしまって名前を付けたくもなる。でも struct{ bool operator()() const {...} } IsHoge; と書くだけでも面倒なのに、スコープが断絶してしまうために、判断に必要な変数にアクセスするためにはコンストラクタで参照を受け取ってメンバ変数に保存しなければならない。コンストラクタを書くために型名も付けなければならない。もうね、やってられない。どうせコンパイラの最適化で消えてしまうコードを長々と書くのは無駄。消えなければもっと無駄。はやく lambdaを。
http://sakura-editor.svn.sourceforge.net/viewvc/sakura-editor?view=rev&revision=1724
とにかく無限ループで強制終了しかできなくなるのは良くない。
* 「# 幅0の上検索がいつまでもその場足踏みしてないで上へ進むように修正。 # キャレットより前の、幅0の行頭マッチがハイライトできていなかったのを修正。(あんまりやりにくいので CViewCommander::Command_SEARCH_PREV()から gotoを取り除いて、不必要に選択範囲を保存するのをやめた)」
⁑ CViewSelect.IsTextSelected() -> return CLayoutRange m_sSelect.IsValid() -> return CLayoutPoint m_ptFrom.BothNatural() && CLayoutPoint m_ptTo.BothNatural()。BothNaturalという名前だけど、実際は xと yが共に 0以上かどうかをテストしている。選択範囲の始点と終点の X,Y座標がすべて 0以上のとき CViewSelect.IsTextSelected()は trueを返す。
♭ ななしfix_searchword_selection_with_selectinglock_on 置換前:$ 置換後:..
♭ ななしてけとー。 CViewCommander.cpp 【追加】 3116: const bool wasSelected..
♭ ななしや、 3158: (sel.IsTextSelected() && matchLayoutRange.GetF..
♭ ななしrev2 「先頭(末尾)から再検索する」をONにしているのに、 末尾から再検索しても「▲末尾から再検索しました」 が..
♭ ななし「選択幅ゼロ」は自明なので一切表示しなくていいと思います。
♭ ななしCViewSelect.cppの修正は、 幅0なら何もしないのではなく、 以下のようにしたほうが良くないですか? ..
♭ ななしrev2です。 abc というテキストで、 置換前:abc 置換後:xyz 先頭(末尾)から再検索する:ON 置換対..
♭ ななし※同じく、置換後を abcxyz、置換対象を[選択文字(0)]としても起きた
♭ 名無しhttp://sakura.qp.land.to/?Macro%2F%C5%EA%B9%C6%2F153
♭ 名無し「Wiki Macro/投稿/153」がまさに相当するマクロだと思うけど。 他にも関連マクロで「Wiki Macr..
♭ 名無しVisual Studioが本元かな? 調べてみたらEmEditor Freeにも同じ動作の 次の文字列を検索(Ct..
♭ ds14050おおぅ。まさしく。 「ダブルクリックで単語ハイライト」とか聞いたことがあるけど、あれの変種でしたね。図らずも VC..