範囲選択の開始と終了を実現するマクロ

  1. Kuroさん、初めまして。ここ2か月ほどWordで文書を書いていたのですが、時折動作がもたつく点が気になっていたら知り合いからエディタを勧められまして、先日ネットを検索し、Meryに出会いました。(キー割り当てが変えられるので、便利に使わせていただいております。感謝申し上げます!)

    さて、質問です。選択範囲の開始と終了をマクロで実現することは可能でしょうか?
    (もっぱら文章を書くことにMeryを使っているので、コードの知識が無く、素人質問で申し訳ございません。)

    マクロのキー割り当ては「Ctrl + I」という設定でイメージをお伝えします。

    1.文章の選択を開始したい文字の左側にカーソルがある状態で Ctrl + I
    2.選択したい範囲の終わりまでカーソル移動
    3.選択したい範囲の最後の文字の右側にカーソルがある状態で Ctrl + I
    4.以上の操作で、範囲が選択状態になる
    5.「選択範囲に対する動作」により、選択解除

    5の「選択範囲に対する動作」とは、たとえば、
    カーソル位置はそのままで、Ctrl + C により選択範囲をコピー AND 選択解除
    とか
    カーソル位置はそのままで、Ctrl + X により選択範囲を切取り AND 選択解除
    とかを想定しています。

    わがままを申しますと、マウスで範囲選択した場合と同様に、選択範囲の背景色が変わると有難いです。

    お忙しいところ恐縮ですが、ご回答いただけましたら幸いですm(_ _)m。

    (備考)
    キーアサイン集のページを拝見したところ、カーソル移動のコードにおいて「false」を「true」にすれば範囲選択も兼ねることは理解できたものの、ひたすらCharRightで選択範囲の終わりまで移動するのも厳しいなと思い、今回の質問をさせていただきました。

     |  くま  |  返信
  2. 初めまして。Mery をお試しいただきありがとうございます。

    > さて、質問です。選択範囲の開始と終了をマクロで実現することは可能でしょうか?

    マクロを使えば可能です。色々な方法があると思いますが、とりあえず思い浮かんだマクロはこんな感じです。

    var a = status.split(":")
    if (a.length > 1 && a[0] == "選択開始" && !isNaN(a[1])) {
    	document.selection.SetActivePos(a[1], true);
    	status = "";
    } else {
    	status = "選択開始:" + document.selection.GetActivePos();
    }
    

    これを Ctrl + I に割り当てておけば、Ctrl + I を押すたびに選択開始、選択終了が切り替わる感じになると思います。(もっと美しいマクロもあるかと思いますが、とりあえず…)

    > 5.「選択範囲に対する動作」により、選択解除

    コピーしたときに選択解除などは MeryWiki のマクロライブラリの「キーアサイン集」にご希望の操作を実現できるものがあったと思います。

     |  Kuro  |  返信
  3. 横から失礼します

    マクロでも 1~5 の内容はおおよそ実現できるとおもいますが、「わがまま」の要求内容 ――範囲選択の確定前のカーソル移動中に「動的に選択範囲をハイライト」させること―― は実現できません。
    1~5 の部分だけを実現させるばあいでも、マクロライブラリにある「includeライブラリ」を導入していただいたうえで(← コードを書く側が楽をする目的で)、マクロのソースコードファイル(js)とは別に動作モード(範囲選択モード ON/OFF の状態)を書き出すための設定ファイルも必要となります(← これについては、マクロ側が勝手に設定ファイルを作成/参照するようにできますが)。

    また、マクロだと「さいしょの実行 (Ctrl+I) で範囲選択モードにしてから選択範囲を確定させるために再実行 (Ctrl+I) するまえに、カーソル移動以外の操作(文字列の入力/削除/変換やタブの切り替えなど)をした場合」にマクロの範囲選択モード状態をキャンセルするような仕組みを入れづらかったりするので、あらかじめ色々な状況を想定したうえで動作仕様を決めないとかえって使いづらくなってしまうかもしれません。

    もし私が作るなら「【include 版】位置を復帰/保存」マクロをベースに改造して、設定項目をいくつも用意するとかになるので、いつもながらの使い勝手にクセがあるマクロになっちゃいそうです。 :|

    個人的には、AHK のような外部ソフトで「Shiftキーの押しっぱなし状態 ON/OFF」のようなプロファイルを作り、カーソル移動操作の前後に実行するほうが現実的な気がします。
    ただし、このばあいは 5 の選択範囲に対する操作には別途「Ctrl+C」などを上書きするプロファイル(コピー+選択解除 を実現させるためのもの)も必要になってしまうかもしれないですが。

    あるいは、Kuro さんに Mery 本体側で「範囲選択モードの開始/終了(確定)」のような機能を盛りこんでいただくか、プラグインで実現していただく方向でご検討を… というかんじ? :)
    でも、キーボードオンリーでの操作なら Shift キー押しっぱなしでよいのでは? で終了かしら… XD

     |  sukemaru  |  返信
  4. あら、かぶってしまいましたか
    > マクロを使えば可能です。色々な方法があると思いますが、とりあえず思い浮かんだマクロはこんな感じです。
    > これを Ctrl + I に割り当てておけば、Ctrl + I を押すたびに選択開始、選択終了が切り替わる感じになると思います。(もっと美しいマクロもあるかと思いますが、とりあえず…)

    これはシンプルですね。
    うちの場合はイベントマクロの「文字数・行数・バイト数・ヒット件数」が常駐しているので、ステータスバーを『置き場』にする発想にいたることができませんでした。
    でも、やはり範囲選択モード開始から「動的に選択ハイライト」を連動させるのはマクロだと難しいですよね…。
    特殊なイベントマクロを常駐させればできそうかしら?

     |  sukemaru  |  返信
  5. > Mery をお試しいただきありがとうございます。

    こちらこそ、素晴らしいエディタを作っていただき、ありがとうございます!
    Wordよりも全然良いです! 快適に文章が書けます♪

    > これを Ctrl + I に割り当てておけば、Ctrl + Iを押すたびに選択開始、選択終了が切り替わる感じになると思います。(もっと美しいマクロもあるかと思いますが、とりあえず…)

    お忙しいところ、素早いご回答に感謝いたします。
    書いていただいたコードをファイルに保存し、Ctrl + I を試したところ、無事に選択開始・終了ができました。

    > コピーしたときに選択解除などは MeryWiki のマクロライブラリの「キーアサイン集」にご希望の操作を実現できるものがあったと思います。

    これは失礼いたしました。「キーアサイン集」を再度拝見します。

    短い文章で恐縮ですが、本当にありがとうございました。
    Kuroさんのお力添えに感謝しながら、文章を書くことに励みたいと思います。

     |  くま  |  返信
  6. >> sukemaru さん

    サポートのご協力ありがとうございます。

    > AHK のような外部ソフトで「Shiftキーの押しっぱなし状態 ON/OFF」のようなプロファイル

    確かに!それだと他のテキストエディターとかでも同じ操作ができそうですし、選択範囲もリアルタイムで反映されますね。

    > ステータスバーを『置き場』にする発想にいたることができませんでした。

    そうなんですよね、今のところグローバルな変数を保持しておくすべがないのでちょっと荒技でした。

    次のバージョンではグローバルな変数を保持できる tag プロパティが実装される予定です。

    > でも、やはり範囲選択モード開始から「動的に選択ハイライト」を連動させるのはマクロだと難しいですよね…。

    そうですね。Shift キーの押下をマクロから送信できれば、と思ったのですが無理でした…

    >> くま さん

    ありがとうございます。そう言っていただけると作った甲斐があります!

    マクロ、無事に動作したようで良かったです。現状ですとリアルタイムで選択範囲のハイライトを反映させるところまではできなくて申し訳ございません。

    > これは失礼いたしました。「キーアサイン集」を再度拝見します。

    いえいえ。キーアサイン集は細かい動作をカスタマイズできるマクロがたくさんあるので眺めているだけでも楽しいですよー

    Mery が文章書きのお力になれれば何よりです。

     |  Kuro  |  返信
  7. > マクロ、無事に動作したようで良かったです。現状ですとリアルタイムで選択範囲のハイライトを反映させるところまではできなくて申し訳ございません。

    いえいえ、この点に関しましては、Ctrl + I で範囲選択した時も 「オプション」 → 「表示」 → 「選択範囲」で設定した背景色が反映しております。

    お気遣いありがとうございます(^^)。

     |  くま  |  返信
  8. ver 3.0.0 で新機能が追加されたので
    set_blockmode.js

    if(!document.tag.exists("blockmode")){
      document.tag("blockmode")=true;
    } else {
      document.tag("blockmode")=!document.tag("blockmode");
    }
    document.tag("anchorpos")=document.selection.GetActivePos();
    

    on_cursol_move.js

    if(document.tag.exists("blockmode")){
      if(document.tag("blockmode")){document.selection.SetAnchorPos(document.tag("anchorpos"))}
    }
    

    set_blockmode.js をキーボードマクロに割り当て。on_cursol_move.js をイベント「カーソルが移動したとき」に遅延 0 秒で割り当て。
    雑に作ったけど、これは夢が広がるかも。

     |  通りすがり  |  返信
  9. 矩形ブロックをモードで実現する夢が広がったので、少しだけ真面目に書き直し
    set_block_mode.js

    //ブロックモードトグル
    var tag_pos=document.selection.GetActivePos();
    if(!document.tag.exists("blockmode")){
      document.tag("blockmode")=true;
    } else {
      if(document.tag("blockmode")){
        //範囲選択状態解除
        document.tag("blockmode")=false;
        if(!document.selection.isEmpty){document.selection.SetAnchorPos(document.selection.GetActivePos())}
      } else {
        //範囲選択状態開始
        document.tag("blockmode")=true;
        if(!document.selection.isEmpty){tag_pos=document.selection.GetAnchorPos()}
      }
      if(document.tag.exists("kukei_blockmode")){
        document.tag("kukei_blockmode")=false;
      }
    }
    document.tag("anchorpos")=tag_pos;
    

    set_kukei_block_mode.js

    //矩形ブロックモードトグル
    var tag_pos=document.selection.GetActivePos();
    if(!document.tag.exists("blockmode")){
      document.tag("blockmode")=true;
      document.tag("kukei_blockmode")=true;
    } else {
      if(!document.tag.exists("kukei_blockmode")){
        document.tag("kukei_blockmode")=false;
      }
      if(document.tag("blockmode")){
        //範囲選択状態解除
        document.tag("blockmode")=false;
        document.tag("kukei_blockmode")=false;
        if(!document.selection.isEmpty){document.selection.SetAnchorPos(document.selection.GetActivePos())}
      } else {
        //範囲選択状態開始
        document.tag("blockmode")=true;
        document.tag("kukei_blockmode")=true;
        if(!document.selection.isEmpty){tag_pos=document.selection.GetAnchorPos()}
      }
    }
    document.tag("anchorpos")=tag_pos;
    

    on_cursol_move.js

    if(document.tag.exists("blockmode")){
      if(document.tag("blockmode")){document.selection.SetAnchorPos(document.tag("anchorpos"))}
      if(document.tag.exists("kukei_blockmode")){
        if(document.tag("kukei_blockmode"))document.selection.Mode=meModeBox;
      }
    }
    

    あとは、カット、コピー、ペースト、全選択などをマクロで置き換えて document.tag("blockmode")=false;の処理を追加すればOK

     |  通りすがり  |  返信
  10. 早速、tag プロパティをお試しいただきありがとうございます。

    おおっ、リアルタイムで選択範囲を画面上に反映できてる!
    これは面白いマクロですね。

    > 「カーソルが移動したとき」に遅延 0 秒で割り当て。

    これを忘れててデフォルトの 1.0 秒で試してしまったところ、特定条件下で画面の再描画が発生せず、選択範囲の色のゴミが残る問題を発見しました。

    次のバージョンでは修正しておこうと思います。

    あと、これは仕様ですが、document オブジェクトは現在フォーカスのあるタブを参照するので、検索ダイアログなどにフォーカスがあるとエラーになってしまいますね…。

     |  Kuro  |  返信
  11. > 早速、tag プロパティをお試しいただきありがとうございます。
    tagプロパティ、強いです。ver 2.8 以前でグローバル変数もどきを使う際、無題のドキュメントでやたら苦労したのが過去のものになりそう。

    > あと、これは仕様ですが、document オブジェクトは現在フォーカスのあるタブを参照するので、検索ダイアログなどにフォーカスがあるとエラーになってしまいますね…。
    デフォルトだと検索結果で一致文字列が選択状態になる件も併せて、検索は鬼門です。
    F3、Shift + F3 にも選択範囲調整するマクロを割り当てる必要があるかもです。

     |  通りすがり  |  返信
スポンサーリンク