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考慮のほうが便利なので仕様変更