last updated:2024/04/20

Hidemaru Q and A

第III部〜秀丸マクロのいろはにほへと
 JavaScript対応


JavaScript対応

はじめに

Ver.9.19以降、マクロファイル内にある js{ } 記述内は JavaScript で記述することが可能になりました。 execjs文で別ファイルの JavaScript も実行できます。

JavaScript 実行時には、HidemaruGlobal オブジェクト、Hidemaru オブジェクト が常にグローバルに存在します。秀丸マクロ命令の実行や秀丸エディタの機能を使うには、この2つのオブジェクトを利用します。

  • HidemaruGlobalオブジェクトは、秀丸マクロの文/キーワード/関数と同名のメソッドがあります。 jsmode文により、グローバル展開をON/OFFできる。
  • Hidemaruオブジェクトは、秀丸エディタ本体関連機能がメソッドとして呼び出せます。 JavaScript と 秀丸マクロ 間で変数をやり取りする場合は、Hidemaruオブジェクトを使います。

他にも使用できるオブジェクトがあるのでマクロヘルプの JavaScript対応オブジェクト を参照してください。

その他 に注意点などが書いてあるので、よく読みましょう。

JavaScriptでなにができるのか

JavaScript は汎用プログラム言語です。各種ライブラリも利用できます。

JavaScriptの使い方としては以下の方法があります。どちらの方法がいいかはマクロによるのでいろいろ試してみましょう。

JavaScript実行環境

JavaScriptの実行環境としては以下の3つを指定可能です。

jsmode文のパラメータ1で文字列として指定します。

  • JScript(デフォルト)

    WSHベースのエンジンで秀丸エディタを実行できる環境なら標準搭載されています。

    対応規格は古い(ECMA-262 3rd edition(December 1999))。

    JScriptの資料はJScript and VBScript Microsoft Learnを参照。

  • Chakra

    IEベースのエンジン。

    対応規格は古い(ECMA-262 5.1 edition(December 2009))。

  • WebView2

    Chromium版 Microsoft Edge相当。 Windows10、11以外の場合は、MicrosoftのサイトからWebView2ランタイムをインストールする必要があります。 (Windows 7、8、8.1 をサポートしているのは、WebView2ランタイム バージョン 109 が最終になります)

    JavaScriptの資料はJavaScript MDNを参照。

新しい JavaScript を使いたい場合は「WebView2」を使うしかありませんが、実行環境としては Windows 10、11 が主なターゲットになります。どの Windows 環境でも動かそうとする場合、現状では「JScript」を使うことになります。

JavaScriptから秀丸マクロの文/キーワード/関数の呼び出し方法

秀丸マクロの文/キーワード/関数は、HidemaruGlobalオブジェクトのメソッドとして呼び出すことができます。

  • 一部例外はあるが 文/キーワード/関数 をそのままのメソッドとして使用できる。
    詳細は HidemaruGlobalオブジェクトのメソッドを参照。
  • メソッドとして呼び出す為、全て関数の書き方(メソッドの書き方)になる。(要は括弧を付けて呼び出す)
マクロの例
//filename2キーワードとmessage文の呼び出し
js {
    //HidemaruGlobalオブジェクト の名前は「hidemaruGlobal」
    a = hidemaruGlobal.filename2();
    hidemaruGlobal.message(a);
}

「hidemaruGlobal」のメソッドとして呼び出す為、hidemaruGlobal.filename2(); としていますが、「hidemaruGlobal.」は省略できます。 (通常はHidemaruGlobalのメソッドがグローバルに展開されている)

//filename2キーワードとmessage文の呼び出し
js {
    //HidemaruGlobalオブジェクトを省略
    a = filename2();
    message(a);
}

jsmode文を使うことで、明示的にグローバル展開を無効にしたり有効にしたりできます。

制限事項

秀丸エディタの切り替え

js{ }の実行中は、他の秀丸エディタへの切り替えができません。

従来のマクロでは、アクティブな秀丸ディタが切り替われば、マクロ実行する秀丸ディタも切り替わっていましたが、 js{ }内では切り替わりません。

  • 従来のマクロ

    debuginfo 1;
    openfile "a.txt";
    debuginfo sprintf("basename=%s\n",basename);
    openfile "b.txt";
    debuginfo sprintf("basename=%s\n",basename);
    endmacro;

    実行結果

    basename=a.txt
    basename=b.txt

    ファイルを開くと、アクティブな秀丸ディタも切り替わるので、マクロの実行も切り替わっている。 (basename が切り替わっている)

  • jsの場合

    debuginfo 1;
    openfile "a.txt";
    debuginfo sprintf("js:basename=%s\n",basename);
    js{
        openfile("b.txt");
        debuginfo(sprintf("js:basename=%s\n", basename()));
    }
    endmacro;

    実行結果

    js:basename=a.txt
    js:basename=a.txt

    ファイルを開くと、アクティブな秀丸ディタは切り替わるが、マクロの実行は切り替わっていない。 (basename が変わっていない)

数値のやり取り

数値を JavaScript と 秀丸マクロ 間でやり取りする場合は、64bit版でも、32bitまでという制限あり。

(hidemaruオブジェクトの)getVar/setVarによる JavaScript - 秀丸マクロ間の数値型変数とのやりとりは、32bitの数値として扱われる。

32bitの数値の上限は 2147483647、下限は -2147483648
  • サンプルマクロ

    debuginfo 2;
    #a = 0x123456789;
    debuginfo(sprintf("macro:#a=0x%llx\n", #a));
    js{
        var jsval1 = hidemaru.getVar("#a");
        hidemaruGlobal.debuginfo(hidemaruGlobal.sprintf("js{} :#a=0x%llx\n", jsval1));
        var jsval2 = 0x123456789;
        hidemaruGlobal.debuginfo(hidemaruGlobal.sprintf("js{} :#b=0x%llx\n", jsval2));
        hidemaru.setVar("#b", jsval2);
    }
    debuginfo(sprintf("macro:#b=0x%llx\n", #b));
    endmacro;
  • 実行結果

    macro:#a=0x123456789
    js{} :#a=0x23456789
    js{} :#b=0x123456789
    macro:#b=0x0
    • 32bit 以上の値を 秀丸マクロ → JavaScript の場合は、32bit で切り捨てられた値が JavaScript へ送られる。
    • 32bit 以上の値を JavaScript → 秀丸マクロ の場合は、0 が 秀丸マクロ へ送られる。

「非同期」とは

現時点では秀丸マクロが実行中かどうかという意味合い。

同期
秀丸マクロ実行中。
非同期
秀丸マクロが実行されていない状態。

非同期の状態では、秀丸マクロ実行中ではないので使用できるオブジェクトに制限があります。

  • hidemaruオブジェクトの幾つかのメソッド・プロパティは、非同期でも使用可能。
  • hidemaruGlobalオブジェクトは、基本的には非同期で使うことはできない。非同期で使うことができるものには、説明文の最初に[非同期]と記載されている。

秀丸マクロを制限なく使いたい場合は、hidemaru.postExecMacroFile や hidemaru.postExecMacroMemory でマクロを実行する方法もあります。

「非同期」のサンプルマクロ変更版

マクロ本体

//ファイル名:test_js.mac
hidemaruversion "9.22.14";
//アウトプット枠に出力
debuginfo 2;
debuginfo sprintf("%d:%s start\n", tickcount, currentmacrobasename);
js{
    //非同期で呼ばれる関数(秀丸マクロ実行中には呼び出されない)
    function checkInterval(){
        console.log(tickcount() + ":[非同期] Call checkInterval() idInterval=" + idInterval  + "\n");
        hidemaru.clearInterval(idInterval);
    }
    
    //秀丸マクロ実行中に実行される内容
    var idInterval;
    idInterval = hidemaru.setInterval(checkInterval,1000);
    console.log(tickcount() + ":[同期] idInterval=" + idInterval + "\n");
}
debuginfo sprintf("%d:%s end\n", tickcount, currentmacrobasename);
endmacro;

実行結果

22375343:test_js.mac start                               ←マクロ開始
22375406:[同期] idInterval=23414                         遅延時間と呼び出される関数を指定
22375406:test_js.mac end                                 ←マクロ終了
22376406:[非同期] Call checkInterval() idInterval=23414  ← setIntervalで指定した時間後に checkInterval関数が実行されている。

実行結果を見ればわかりますが、checkInterval 関数はマクロ実行時には呼び出されず、マクロが終了してから setInterval で指定した時間経過後に呼び出されています。

JavaScript は明示的にリセットしなければ、同じスクリプトエンジン・同じ名前空間のオブジェクトはウィンドウを閉じるまで保持されます。この性質を利用しローバルスコープで変数を宣言すれば、どのタイミングでも変数にアクセス可能です。

なので、マクロを終了しても

idInterval = hidemaru.setInterval(checkInterval,1000);

idInterval の内容は保持されていので、checkInterval 関数内の

hidemaru.clearInterval(idInterval);

で、タイマーを止めることができます。


ページトップ 目次に戻る