sakura editor マクロ追加しよう rev.2 自分(もか)がほしいなと思うEditor所有マクロ関数群を提案します。 上のほうが個人的に優先度が高いです。 既存のテクニックも、XPだけなら使えるとか、IE8だとセキュリティで使えないとか PerlScriptならできるとか、そんなのばかりなのでなるべく環境非依存で 皆でマクロを共有できるような追加機能を提案します。 (仮)でないものは、自分で実装する気があるものです。 オーバースペックではない程度で「これがないと不便だ」というのがあれば、 提案してください。 ■単位の定義 ・Logic_Y:Integer 論理行番号1開始 ExpandParameter("$y")と同じ座標系。いわゆる行番号 Grep結果/タグジャンプの行番号に同じ コマンドラインオプション -Y=/-VY= ・Logic_X:Integer 論理桁番号1開始 行頭からのオフセット(ACHAR/WCHAR単位)+1 ExpandParameter("$x")と同じ座標系。いわゆる列番号 Grep結果/タグジャンプの列番号に同じ コマンドラインオプション -X=/-VX= ・Layout_Line:Integer レイアウト行番号1開始 表示上の行頭からの位置 GetSelectLineFrom/GetSelectLineToと同じ座標系 ・Layout_Colm:Integer レイアウト列番号1開始。インデント幅、文字の表示幅を考慮 10242がおそらく最大値 GetSelectColmFrom/GetSelectColmToと同じ座標系 ・BOOL:Integer 0:false 失敗 1:ture 成功 その他 成功 ・ERROR_NO:Integer 0:エラーなし それ以外:エラー ・void JScript的には Undefined。 引数は()だと、未定なのか、引数なしなのか分かりにくいので(void)と書いてます 補足 ステータスバーの行、桁番号について これは少し特殊で、[タイプ]-[カラー]-[番号の表示]で指定可能 折り返し単位: 行: Layout_Line 列: Layout_Colm 改行単位: 行: Logic_Y 列: 改行単位行を折り返さない状態にしたときのカーソル位置 折り返し行(行番号が書かれない行)でないなら、Layout_Colmと同じ ■カーソル移動 TODO:選択範囲の扱いについて、考慮が必要そう サクラのコードからすると、 MoveCursorTo→MoveCursorLogic MoveCursorLayoutTo→MoveCursor のほうがいいかも。 ・MoveCursorTo(Logic_Y, Logic_X):void 指定の論理座標へ移動。移動したかどうかは別 普通のマクロでも使うように戻り値をvoidにした 実は「ExecCommand("sakura -Y=1 -X=1 filename.ext", 0)」で 移動できるらしいが、プロセスが一瞬増える 参考:MYWM_SETCARETPOS ANSI/CEditView::MoveCursor は引数がレイアウト行でした ・MoveCursorLayoutTo(Layout_Line, Layout_Colm):void 指定のレイアウト座標へ移動。移動したかどうかは別 論理座標では移動できない場所があるので必要 レイアウト座標だけだと、下のほうの変換関数が必須に。 普通のマクロでも使うように戻り値をvoidにした 参考:ANSI/CEditView::MoveCursorSelecting ANSI/CEditView::MoveCursorProperly ANSI/CEditView::MoveCursor Unicode/CEditView::MoveCursorSelecting Unicode/CCaret::MoveCursorProperly Unicode/CCaret::MoveCursor ■Sleep ・Sleep(msec:Integer):Integer BOOL msのお休み。20msから4000msが有効。それ以下・以上は範囲内に切り詰める。 長い場合はBlockingHookを勝手に呼ぶのも検討。 ずっと止められても困る。 BlockingHookを考慮して戻り値をDispatchWindowMessageと同じとして定義する ■対ユーザー基本ダイアログ ・InputBox(text:String, value:String, maxLen):String サクラの1行入力の流用/JScriptでめんどくさい text:String 表示メッセージ value:String デフォルト値。WSHではオプション。指定しないと""になる maxLen:Integer WSHではオプション。無指定と0以下は_MAX_PATH(260)。1023以上は1023になる。 1023なのはUnicode版ANSIビルドにおけるCDlgInput1の制限のため キャンセルされると空文字列が返る maxLenはANSI版とUnicode版ANSIビルドでは、SJIS単位の長さになる CDlgInput1ではタイトルを指定可能だけど"sakura from macro"に固定 参考:CDlgInput1 本物は[共通]-[強調キーワード]-[追加..]などでみれます ・MessageBox各種 サクラのメッセージボックスを流用 ErrorMsgBox(text:String):Integer BOOL [OK]ボタン WarnMsgBox(text:String):Integer BOOL [OK]ボタン InfoMsgBox(text:String):Integer BOOL [OK]ボタン confirmMsgBox(text:String):Integer BOOL [YES]/[NO]ボタン タイトルは"sakura from macro"に固定 textの長さは約16000まで。それ以上は切れる confirmはないので新設 改行は\r\nではなくて\nです MessageBox(caption:String,text:String,type:Integer):Integer Win32ほぼ直通 typeは本来UINTだけど符号付INTで我慢してもらう いずれも、親ウィンドウはsakuraのメインウィンドウ 参考:Debug.h ■ファイル関連ダイアログ サクラで使ってるのを流用 ・FileOpenDialog(defFilePathName, extFilters:String):String fileName ・FileSaveDialog(defFilePathName, extFilters:String):String fileName defFilePathName デフォルトのファイル名。かフォルダ名 フォルダ名/フルパスならそのフォルダを表示した状態で開くはず extFilters デフォルトのフィルターを指定。 "*.*" "*.html;*.js"など 指定されると拡張子補完も働くらしい キャンセル時は""を戻す。(nullではない) 本来はOpenFileDialog/SaveFileDialogなのだけど、.netのクラスと紛らわしいのでやめる 参考:CDlgOpenFile::Create DoModal_GetOpenFileName DoModal_GetSaveFileName ・DirectoryDialog(msg:String, defDir:String):String dirName msg 表示する文字列 例:「保存先フォルダを選択してください」 defDir ディレクトリ名。ファイル名は不可だとおもう 戻り値 キャンセル時は""を戻す。(nullではない) サクラのは新規作成ボタンがない。大きさが微妙 「Shell.Application」で作成可能らしいからいらないかも タイトルバーは「フォルダ選択」固定になるらしい 実物はGrepダイアログのフォルダ指定の「..」あたりをみてください 参考:ANSI/etc_uty.cpp SelectDir 参考:Unicode/util/shell.cpp SelectDir ■ANSI/Unicode対応 ・IsUnicode(void):Integer BOOL テキストバッファがUnicodeかどうかを返す。 Unicode版のANSIビルドでもtrue(1)。ANSI版は0 ・GetNativeLength(str):Integer Unicode版ならUTF-16の長さを返す。サロゲートペアは2になる Unicode版ならJScrptのString#lengthと同じ ANSI版ならSJISのバイト数 いわゆるstrlen ■指定期間・スコープの値取得・設定・削除 完全新機能だがほしい。 scopeはwindow か document windowはウィンドウ毎ウィンドウを閉じるまで。 documentはウィンドウ毎ファイルを閉じるまで。閉じるか、閉じて開く、開きなおすと消える。 名前をつけて保存では保持する ウィンドウ間/ファイル名毎(例:ブックマーク)、全プロセス設定などは、面倒なので実装しない プラグインの設定保持インターフェイスを活用するか個別にファイルに保存すべき 全プロセス共通、iniなどに保存しない起動中バッファは必要なら検討する 長さ/個数制限は検討中 ANSI版でも、Unicodeで保持する nameは、AppName.ValueName形式を推奨。階層は自由定義。大文字小文字は区別する nameで使用できる文字種は[a-z0-9_.]+以外は拒否するようにするかも ・GetCookie(scopeName, name):String 無いときは""を返す エラー番号は返せない ""になる ・GetCookieDefault(scopeName, name,defaultValue):String エラー番号は返せない ""になる ・SetCookie(scopeName, name, value):Integer ERROR_NO エラー状況 0:成功 1:scopeName が不正 2:nameが不正 3:valueが不正。長すぎるなど 4:個数制限 ・DeleteCookie(scopeName, name):Integer ERROR_NO エラー状況 0:成功 1:scopeName が不正 2:nameが不正 5:nameが存在していない ・GetCookieNames(scopeName, PrefixName):String PrefixNameで始まるnameを,で区切って返す 1つもないときは""を返す ■クリップボード標準 ・GetClipBorad(nOpt:Integer):String サクラ標準 参考:CEditView::MyGetClipboardData ANSIでは一度SJISを仲介することになる nOpt 予約。0を指定してください。改行コード変換とかを想定 ・SetClipBorad(nOpt:Integer, str):Integer サクラ標準設定 参考:CEditView::MySetClipboardData ANSIでは一度SJISを仲介することになる nOpt 予約。0を指定してください。改行コード変換とかを想定 ■ステータス表示 ・SetStatusMsg(str):void ステータスバーか右上にメッセージ表示 カーソル移動したり、何かすると消えます。 範囲選択中は選択情報が表示されているので使えません。 voidにしたので、マクロから呼び出せます プログレスと同時に表示できません。 ■長時間処理系 TODO:マクロがネストになっていて、競合した場合が心配 ・StartProgress(minRange:Integer, maxRange:Integer):Integer BOOL ステータスバーのプログレスバーを表示・初期設定 表示直後は、minRangeで指定した値を設定します。 minRange 0 - 65535の間の数字を指定 WSHで省略すると0になります。 maxRange 0 - 65535の間の数字を指定。minRangeより多きい必要がある WSHで省略または0を指定すると100になります。 戻り値 0: ステータスバーが非表示などの理由で、プログレスバーがありません 1: 成功 参考:win32 PBM_SETRANGE ・SetProgress(nPos:Integer):Integer BOOL プログレスバーの進行状況を設定 参考:win32 PBM_SETPOS ・EndProgress(void):void ステータスバーのプログレスバーを非表示に戻す ・DispatchWindowMessage(void):Integer BOOL メッセージ配信。どうなるかは未定義。 終了系以外の通常コマンドを拒否する機能を追加しないといけないかもしれない 戻り値 0: WM_QUITを拾った。速やかにマクロを終了してください。 (TODO: 要調査 Editor.WinClose() を呼び出してください) 1: 続行してもよいです 通称 DoEvents 参考:ANSI/etc_uty.cpp Unicode/util/window.cpp BlockingHook ・ShowCancelDlg(void):Integer ERROR_NO キャンセルダイアログをモードレス表示 外部コマンド実行の物を表示 表示できたら0を返す すでに表示されていたら1を返す それ以外は何らかのエラー ・SetCancelDlgMessage(strMessage, strTitle):Integer ERROR_NO キャンセルダイアログの表示を変更 strMessage ""でも""に変更する strTitle ""なら変更しない.WSHならオプション 成功したら0を返す ウィンドウがないなら1を返す(キャンセルされた場合も) それ以外は何らかのエラー ・IsCancelDlgCanceled(void):Integer BOOL 0: キャンセルされていない/ダイアログがそもそもない 1: キャンセルされた/ダイアログが閉じられた ・CloseCancelDlg(void):Integer BOOL キャンセルダイアログを閉じる。 0: ダイアログが表示されてなかった ユーザがキャンセルしたのも含む 1: ダイアログを閉じた ■(仮)論理レイアウト座標変換 X,Yまとめたいけど、どうすればいいかわからない TODO:要調査.存在しない位置の場合の処理 ・GetLayoutToLogicY(Layout_Line, Layout_Colm):Integer Logic_Y ・GetLayoutToLogicX(Layout_Line, Layout_Colm):Integer Logic_X ・GetLogicToLayoutLine(Logic_Y, Logic_X):Integer Layout_Line ・GetLogicToLayoutColm(Logic_Y, Logic_X):Integer Layout_Colm 論理(ロジック)、レイアウト座標変換 引数がいずれかが0以下なら、エラーにする ・GetLayoutWidth(beginColm:Integer, str):Integer Layout_Colmの親戚 サクラ的に表示の横幅をいくつと見るか調べる 改行コードを含んでいる場合の動作は未定義 beginColm 文字列の先頭のレイアウト桁。1で行頭 この値で、タブの計算幅が変化する 0以下が指定された場合は、エラーにしておく 戻り値 現在のタブ幅・フォント設定でTAB幅/文字幅を考慮する 合成文字の扱いは実装依存 <削除 r2>TABは行内の位置で変わるので、TAB=1 ■(仮)クリップボード種類別 文字コード変換やバイナリが絡むと、PPAとかどうしたらいいかわからないので保留 ・ClearClipBorad(void):Integer クリップボードを空にする。AddClipBoradStringByFormat前に呼ぶ必要がある EmptyClipBoradのほうがいい? ・RegistorClipBoradFormat(formatName:String):Integer clipFormat クリップボードの種類を登録する 使いそうなフォーマット "SAKURAClip", "SAKURAClipW", "MSDEVColumnSelect", 矩形選択マーク "MSDEVLineSelect", 行選択マーク "HTML format", "Rich Text Format", "Rich Text Format Without Objects" ・IsClipboardFormatAvailable(clipFormat:Integer):Integer BOOL クリップボードの指定のタイプがあるか調べる。win32直通 clipFormat例: 1:CF_TEXT 7:CF_OEMTEXT 13:CF_UNICODETEXT 16:CF_LOCALE 129:CF_DSPTEXT ・GetPriorityClipboardFormat(clipFormatArr:String):Integer 無くても何とかなるので不要かも clipFormatArr かっこ悪いけど、10進数字を,で区切って指定 戻り値 -1:指定したフォーマットが全部使えなかった 0:クリップボードが空 ・AddClipBoradStringByFormat(clipFormat:Integer, convOpt:Integer, data:String):Integer クリップボードに文字列を追加設定。 戻り値未定 ・GetClipBoradStringByFormat(clipFormat:Integer, convOpt:Integer, convOpt2:Integer):String クリップボードから文字列を取得 戻り値:"" エラーか中身が""だったかかは判別不能 convOpt 詳細未定 文字コード変換:Shift_JIS,EUC,SJIS,UTF-16LE,UTF-8(N),BINHEX 長さ処理指令(Get時):CStrLen(NUL終端まで),GlobalSize,User指定...と思ったが、 サクラのstrはNULを含んだ文字を使えないのでした→BINHEXならOK convOpt2 詳細未定 取得する長さがUser指定のときのバイト数用 sakuraClipで4バイト読み出しに必要 ■(仮)現在のタイプ別設定を取得 IsCurTypeExt/IsSameTypeExtで十分かな タイプ別設定から各設定は取得できないが、それはsakura.iniから頑張ってもらう ・GetCurTypeId(void):Integer 番号。一番上の共通が0 ・GetDocTypeName(id):String タイプ名 ・GetDocTypeExts(id):String 拡張子一覧たぶん,区切り ■(仮)Redoバッファ管理 ・まとめる機能がほしい サクラ側の新機能になるのでやらないかも。 ・Officeの履歴表示みたいに、それぞれの処理内容が分かる名称もつけられるといい 階層にはしない。 Begin後にBeginを追加したら数える。EndがBeginと同じになったら閉じる strTitleは画面表示用であり、階層管理用ではない BeginRedoPack(strTitle):Integer BOOL EndRedoPack(void):Integer BOOL ■(仮)ファイル読み書き 文字コード変換、改行変換、BOM対応のエディタの読み書き互換関数 クラスにしないとまずそうだが拡張が面倒 ・読込クラスはあるのでたぶん使える ・サクラの保存と同じオプションが使える高レベル書き込みクラスがない ■履歴 rev 2 匿名さんの指摘を元に見直し。感謝。 →論理座標系 Phy..になってたものをLogicに変更(そもそも意味が反対だ) (仮)でないもの 以下の(仮)でないものの引数変更 X,Yと書いてあると普通に見えるが「列,行」なので不自然だった MoveCursorTo(X, Y)→(Y, X) MoveCursorLayoutTo(X, Y)→(Y, X) DirectoryDialog(dir)→DirectoryDialog(msg,dir) GetClipBorad()→(nOpt) SetClipBorad(str)→(nOpt,str) 名称変更 MessageBox→MsgBox QuesionMessageBox→ConfirmMsgBox 戻り値など足りない定義を追加 細かい動作・説明を追記 (仮)類 いくつか変更。追加、名称変更など GetLayoutWidthでTab考慮のほうが便利なので仕様変更