マクロのイベント駆動「編集モードが変更された時」のタイミング

  1. マクロをイベントで実行するケースで「編集モードが変更された時」を指定していると意図しないタイミングでマクロが実行されるようなので報告します。

    具体的には以下のタイミングで実行されるのを確認しました。

    1. ファイルを開く
    2. 新規作成
    3. 名前を付けて保存
    4. オプションを OK ボタンで閉じる
    5. マクロでeditor.ReadSettings()メソッドを使用(「編集モードが変更された時」を指定しているマクロで使うと場合によっては無限ループします)

    Mery: 3.8.2 (x64)
    OS: Windows 11 (Version 25H2, OS Build 26200.7628, 64-bit Edition)

     |  ucky  |  返信
  2. ご報告ありがとうございます。

    マクロイベントの [編集モードが変更された時] は、編集モードが変更された場合だけでなく、Mery の一部の設定が変更されたタイミングや、その他の特定のタイミングでも実行される仕様としています。

    これは、編集モードの変更時や、フォントサイズ、色の反転などの設定変更時を含め、「全体的に設定が大きく変わった」と考えられるタイミングや、イベントを設定したいであろう場面を想定したものです。

    なお、具体的にどのタイミングで発生するかといった詳細な仕様については、現時点ではマニュアルとしては用意していません。

    発生タイミングについても、私個人が必要だと判断した箇所に設定している状況ですので、ベータ検証の中で「必要/不要」といったご意見をいただければ、変更や調整は可能です。(ただし、プラグインイベントとも共通なので、減らすのは問題ありそうですが…)

     |  Kuro  |  返信
  3. ご確認ありがとうございます。

    仕様ということで承知しました。失礼しました。

    > 発生タイミングについても、私個人が必要だと判断した箇所に設定している状況ですので、ベータ検証の中で「必要/不要」といったご意見をいただければ、変更や調整は可能です。(ただし、プラグインイベントとも共通なので、減らすのは問題ありそうですが…)

    フォーラムの別の投稿ででてた「背景画像を切り替えるマクロを[編集モードが変更された時] のイベントで設定」といったケースでは都合が悪そうだと思いました。

    例えば背景画像を切り替えるマクロが以下のような場合、一度の編集モードの変更で 2 回実行されます。また、背景画像の切り替えが必要かどうかを判定しているifをなくすと無限ループしてしまいます。

    #language = "quickjs"
    
    const graphicSettings = {
    	"COBOL": {
    		path: "C:\\Users\\UserName\\Pictures\\cobol.png",
    	},
    };
    const editMode = document.Mode;
    const graphicPath = graphicSettings[editMode]?.path || "";
    if (editor.ReadSettingString("Display", "GraphicPath", "") !== graphicPath) {
    	editor.WriteSettings();
    	editor.WriteSettingString("Display", "GraphicPath", graphicPath);
    	editor.ReadSettings(); // ここで[編集モードが変更された時] イベント発生
    }
    

    減らすのは問題ありそうとのことなので気を付けて活用させていただこうと思います。

     |  ucky  |  返信
  4. ご返信ありがとうございます。

    > フォーラムの別の投稿ででてた「背景画像を切り替えるマクロを[編集モードが変更された時] のイベントで設定」といったケースでは都合が悪そうだと思いました。

    なるほど。確かに、そのようなケースでは工夫が必要になりそうですね。

    念のため調査したところ、[編集モードが変更された時] イベントが呼ばれるタイミングは、主に以下のとおりでした。

    • 表示 > 編集モード > 編集モードの設定
    • 表示 > 色の反転
    • 表示 > フォント > フォントの一覧
    • 表示 > フォント > 大きいフォントサイズ
    • 表示 > フォント > 小さいフォントサイズ
    • 表示 > フォント > フォントサイズをリセット
    • 表示 > フォント > フォントの設定
    • 表示 > 編集モード
    • オプション更新
    • 編集モード設定 (内部的に使用)
    • 名前から編集モード設定 (内部的に使用、ファイルを開く/読み直し)
    • ファイル名から編集モード設定 (内部的に使用、ファイルを開く/名前を付けて保存/読み直し)

    おそらく、EmEditor さんのマクロイベントでいう [設定が変更された時] に近い用途を想定して実装したのだと思います。

    EmEditor さんでは「設定」という単位が、Mery でいうところの「編集モード」に概ね相当するため、[設定が変更された時] というイベント名で、さまざまなタイミングで呼ばれても違和感が少ないのでしょうね。

    > 例えば背景画像を切り替えるマクロが以下のような場合、一度の編集モードの変更で 2 回実行されます。また、背景画像の切り替えが必要かどうかを判定しているifをなくすと無限ループしてしまいます。

    無限ループについては、たとえば [テキストが変更された時] イベントなどでも同様で、そのイベント内でテキストを変更するようなマクロを設定すると、同じく無限ループが発生します。

    これはイベント駆動の仕組み上、一般的に起こり得る挙動であり、イベントを利用する際には、フラグを立てる、条件チェックを行うなどして、意図しない再実行や無限ループを避ける工夫をユーザー側で行っていただく必要がありますね。

     |  Kuro  |  返信
  5. 詳しいご説明ありがとうございます。

    イベント駆動を使用する際は工夫して使おうと思います。

     |  ucky  |  返信
スポンサーリンク