縦書き編集機能とか実装できるほどのスキルがあればいいんだけどねえ。
2chに化けるという書き込みがあって試してみたら表示が消しゴムで消すように欠ける。描画漏れだと思ったんだけど、後で調べたらそもそもメッセージを保存していなくて再描画するつもりがない。だったら改善す"べき"とまでは思えないんだよね。(タイポのようなものの指摘はできても、自分の考えを押しつけることまではできないし)
ステータスバーが非表示のときにメニューバー右端に表示されるメッセージの、再描画に対応。一時メッセージだとしてもメッセージが半欠けの状態で表示されてたらバグととられても仕方ないから。> fix_menubarmessage.diff
この修正中にこんな処理が行われていたことを知ったのだけど……
// 編集ウィンドウ切替中(タブまとめ時)はタイトルバーのアクティブ/非アクティブ状態をできるだけ変更しないように(1) // 2007.04.03 ryoji // 前面にいるのが編集ウィンドウならアクティブ状態を保持する
タブ切り替え時に二つのサクラエディタウィンドウが重なる瞬間があって、Aero Glass効果が有効だとこの時にタイトルバーの透明度が下がる(色が濃くなる)。結果、対策もむなしくちらついて見える。これに対応した対処法はあるかな?
行・列番号の表示よりも右の部分にゴミが表示されます。
Vistaしかないので制御文字が半角空白に置き換えられたときに区別できるように、メッセージの余白を「 」ではなく「*」で埋めて表示してみたけれど表示は変わらない。この、メッセージの余白を埋める文字がすべてゴミになっているのだろうか。2chの
ステータスバーを消すとメニューバーの右端が化けちゃうんだけどどうすれば
というのを読んで俺は表示が欠けることを指して化けると言っているのかと思ったんだけど(繰り返すけど Vistaだとゴミは見えないので)、この書き込み主は Windows2000でも使っていて半角の「・」のことを指して化けると言っている可能性もあるかも(俺がバグを仕込んだのではないと思いたい)。
タブ切り替え時のちらつき防止はノーアイディア(あったら書いてる)。せっかく見映えの細かいところにまで気が配られているのに自分の環境で働いていないってのは悲しいから、Aero Glassにも対応できたらいいよね。
_tcsncpyが、コピー元が短いときにコピー先の末尾に埋める '\0' が「・」に変換されるんだ。Cの林立する文字列操作関数が大嫌いでいつも(といって片手で数えられるほど)は std::stringに逃げるんだよね。元々のソースはちゃんとやってたのに、俺がテケトーなことをしたわけだ。確保した領域の一つ先に書き込むとか言い訳できないミスもしてるし……。
今度は右端に埋め文字(「 」の代わりの「*」)が見えた > fix_menubarmessage(rev2).diff
さらなるチョンボ(泥沼の様相を呈してきました)。さっきの改訂でメッセージが空になることがなくなったので、表示したメッセージのクリアが行われないはずだ。
もう最後にしたい > fix_menubarmessage(rev3).diff
最終更新: 2009-08-26T17:01+0900
要望を書いて次の日になんとかするセルフサービス > open_tab_right.diff
便利なメソッド( CTabWnd::ReorderTab )が既に用意されていたので楽でした。
結果はわりと希望通りの動作。
バックグラウンドでタブを開く機能はないから、連続してファイルを開いたときに新しいタブが右に延びるか左に延びるかということは考えていない。(01234...となるか 0...4321となるか。特別に考慮しなければ後者になる)
タブを閉じたときに次にアクティブになるタブは、多分直前にアクティブだったタブ。理想とする Firefox + TabsOpenRelativeだと、基本的に閉じたタブの右側のタブがアクティブになるものの、ある条件で元のタブ(閉じたタブの左側のタブ)がアクティブになる。タブを閉じたとき次にアクティブになるタブにこだわりはないので変更していない。
知らなかったけど svk diffの出力をリダイレクトしたファイルが CR/CRLF混合。diff自身のメッセージが CR区切りになってるからみたい。いったいどこの diffを使ってるんだ。
よくみると CRの部分は改行がダブってる。CRCRLFが CR+CRLFと解釈されてるみたい。CRLFの LFに誤って CRを補ってしまったのかも。(だれが?)
あとは、常に「前回開いていたファイルを復元する」機能が欲しいところ。タブの順序、カーソル位置、スクロール位置、検索文字列、アンドゥ記録(は無理か)などなどの復元も込みで。
最終更新: 2009-09-02T23:17+0900
おかしい。チェックが外れていると正規表現キーワードによる色分けも無効になる。
まずはこちら
242 //色指定でチェックが入ってなければ検索しなくてもよい …… 249 //正規表現では色指定のチェックを見る。 …… 255 //正規表現以外では、色指定チェックは見ない。 256 //例えば、半角数値は正規表現を使い、基本機能を使わないという指定もあり得るため
このコメントを読めばまさしく現在の状況が考慮されていることがわかる。
仕様がねじれている気もするが、正規表現キーワードに「正規表現キーワード3」という色指定より「ダブルクォーテーション文字列」という色指定をしたいのだよね。基本機能を無効にして正規表現キーワードだけを使いたい場合もあるし(今回のように)、基本機能を使いつつ正規表現キーワードを使って、標準的でない文字列形式(Rubyの %!string! など)を補いたい場合もあり、そのときに複数の色指定を同じに保つより「ダブルクォーテーション文字列」という一つの色指定で色を管理したい、という要求がある。この両方を満たすのが以前の仕様。
待ってても直らないかもしれないので*他人の修正を待てないので調べた。
17 if( TypeDataPtr->m_bUseRegexKeyword 18 && pcView->m_cRegexKeyword->RegexIsKeyword( cStr, nPos, &nMatchLen, &nMatchColor ) 19 ){ 20 this->m_nCOMMENTEND = nPos + nMatchLen; /* �L�[���[�h������̏I�[��Z�b�g���� */ 21 this->m_nCOMMENTMODE = ToColorIndexType_RegularExpression(nMatchColor); 22 return true; 23 } 24 return false;
21行目の ToColorIndexType_RegularExpression(nMatchColor); とは実質的に
(EColorIndexType)(COLORIDX_REGEX_FIRST + nMatchColor);
こういうことだ。nMatchColorとはそのまま色指定なのだから COLORIDX_REGEX_FIRSTという下駄をはかせる必要はなくて
(EColorIndexType)nMatchColor;
これで十分のはずだ。正規表現キーワードだからって正規表現キーワードNという配色とは限らないのだよ。
[訂正] これはわざとだった。どんな色指定をされていても正規表現キーワードを他と識別するために行っている。同じファイル(sakura_core\view\colors\CColorStrategy.h)内に下駄を外す処理もある。
デバッガで nMatchColorの値を見てみたら 29であって、これはシングルクォーテーション文字列に対応した色インデックスだから期待通り。でも色分けはなされない。
なんでだろー。
223 /* 現在の色を指定 */ 224 void CEditView::SetCurrentColor( CGraphics& gr, EColorIndexType eColorIndex ) 225 { 226 //インデックス決定 227 int nColorIdx = ToColorInfoArrIndex(eColorIndex); 228 229 //実際に色を設定 230 if( -1 != nColorIdx ){ 231 const ColorInfo& info = m_pcEditDoc->m_cDocType.GetDocumentAttribute().m_ColorInfoArr[nColorIdx]; 232 if( info.m_bDisp ){ 233 gr.SetForegroundColor(info.m_colTEXT); 234 gr.SetBackgroundColor(info.m_colBACK); 235 gr.SetMyFont( 236 GetFontset().ChooseFontHandle( 237 info.m_bFatFont, 238 info.m_bUnderLine 239 ) 240 ); 241 } 242 } 243 }
232行目。色指定のチェックの有無のチェックを無効にしたらとりあえず色分けはされた。正規表現キーワードが正規表現キーワードN以外の色指定をしている場合、チェックの有無をみてはいけない。ここでのチェックを期待しているコードがある場合、悪影響がある。
* r1576@2009-05-27 21:15 で直りました。
最終更新: 2009-11-26T01:48+0900
改行コードの意図しない混在が嫌で、ファイル中に存在する改行コードをステータスバーに列挙してみた。
CRLF改行のみの一般的な画面 | LFと CRLFが混在。コピペなんかしてるとよくこうなる。 |
まずないだろうという判断のもと表示スペースを削った結果、一部の文字が切れてます。(CRとLFとCRLFが混在) | 改行がなければステータスバーにも表示なし。 |
publicなメンバ変数、豊富なアクセサ、中身すけすけで便利な friendクラス指定、管理下のデータメンバを非constで晒す C...Mgrクラスの constメンバ関数。どれも利用する側からすれば便利だったけど、オープンすぎて必要最小限の変更をつかまえることができずに毎回のフルスキャン。
どうするのがいいのかなあ。
Ctrl+Sに改行コードチェックマクロ(これから書く)を割り当てて、保存前に「改行コードが混在してるがそれでいいのか?」と確認しようか。すでに Ctrl+Sには Subversionを使ったバックアップマクロが割り当てられているが、どちらも JScriptなので片方を eval()でチェインして……。
最終更新: 2010-07-05T02:44+0900
既存のコード(主に検索ボックス)の切り貼りで、とりあえず機能するものに。
ソース面の難はニンともしがたいが機能面の問題くらいは何とかしたいところ。以下、わかっている問題点。
switch-caseで break忘れというまぬけぶりが原因だった。
フォント(HFONT)の削除漏れも修正した。
ツールチップはリストの上下数ピクセルで出ていた。(役に立たない!でもマウスオーバーでツールチップが出てもうるさいだけなのでそのまま)
他に、WM_PAINTで行っていた処理を、本来あるべき位置である WM_COMMAND(CBN_SELCHANGE)で行うように変更した。
キーボードアクセラレータを有効にするのは難しい。矢印や PageUp/PageDownキーまでが登録されているから、単純に有効にするとアクセラレータにそれらの入力を奪われてリストの操作が行えなくなる。
ドロップダウンリストにフォーカスがあるときでもエディタのキーボードショートカットを有効にした。優先順位は
なぜ一部のキーボードショートカットを無効にするかというと、リストの先頭のアイテムが選択されているときに Homeを押してもリストはこの入力を処理しない(すでに先頭が選択されているから)のだが、リストの選択位置に依存してキーの意味が変わってしまう(リストの先頭を選択↔キャレットを行頭に移動)のは不自然だと思うから。同様のキーをわかっている分だけ無効にした結果が上記リストの 2。モディファイアキーの状態やリストの選択位置を考慮して、もっと多くのキー入力をキーボードショートカットとして渡す余地はある(が、こんなアドホックな対処にこれ以上の手間をかけるのもどうかと)。
追従しないことにむしろ驚いた。ブラウザにできてテキストエディタにできないはずがない。
ファイル名も与えられていた場合は、それを上書き保存先にしてくれると尚良し。長めの出力をコマンドプロントからエディタに流して読んだりできる。
svn diff hoge.rb | sakura --stdin "hoge.rb.diff"
Set/GetWindowLongPtr(hwnd, GWLP_USERDATA, ) の代わりに Set/Get/RemoveProp(hwnd, TEXT("MyData"), ) を使うようにした。
参考> http://hilbert.elcom.nitech.ac.jp/~taki/program.html
以下のものを見つけた。
答え。GWLP_USERDATAはウィンドウに属し、その領域は WNDCLASSEX.cbWndExtraの値に従って確保される。
いったいどこを読み書きしていたんだろう? クラッシュしなかったのは Windowsが俺みたいなうっかりもののために余白を空けていたから?
言い訳。msdnのこの記述は非常に誤解を招きやすいと思う。予め 32ビットだけメモリが確保されてると勘違いしても仕方ないじゃない?
GWLP_USERDATA | ウィンドウに関連付けられた 32 ビット値を取得します。この 32 ビット値は、ウィンドウを作成したアプリケーションで使用する目的で各ウィンドウが持っているものです。この値の初期値は 0 です。
現状の理解で、この「32 ビット値」の出所は、読み書き(Get/Set)の単位が 4バイトだというところから。LONG=32ビットだから。
ここで、LONG_PTRが 64ビットのとき、GetWindowLongPtr(,GWLP_USERDATA)は 64ビット値を取得するのでは?ドキュメントあってる?という新たな疑問。
GWLP_USERDATAのように汎用的な場所から取得した値を恐る恐る CMainToolbar* にキャストするより、特別な名前をつけた場所に保存した値をキャストする方がまだ安心できる、という理由で改訂した。
ありふれた課題のようで GWLP_USERDATA を検索するだけで似たような話が見つかる。最初にリンクを張ったページは理解しやすかったが ATLのは難しい。これから読む > WTL/ATLのメッセージマップ実現のしくみ
GWLP_USERDATAと WNDCLASSEX.cbWndExtraが別物の可能性。
別物。GWLP_USERDATAは負のオフセット(-21)。cbWndExtraで確保した領域には 0から始まるオフセット(バイト単位)でアクセスする。
GWLP_USERDATAの有効な領域はポインタのサイズに関係なく、ドキュメント通りの 32ビットなのかについては winuser.hを見てもよくわからない。GWLP?_USERDATA(-21)から GWL_EXSTYLE(-20)まで差が 1しかないし……。GWLP?_* というのはオフセットでなく特別扱いされる値で、Windowsのソースを見ないと何もわからない、ということ? GWLP_USERDATAにポインタを格納できるのとできないのの差は大きいからハッキリ 64ビットサイズだと知りたい。
/* * Window field offsets for GetWindowLong() */ #define GWL_WNDPROC (-4) #define GWL_HINSTANCE (-6) #define GWL_HWNDPARENT (-8) #define GWL_STYLE (-16) #define GWL_EXSTYLE (-20) #define GWL_USERDATA (-21) #define GWL_ID (-12) #ifdef _WIN64 #undef GWL_WNDPROC #undef GWL_HINSTANCE #undef GWL_HWNDPARENT #undef GWL_USERDATA #endif /* _WIN64 */ #define GWLP_WNDPROC (-4) #define GWLP_HINSTANCE (-6) #define GWLP_HWNDPARENT (-8) #define GWLP_USERDATA (-21) #define GWLP_ID (-12)
// まだファイルタイプは取得できないっぽい。常に基本(0)になる。 //::SendMessageAny( m_hwndFileTypeBox, CB_SETCURSEL, m_pOwner->GetDocument().m_cDocType.GetDocumentType().GetIndex()+1, 0 ); ::SendMessageAny( m_hwndFileTypeBox, CB_SETCURSEL, 0, 0 );
とコメントアウトしていた部分を復活させて
::SendMessageAny( m_hwndFileTypeBox, CB_SETCURSEL, m_pOwner->GetDocument().m_cDocType.GetDocumentType().GetIndex(), 0 );
ちょっと修正した(謎の+1を取り除いた)だけ。
アプリケーションの起動と同時にツールバーが作成されるときであれば、コメントの内容は正しい。アプリケーションが起動してファイルが読み込まれた後でツールバーが表示する設定に変更されたとき(このときもツールバーが作成される)は、そうではなかった。
SHJSの javascript定義ファイル(lang/sh_javascript.js)の元になったファイル(javascript.lang)の中身がこれ。
include "java.lang" subst keyword = "abstract|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|final|finally|for|function|goto|if|implements|in|instanceof|interface|native|new|null|private|protected|prototype|public|return|static|super|switch|synchronized|throw|throws|this|transient|true|try|typeof|var|volatile|while|with"
javaて……。キーワードにしても使ったことのないものがいっぱい。
あまりにあんまりなんで一から書いた。(sh_javascript.js, sh_javascript.min.js)。 参照したのは JScript5.5の HTMLHelpなので JScript.NETや ECMAScript4には対応していない。古典的な JavaScript。
ついでに同じものを SakuraEditorにも。(javascript_keywords.zip)
最終更新: 2016-11-12T11:41+0900
ブラウザの等幅フォントを Consolasにした(20080110p01)だけではあきたらずエディタのフォントも Consolasにしようと思ったが……。
Firefoxは FontLinkを設定しなくても Consolasに足りない文字を他のフォントで補完してくれた。SakuraEditorは化けた。レジストリをいじって FontLinkを有効にして Windowsを再起動しても化けた。でも Unicode版の SakuraEditorなら化けなかった。
Unicode版はまだ SakuraEditorのメインストリームではない(というかバグバグ&レイアウト遅い)が、フォントのために乗り換えた。MSゴシックには戻りたくない。
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink] Consolas | REG_MULTI_SZ | M+1VM+IPAG-circle.ttf
http://sourceforge.net/tracker/index.php?func=detail&aid=1832567&group_id=12488&atid=312488
最終更新: 2016-11-12T11:41+0900
テキストエディタは、メモ帳、TeraPadときて、現在は SakuraEditorを、もう五年以上使っている。xyzzy(正式な読み方はないらしい。ジッズィと読んでいる。saxyunの読みがサッキュンなのは詐欺だと思います)や Meadowに移る気は無し。
構文ハイライトには興味がなくて、どこかからダウンロードしてきた強調キーワードファイルや正規表現キーワードファイルを使っていた。間違いがあっても正規表現を直したりはせず、オフにするだけ。邪魔にならなければいい程度の扱いだった。
ところが最近 SHJSをいじってたこともあって中途半端なハイライトが許せなくなってしまった。
そのためには鬼車が必要。BREGEXP.dllでは %Q<a<b<c>d<e>f>g> のように入れ子になった括弧の対応を調べられないので。
キーワードファイルはこの日記の SHJS(with カスタマイズ版 sh_ruby.js)を使ったハイライトとコンパチ。ただし完全移植ではない。サクラエディタの正規表現キーワードは正規表現一発で、マッチした全体を特定の配色にするだけだけど、SHJSはパターン中のキャプチャグループごとに配色を分けることができる。サクラエディタの制限で、正規表現が行をまたいでマッチできないことも影響がある。正規表現マッチが行をまたげないのは SHJSも同じなのだが、SHJSは正規表現キーワードから利用できるスタックを用意していて、行を超えて色指定を継続できる。
♭ ryojiパッチ(fix_menubarmessage.diff)を適用したものだと、 行・列番号の表示よりも右の部分にゴミが..