/ 最近 .rdf 追記 設定 本棚

脳log[SakuraEditor: 2013-04-14~]



2013年04月14日 (日)

最終更新: 2013-04-15T03:23+0900

[SakuraEditor][Ruby] サクラエディタBBS[7601]

  • Editor定数の参照で落ちる。他の名前なら問題なし。
  • $Editorとすることで Editorオブジェクトが得られる。
  • マクロコマンドは先頭を小文字にしないと呼べない。(TraceOut→traceOutなど)
  • Editorオブジェクトに SCRIPTITEM_GLOBALMEMBERSフラグが付いてると、Rubyマクロのばあい ITypeLibが必要になる。(ITypeInfo->GetContainingTypeLibを実装する必要がある)
  • ITypeInfo->GetFuncDescがマクロコマンドの数(271)×3回、マクロを実行する前に呼ばれる。
  • 3回目に取得された ITypeInfoがリリースされない。
  • Editorオブジェクトもリリースが足りない。
  • 実行の成否にかかわらず一回につき 100KBぐらいメモリ使用量が増える。
  • リソースリークをなくしたければ参照カウントを捨てて、マクロ実行の前後ですべてのオブジェクトの作成・破棄を行うのが確実。
  • 12回目のマクロ呼び出しが必ず失敗する。例外が発生しているもよう。
  • TYPEATTR.cFuncsの数を減らしてマクロコマンドの数をごまかすと 11回を超えて成功するようになったり。リリースモードにしても回数は変化する。
  • 失敗しても繰り返しマクロを実行してるとときどき成功する。
  • マクロ実行に失敗するとき、IActiveScriptParse->ParseScriptText直前の IActiveScript->SetScriptState(SCRIPTSTATE_STARTED)呼び出しから足取りがつかめなくなる。
  • SetScriptStateを飛ばして ParseScriptTextを実行するようにすると例外はなく、正常にエラーメッセージ("実行に失敗しました")が表示される。なんにせよ失敗。
  • スクリプトエンジンをマクロ実行ごとにきれいに片付けられていれば、○回目から失敗みたいなことは起こらないと思うんだけど。なにが継続しているのか、あるいはこちらの何が破壊されていってるのか。

どうせ Rubyマクロはコマンドの先頭を小文字にする必要があって他のマクロと同じように書けないのだし、使われてないからこれまでに書かれたマクロ資産との互換性を図る必要もないし、例外とリークの元になり実行前の負荷も発生させる SCRIPTITEM_GLOBALMEMBERSフラグを落とすのがいいと思う。ScriptEngine名が "RubyScript." で始まるときとかに限って。

SCRIPTITEM_GLOBALMEMBERSフラグを落とすと $Editor.insTextだけのマクロは何十回でも問題なく実行できてるけど、それだけで安心してよいものか。Editorと書いたときのように(数字で始まるマクロコマンドを呼んだときも?)初回で確実に落ちるというだけならいいけど、何回も実行してるうちに運が悪ければ落ちるというのがあれば(たち)が悪い。


2012年10月23日 (火) 役に立つ機会があるかはともかく、least negative valueという表現。そんなに、ネガティブ(負)じゃない、値。-35と -35.5では -35が LNVらしい。※言及リンクは省略しました。

最終更新: 2012-10-24T00:56+0900

[SakuraEditor] またやらかしてたみたい。これ→20091026p01

矩形の選択中の未選択状態でコピーをすると矩形のままになる - ID: 3578282

IsBoxSelectingは IsTextSelectingに含まれる概念だと思われるから IsTextSelecting(0幅選択を含む選択状態)と IsTextSelected(1文字以上選択されている)の2つだけで判定条件を書きたい。0文字選択→選択キャンセル&移動。1文字以上選択→選択キャンセル。実際の処理は共通でいけるはず。

IsTextSelectingは BoxSelectが必ずロックを伴うことを当てにして今のように書かれてる気がするので追い追い修正が必要になりそう。>20090923p01

でも黙っとく。実際に正しく動くか検証もしてないし。


2012年10月02日 (火) すすぐ、というのは不純物の入った水を万倍の万倍の万倍に薄めて無いも同然になりました、ってこと? 理科の先生が一生懸命いつまでもこするより回数を増やした方がいいって言ってるのを見た記憶があるけど、万にかかる係数を増やすより指数を増やした方が効率がいいって事?■検索……。「洗浄の回数について - 質問・相談ならMSN相談箱」 同量の水を小分けにして回数を増やす。溶解の速度。廃液を減らす。初めて聞いた言葉>コンタミ(contamination)。

最終更新: 2012-10-02T16:53+0900

[SakuraEditor] マクロのお試しとかデバッグに。

選択された文字列かファイルの全体を JScriptマクロとして実行する。登録の手間なしにマクロを試してみたり、マクロのデバッグ&実行を登録や読み直しの手間なしに行うために。何個目の車輪になるのか数え切れないほどだと思ったので書いてなかったが、今日読んだ本*に同じようなアイディアが書いてあったので。2010年作。

/*
	InstantMacro.js
	選択テキストまたはファイル全体を JScriptマクロとして実行する。
*/

var jsmacro = Editor.GetSelectedString(0) || Editor_AllText();
try {
	eval(jsmacro);
} catch(e) {
	Editor.TraceOut(e.message);
}

function Editor_AllText()
{
	var text = "";
	for(var n = 1, n_max = Editor.GetLineCount(0); n <= n_max; ++n) {
		text += Editor.GetLineStr(n);
	}
	return text;
}

* リンク先は今日読み終わった本。このマンガを読んでも出てこない。


2012年08月09日 (木) [Vista] 驚愕の事実。「Windows 8でもっとも進化したもの、それはマインスイーパ | スラッシュドット・ジャパン」Vistaを5年以上使用してきてマインスイーパを今日初めて起動した!ピンボールに次いで、フリーセルと同じくらいよくやってたのに。■ Vistaに限れば一番よく起動したのは上海だった。Flappyと同じくらい懐かしさを感じるゲームだ。

最終更新: 2012-08-10T23:22+0900

[SakuraEditor] cacheExt.xmlから history要素を取り除くときにどれだけのサイズ削減効果があるのかを把握していちいち喜びを感じたいが検索によって選択された領域のステータスバー情報が一瞬で消えてしまうので

Index: sakura_core/CViewCommander.cpp
===================================================================
--- sakura_core/CViewCommander.cpp	(リビジョン 55744)
+++ sakura_core/CViewCommander.cpp	(リビジョン 55745)
@@ -3035,9 +3035,6 @@
 			//	2005.06.24 Moca
 			m_pCommanderView->GetSelectionInfo().DisableSelectArea( bReDraw );
 			m_pCommanderView->GetSelectionInfo().SetSelectArea( matchLayoutRange );
-			if( bReDraw ){
-				m_pCommanderView->GetSelectionInfo().DrawSelectArea();
-			}
 		}
 
 		/* カーソル移動 */
@@ -3046,6 +3043,15 @@
 		GetCaret().MoveCursor( matchLayoutRange.GetFrom(), bReDraw );
 		GetCaret().m_nCaretPosX_Prev = GetCaret().GetCaretLayoutPos().GetX2();
 
+		if( bReDraw && !keepCurrentSelection ){
+			// keepCurrentSelectionのときは不要っぽい。
+			// ステータスバーに表示される選択領域のサイズが
+			// (たぶんカーソル移動によって)消去されないように
+			// 後ろの方に移動してきた。
+			/* 選択領域描画 */
+			m_pCommanderView->GetSelectionInfo().DrawSelectArea();
+		}
+
 		/* メッセージ */
 		if( PointCompare( originalSearchPos, searchPos ) < 0 ) {
 			m_pCommanderView->SendStatusMessage(_T("▲末尾から再検索しました"));
@@ -3218,10 +3224,6 @@
 		} else { // マッチ範囲で選択範囲を置き換える。
 			sel.DisableSelectArea( bRedraw );
 			sel.SetSelectArea( matchLayoutRange );
-			if( bRedraw ){
-				/* 選択領域描画 */
-				sel.DrawSelectArea();
-			}
 		}
 
 		/* カーソル移動 */
@@ -3230,6 +3232,15 @@
 		GetCaret().MoveCursor( matchLayoutRange.GetFrom(), bRedraw );
 		GetCaret().m_nCaretPosX_Prev = GetCaret().GetCaretLayoutPos().GetX2();
 
+		if( bRedraw && !keepCurrentSelection ){
+			// keepCurrentSelectionのときは不要っぽい。
+			// ステータスバーに表示される選択領域のサイズが
+			// (たぶんカーソル移動によって)消去されないように
+			// 後ろの方に移動してきた。
+			/* 選択領域描画 */
+			sel.DrawSelectArea();
+		}
+
 		/* メッセージ */
 		if( PointCompare( originalSearchPos, searchPos ) > 0 ) {
 			m_pCommanderView->SendStatusMessage(_T("▼先頭から再検索しました"));

2012年07月01日 (日)

最終更新: 2012-07-01T14:27+0900

[SakuraEditor] CEditView::IsSearchStringという無茶な関数。

  • 検索条件を thisで与え、検索対象を引数で与える。(なぜ検索対象が可変?そのせいで対象となる文字列(連続したバッファ)が必要で、将来的に複数行検索に対応できない)
  • 仕様(出力)が検索オプションで変わる。
  • 検索コードを呼ぶのでなく自分でマッチ判定をしてる。(コピペコード)
  • 検索語ハイライトを行う CColor_Foundからしか呼ばれていない。
  • (関数の目的から)一文字一文字呼ばれることを想定しているが、検索情報を蓄えたりせず(できず)、その場その場で判断している(無駄が多い)。CColor_Foundの方が、行が変わるごとに通知があり行末に向かって順次実行されることがわかっているぶん戦略的に動ける。

というわけで、CEditView::IsSearchStringからコピペコードを廃すると CColor_Foundが知りたがっている何番目の単語がマッチしたのかを知るためにさらなる検索が必要になるにもかかわらず、CEditView::IsSearchStringという変態のために仕様を決める必要は全然ない気がしてきた。仕様ってのはこれの→「sakura-unicode:1830」「複数単語検索のブックマーク・Grep対応 - ID: 3539115」。CEditView::IsSearchStringには消えてもらって CColor_Foundと CSearchAgent::SearchWordの組み合わせで何とかすべき問題ではないかと。SearchWordだと検索結果が改行をまたぐようになってもそのままで適応する利点もある(CColor_Foundと CColorStrategyの方には対処が必要だが)。


2012年06月22日 (金)

最終更新: 2012-12-05T05:04+0900

[SakuraEditor] InsTextマクロでドキュメントを変更しても(変更)フラグが表示されない。 (BugReport/99) - SakuraEditorWiki

前に自分が引っかかったのと同根。「タブやタイトルバーに変更フラグが表示されるように修正した。フラグ自体は立ってたけど描画が行われていなかったというミス。(20100620p01)

変更フラグを管理してるのは CDocEditor。ドキュメントを変更した関数が SetModified(bool modified, bool redraw)メソッドでこれに通知するが、更新フラグが立ったとき(落ちたとき)に描画が抑制されていると、以後ドキュメントの変更をトリガにしたキャプションの変更機会を失う。キャプションの内容は変数展開、条件分岐を利用して高度にカスタマイズが可能で、キャプションの更新を必要最低限にケチるのは理に適ってる。ではどうするか。描画の抑制を描画の遅延ととらえて、抑制中に加えられた描画に影響する変更を記録して、後でまとめて描画する? Webブラウザが JavaScriptに対して行ってるように? それは大変。マクロ由来のコマンドを描画を抑制して実行してるのは CMacro。かといって CMacroがコマンド呼び出しの前後で描画を適切に維持するのは出過ぎた行為。さっき「キャプションの更新を必要最低限にケチるのは理に適ってる」と書いたけど、描画の抑制をやめるのが一番簡単。だって Charマクロで InsTextのような問題が起きないのは、Charマクロの実体関数が redrawフラグを受け取らないで常に描画を行ってるせいだから。

 余談: InsTextで何をしていたのか。

<2012-06-25> ReDrawマクロの存在を教えてもらったのでちょっと修正。なんでこんな(描画に問題があるときに実行して下さい)コマンドがあるんだか。

現在の編集ウィンドウを再描画します。何らかの原因で画面表示を最新状態に更新したい場合に使います。

【例】 ステータスバーを非表示にしたとき、メニューバーの左側にステータス情報が表示されますが、ファイル名のチップ等で消されてしまうことがあります。そういう場合に使います。

なんで手動でやらそうとしたんだ……。 </2012-06-25> <2012-07-04> ……って、その、メニューバーの左側右端に表示されるステータス情報は、もう消えなくなってるアレだ。「SourceForge.net Repository - [sakura-editor] Revision 1594</2012-07-04>

/** OneTouchIndent.js
 * サクラエディタのマクロ。
 * Tabキーに割り付けて使う。
 * 前の行にならって同じインデント(Tab,Spaceなど空白文字全般)を挿入する。
 * Enterをトリガーにしたオートインデントってイマイチじゃない?
   一段深すぎたり、空行を挿入したかったりするときに削除の手間が必要で。
   このマクロは、Tabキーを押す手間は必要だが、望まないインデントは行わない。
*/

if (OneTouchIndent()) {
	Editor.ReDraw();
} else {
	Editor.IndentTab();
}

function OneTouchIndent() // returns true(done) or false(undone)
{
	// 文字列選択中はインデント文字の挿入ではなく、インデントを行いたい。
	if (Editor.IsTextSelected) {
		return false;
	}

	var caret = eval(Editor.ExpandParameter("({y:$y-1, x:$x-1})"));

	// 前の行にならってインデントの文字と量を決定するので、先頭行では(デフォルトの)インデントを行いたい。
	if (caret.y < 1) {
		return false;
	}

	var thisline = Editor.GetLineStr(caret.y+1);
	var prevline = Editor.GetLineStr(caret.y);
	var previdnt = prevline.match(/^(?:(?![\r\n])\s)*/)[0]; // 行頭の、改行を除く空白文字

	// prevline[0...previdnt.length]
	// thisline[0...caret.x]
	if (previdnt.length <= caret.x) {
		return false;
	}
	if (previdnt.substring(0, caret.x) !== thisline.substring(0, caret.x)) {
		return false;
	}

	Editor.InsText(previdnt.substr(caret.x));
	return true;
}

 @2012-12-05

気付くのが遅すぎるけど、インデントを深くしたいときには意識的にタブキーとスペースキーを使い分けないといけなかった。そういうのを気にせずワンボタンで済ませられたらなお良かった。


2012年05月17日 (木) exeにデバッグ情報などとしてユーザー名(を含んだパス)が埋め込まれることへの対策が必要。過去にアップロードしたあれとかあれとかあれとか。

最終更新: 2013-04-02T03:37+0900

[SakuraEditor] サブパターンハイライト。

348 :名無しさん@お腹いっぱい。:2012/05/15(火) 20:41:18.84 ID:F7CbiPBA0

正規表現検索でグループ化してる部分を全体一致とは別の色で表示するにはどうすればいいのでしょうか?

こうですか? subpattern_highlight.patch(7.7KiB)

  • 繰り返し付きグループは最後のキャプチャしか認識しません。
  • 包含関係が見えるように色を塗れるといいのだけどね。
  • 正規表現キーワードでもキャプチャグループを塗り分けたいね。
  • ハイライト関連は性能劣化が怖い。(すでに個人ビルドでやっちゃってるから)

 でばぐ@2012-09-28

なんでこれでいけると思ったのかが不思議なほどバグってた。スクリーンショットを撮ろうとしても、うまくいくケースを見つける方が難しい。修正した。

subpattern_highlight.rev2.patch(7.8KiB)

再帰パターンとか繰り返し(量指定子)付きグループをうまく色分けすることはできないので、あんまり実用性はない。

※ベースラインから下が切れてるのはサクラエディタのせいではありません。


2012年02月27日 (月) 変な茶々は入れるまい。リンクはなし。STDINと(省略された)$stdoutの組み合わせはちぐはぐだとか、Scripting.FileSystemObjectは最初に一回だけ作成して使い回すんだとか、WshScriptExecっていう入出力を扱うオブジェクトが Windows(WSH5.6から)に用意されていて JScriptで利用できるんだとか、コメントアウトされた echoバージョンのコマンドでもウチでは動いた(※だけどところどころ lineの内容によって指定されたファイルが見つからないというメッセージが出た)とか、言いたい。

最終更新: 2012-02-29T12:47+0900

[SakuraEditor] なんで ActiveScriptRuby(旧称?)を直接使わないの?

と思わないでもないけど、Rubyマクロにはエディタ側に色々と問題があるのがわかってるので、大枠に沿ったまま書き直してみた。WshScriptExecを使ってみたかっただけ。WshScriptExecを得る方法は WScript.Shell.Execだけなんだけど、これを実行すると必ずコンソールが表示されるのがうまくない。こっそり実行して処理結果だけ欲しいのに。

 script.rb

# coding: windows-31j
$/ = "\r\n"
$stdout.sync = true # putsした内容をすぐ flushして .jsが受け取れるように。
puts("[size = % 4d]" % $_.chomp.size) while gets

 call_ruby.js

var RubyBin = "ruby";
var RubyScr = "script.rb";

var RubyExec = new ActiveXObject("WScript.Shell").Exec("\""+ RubyBin +"\" \""+ RubyScr +"\"");
RubyExec.StdErr.Close();

/*
  (折り返し行でない)改行単位でのカーソル移動が「GoLineTop」しかなさそうなので、これを基にしてカーソル移動を行う。
  ExpandParameterで $yの変化を監視する手もあるにはある。
*/

// 開始地点(最終行)へ移動。
Editor.GoFileEnd();
Editor.GoLineTop(9);
if (! Editor.GetLineStr(0)) {
  Editor.Up(); // skip [EOF] only line.
}

// 下から上へ一行ずつ処理する。
for (var linenum = Editor.GetLineCount(0); 1 <= linenum; --linenum) {
  if (RubyExec.Status != 0) { // if not running
    break; // 継続は無意味。
  }

  RubyExec.StdIn.WriteLine(Editor.GetLineStr(0).replace(/(?:\r\n?|\n)$/, "")); // カーソル行の文字列をRubyに送る
  Editor.InsText(RubyExec.StdOut.ReadLine());

  //カーソルを上の行の先頭へ移動
  Editor.GoLineTop(9);
  Editor.Up();
}

RubyExec.StdIn.Close();
RubyExec.StdOut.Close();
RubyExec.Terminate();

2011年12月09日 (金) リファクタリングとパッチ。パッチはそう易々と構造変革を乗り越えられない。自分専用のスペシャルパッチがたまればたまるほどリファクタリングが悪に見える。347KBの差分を前に途方に暮れています。

最終更新: 2011-12-14T19:35+0900

[SakuraEditor] これに関する戦略。

  1. (下拵え1) 色分けに行をまたぐ機能を追加。
  2. (下拵え2) 個々の色分けユニットの移植。(結果が変わらないこととパフォーマンスへの影響が焦点)
  3. (下拵え3) レイアウトと絡んだ古い色分け機能の削除。
  4. (餌1) 正規表現キーワードのキャプチャグループ*別色分け対応(設定の画面とiniへの入出力が面倒だから最初は隠し機能として)。
  5. (餌2) K2Editorっぽい(※勝手な想像です)ヒアドキュメント対応色分け規則追加(正規表現で開始・終了を指定する複数行コメントみたいなもの。終了パターンは開始パターンのマッチを使って $N, $$を置き換えてからコンパイルする。${N}もいる?)。
  6. (本命) SHJSっぽい色分け規則追加(GUIで設定するのは無理だから隠し機能として)。
  7. (できれば)色と色分けと CEditViewの分離・凝集。
  8. (できれば)機能に着目した色名の追加。「正規表現キーワード(定数)」とか。

ヒアドキュメントといえば前にも書いて(そんで忘れて)たが、

print <<HEAD, <<BODY
HEAD
BODY

みたいなのをどうするのかってことだ。<<HEAD...HEADの中に BODYだけの行が来ないことを期待しつつ、一番後ろの <<BODY...BODYだけを対象にするとか?でも <<HEADが来た時点でコメントモードが始まってしまうな。終了パターンで $+ (最後のキャプチャ内容)が使えたらいいのか?そもそもこの姑息な手でいくのか?それに開始パターンで <<HEADから、<<BODYをキャプチャしつつ、改行までを食うとしても、こういうスクリプトを想定してしまうわけだ。正規表現を使った簡易ハイライトだというのに。

p "" << <<"HEAD" <<"NECK" << <<"BODY"
<head>
HEAD
<body>
BODY
#=> "<head>\nNECK<body>\n"

* 繰り返し付きグループの色分けはたぶん最後のマッチだけが対象になると思う。


2011年08月17日 (水) な、なんだってー。構文木がコウブンボクじゃないとか……。もしやと赤黒木を Wikipediaでみると、こちらもセキコクボクではなかった。赤黒黄とかどんな冗談。もうひとつ、B木もビーボクじゃなかった。ぎゃー。もういい。red-black treeと B treeで十分だ。(こういうデータ構造を本で読んだのって Windows PCを触り始めた翌年の、オブジェクト指向やらオートマトンの本を図書館で借りたのと同じ頃(だけ)だ。県立図書館++。それにくらべて今の自分は……)

最終更新: 2011-08-21T01:48+0900

[SakuraEditor] 正規表現検索。トリック。不完全。

 (?imx-imx)        孤立オプション
                     i: 大文字小文字照合
                     m: 複数行
                     x: 拡張形式
 (?imx-imx:式)     式オプション
 補記 1. 文法依存オプション
  + ONIG_SYNTAX_RUBY
    (?m): 終止符記号(.)は改行と照合成功
  + ONIG_SYNTAX_PERL と ONIG_SYNTAX_JAVA
    (?s): 終止符記号(.)は改行と照合成功
    (?m): ^ は改行の直後に照合する、$ は改行の直前に照合する

サクラエディタが自動で mフラグをくっつけて m/pattern/km みたいなのを正規表現ライブラリに渡すので油断していた。インラインでフラグを変更する方法がある。

ところで、mフラグは実装間で意味に一貫性が無く、また鬼車のフラグも間違いを誘うような名前をしているので注意が必要。みんな ECMAScriptに倣え!

 + 孤立オプションの有効範囲は、その孤立オプションを含んでいる式集合の終わりまでである
   例. (?:(?i)a|b) は (?:(?i:a|b)) と解釈される、(?:(?i:a)|b)ではない

フラグの意味に加えて、その有効範囲の面倒くさいことよ。これに対処するくらいなら他の方法を考えるレベル。Onigmoは PCREみたいに、パターンのコンパイル時オプションとして「改行」を意味する文字を指定することに対応してくれないのかな。>NEWLINE CONVENTIONS(pcre.txt)


mフラグを OFFにする目的は何かといえば、JavaScriptと bregonigにおいては $ と ^ が改行前後にマッチしないように、Rubyにおいては . が改行にマッチしないように、ということだ。

「$ と ^ が改行前後にマッチしないように」は言い換えると「^ と $ が文書の頭と末尾にだけマッチするように」ということだが、サクラエディタにおいては従来、文書の先頭・末尾と各行文字列の先頭・末尾は区別できず、各行文字列末尾と改行直前の区別は曖昧だった。であれば、この問題は複数行検索が実現するときまで先送りしても差し支えないだろう。(ないよね?)


2011年06月26日 (日) アニメ(※順不同ではない)。シュタゲは毎回 30分が短い。世界線が切り替わる度のあの喪失感と絶望。変わらないまゆしぃの安心感。ぬるぽに即答できる助手から重度の厨二病のおかりんまで、その他のキャラもみんな愛おしい。あの花は良いアニメ(それでもめんまのかわいさが肝)。ロッテはあの世界とそれにマッチした「真夏のフォトグラフ」が好きだ。A-channelはユー子の関西弁が目当て。

最終更新: 2017-09-20T01:01+0900

[SakuraEditor] >> 脳log[2010-06-10-p01] サクラエディタの正規表現キーワードを SHJS相当にしたい。(その二)

新たなバグもなく、すっかり終わってしまったプロジェクト。やり残しは、従来の、状態を持たない正規表現キーワードを色分けストラテジの一つとして移植すること。コメントや URLの色分けなんかと同じで、従来の正規表現キーワードも SHJS相当の正規表現キーワードと共存できる。そのために、協働するために余計な面倒を抱え込んだんだし。

あと、rkw2フォルダやファイルに隠し属性がついてたら読み込まない、とか。

 @2017-09-19

スペース(0x20)が C_SPACEである一方、HT(0x9)/CR(0xD)/LF(0xA)が C_WHITE(その他の空白)であるせいで、タブが改行と同じ分類なせいで、一行コメントがタブインデントで終了してしまっていた。

 @2017-09-19

HTML.rkw2を自作しようとしてすごく面倒くさいというか、色分け方式の能力不足を感じた。

"move" して "exit" したときに、move元の Stateに戻るだけではなくその中の moveした Patternそのものに戻り、その次のパターンから色分けを再開しなければいけないのではないか。

それはちょっと面倒だったので、"move" と "exit" が同時に指定されていたときは "move"先から exitしてきたときに "exit" が発動するようにした。サブルーチン的に使える。20170919.patch

そんなこんなで HTMLと CSSと JavaScriptの色分けを同時にするどころではなかった。HTML.rkw2。HTMLと CSSと JavaScriptが混在するときでも通用する色指定とは。


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で変わらない)削除・追加を受け付けたりできるよね。

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