hmRbが持つ特別な関数一覧 その③

IronRubyから秀丸マクロへアクセスする関数

IronRubyの機能をフルに生かしつつ、秀丸マクロの機能や各種値もほぼ全て使えるところが、
hmRbが優れている所以です。

  • 秀丸マクロをそのまま実行
  • 「秀丸マクロの変数」⇔「IronRubyの変数」を相互にやり取り。

の2つの手段で秀丸マクロを取り扱うことが出来ます。

  • IronRubyから秀丸マクロを実行

    秀丸エディタ 8.66以降では、Hidemaru_EvalMacroという関数が秀丸本体からエキスポートされたため、
    マクロ実行中であれば、秀丸マクロ以外の場所からでもマクロを記述し、実行することが可能となりました。

    • 現行バージョンのバグ

      IronRubyの内部的な不具合により、$hm.Macro.Evalに最初にヒアドキュメントを渡すと、NullReferenceErrorが出ることがあります。
      これはhmRbではなく、IronRuby自体に存在する根深いバグです。
      このような、場合は、下記サンプルの

                  $hm_version = $hm.Macro.Var["version"];
                  
      のような$hm.***へとアクセスするダミーの記述を、ソースの先頭に記載しておいてください。

    • $hm.Macro.Eval( ヒアドキュメント文字列)

      引数の文字列を、「秀丸マクロ」として実行する。

    #RB = loaddll( hidemarudir + @"\hmRb.dll" );
    
    if ( !#RB ) {
        message("hmRb.dllが導入されていません");
        endmacro;
    }
    
    #_ = dllfuncw(#RB, "DoString", R"IRONRUBY(
    $version = $hm.Macro.Var["version"]; # インスタンス状態を整えるダミーの記述
    
    py_x = 100
    
    #ironrubyの中で、$hm.Macro.Eval関数を使って、秀丸のマクロを書くことが出来る
    $hm.Macro.Eval <<'MACRO'
      #a = 3;
      debuginfo 1;
      showvars;
      message("あいうえお");
    
      showvars;
    MACRO
    ;
    
    )IRONRUBY"
    );
    
    freedll( #RB );
    
  • IronRubyから秀丸マクロの変数の読み書き

    • $hm.Macro.Var["変数名"]

      対象の「秀丸マクロ」としてのシンボル名に対応する値を取得する。

    • $hm.Macro.Var["変数名"] = 新たな値

      対象の「秀丸マクロ」としてのシンボル名に、新たな値を設定する。
      (読み取り専用の値には設定出来ません)

    #RB = loaddll( hidemarudir + @"\hmRb.dll" );
    
    #_ = dllfuncw(  #RB, "DoString", R"IRONRUBY(
    
    # 秀丸マクロの「#aaa」という変数に3を設定。
    $hm.Macro.Var['#aaa'] = 3;
    
    # 秀丸マクロの「$bbb」という変数に「あいうえお」を設定。
    $hm.Macro.Var['$bbb'] = "あいうえお。"
    
    # 秀丸マクロとして一連の文字列を実行
    $hm.Macro.Eval <<'MACRO'
        message($bbb);
        $$message = $bbb + $bbb;
        message($$message);
    
        // アウトプット枠へ出力
        #OP = loaddll("HmOutputPane.dll");
        #ret = dllfunc(#OP, "Output",hidemaruhandle(0), $$message);
        freedll(#OP);
    MACRO
    ;
    
    $hm.debuginfo( $hm.Macro.Var['$bbb'] );
    $hm.debuginfo( $hm.Macro.Var['filename'] );
    
    hmdate = $hm.Macro.Var['date'];
    $hm.debuginfo( hmdate );
    
    )IRONRUBY"
    );
    
    freedll( #RB );
            

    上記の例はさほど意味がある例題ではありませんが、 実践では「フォーム系」を使ったIronRuby層で、
    「フォームを閉じることなく、イベントハンドラに呼応する形で(フォームを閉じることなく)秀丸を制御したい場合」などに威力を発揮することでしょう。
    又、ループを伴った値の伝達なども、秀丸マクロ層でやるよりも、IronRuby層でやった方が記述が簡潔に済みます。

    #RB = loaddll( hidemarudir + @"\hmRb.dll" );
    
    #_ = dllfuncw(  #RB, "DoString", R"IRONRUBY(
    require 'mscorlib'
    require "System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    require "System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
    
    include System::Windows::Forms
    include System::Drawing
    
    $result_from_ruby = $hm.Macro.Var['date']; # 秀丸マクロの「date」シンボルの文字列
    
    class IronRubyForm < Form
    
      def initialize()
        self.Text = 'こんにちわ'
        self.Size = Size.new(400, 200)
        @btn = Button.new
        @btn.Location = Point.new(16, 16)
        @btn.Width = 200
        @btn.Text = "クリック"
        @btn.Click { |sender, e| self.btn_Click(sender, e) }
    
        @count = 0;
    
        self.Controls.Add(@btn)
      end
    
      def btn_Click(sender, e)
        @count += 1;
          $hm.Macro.Var['$count'] = @count.to_s
          MessageBox.Show( "今開いているファイルは…\n" + $hm.Macro.Var['filename2'] );
    
          $hm.Macro.Eval <<-'MACRO'
            // アウトプット枠へ出力
            #OP = loaddll("HmOutputPane.dll");
            #ret = dllfunc(#OP, "Output",hidemaruhandle(0), $count);
            freedll(#OP);
          MACRO
      end
    
    end
    
    
    f = IronRubyForm.new
    f.ShowDialog
    
    )IRONRUBY"
    );
    
    freedll( #RB );