操作の繰り返し

提供: MeryWiki
ナビゲーションに移動 検索に移動

概要[編集]

指定した回数だけ操作を繰り返すマクロです。Emacs のC-u(universal-argument) に近い動作をします。

動作環境[編集]

  • Mery Ver 3.7.18 以降

使用方法[編集]

  1. マクロを実行します。
  2. ステータス バーに [繰り返し回数] が表示され、入力待ち状態になります。
  3. 繰り返したい回数を数値で入力します。
  4. 続けて実行するコマンドを入力します。
(利用可能なコマンドはマクロのソースコードを参照してください)

補足事項[編集]

  • 入力待ちの状態でEscキーを押すとキャンセルできます。
  • actionsにコマンドを追加することで機能を拡張できます。
  • C-Ctrlキー、M-Altキーを表します。

使用例[編集]

マクロを実行 → 10Ctrl+Y と入力すると、クリップボードの内容を 10 回貼り付けます。

ソースコード (RepeatAction.js)[編集]

#title = "操作の繰り返し"
#async = true

const actions = {
	// 左へ移動
	"C-b": "document.selection.CharLeft(false, %d)",
	// 右へ移動
	"C-f": "document.selection.CharRight(false, %d)",
	// 上へ移動
	"C-p": "document.selection.LineUp(false, %d)",
	// 下へ移動
	"C-n": "document.selection.LineDown(false, %d)",
	// 上にスクロール
	"C-v": "document.ScrollY -= %d;",
	// 下にスクロール
	"v": "document.ScrollY += %d;",
	// 貼り付け
	"C-y": "document.selection.Paste();",
	// 削除
	"C-d": "document.selection.Delete(%d);",
	// 改行
	"C-j": "document.selection.NewLine(%d);",
	// 改行 (カーソル位置を維持)
	"C-o": "let p = document.selection.GetActivePos(); document.selection.NewLine(%d); document.selection.SetActivePos(p);",
	// 置換
	"r": "",
	// 置換 (正規表現)
	"x": "",
	// 挿入
	"i": "",
	// 単語を選択
	"w": "document.selection.SelectWord();",
};

const s = status;
function main() {
	status = "繰り返し回数: ";
	let repeat = 0;
	let pressed = {};
	let command = "";
	const d = Date.now();
	while (Date.now() - d < 10000) {
		// Esc
		if ((shell.GetKeyState(0x1B) & 0x8000) !== 0) {
			return false;
		}
		// 0 .. 9
		for (let k = 0x30; k <= 0x39; k++) {
			const press = (shell.GetKeyState(k) & 0x8000) !== 0;
			if (press && !pressed[k]) {
				pressed[k] = true;
				const digit = k - 0x30;
				repeat = repeat * 10 + digit;
				status += digit.toString();
			}
			if (!press && pressed[k]) {
				pressed[k] = false;
			}
		}
		// A .. Z
	    for (let k = 0x41; k <= 0x5A; k++) {
	        if ((shell.GetKeyState(k) & 0x8000) !== 0) {
	           	command = ((shell.GetKeyState(0x11) & 0x8000) !== 0 ? "C-" : "") + ((shell.GetKeyState(0x12) & 0x8000) !== 0 ? "M-" : "") + String.fromCharCode(k).toLowerCase();
	            break;
	        }
	    }
	    if (command !== "")
	    	break;
	    Sleep(20);
	}
	if (repeat === 0) {
		repeat = 1;
	}
	Sleep(300);
	if ((command === "r") || (command === "x")) {
		const t = prompt("検索する文字列:", "");
		const u = prompt("置換後の文字列:", "");
		if (t && u !== null) {
			Redraw = false;
			BeginUndoGroup();
			for (var i = 0; i < repeat; i++) {
				document.selection.Replace(t, u, meFindNext | (command === "x" ? meFindReplaceRegExp : 0));
			}
			document.selection.Collapse(meCollapseEnd);
			EndUndoGroup();
			Redraw = true;
			return true;
		}
	} else if (command === "i") {
		const t = prompt("挿入する文字列:", "");
		if (t) {
			Redraw = false;
			BeginUndoGroup();
			for (var i = 0; i < repeat; i++) {
				document.selection.Text = t;
			}
			EndUndoGroup();
			Redraw = true;
		}
	} else if (command !== "" && actions.hasOwnProperty(command)) {
		Redraw = false;
		BeginUndoGroup();
	    const action = actions[command];
    	if (/%d/.test(action)) {
    		editor.executeMacro(action.replace(/%d/g, repeat), meRunText | meMacroLangJScript);
    	} else {
			for (var i = 0; i < repeat; i++) {
				editor.executeMacro(action, meRunText | meMacroLangJScript);
			}
    	}
		EndUndoGroup();
		Redraw = true;
	}
	return false;
}
if (!main()) {
	status = s;
}
スポンサーリンク