タブを閉じる系コマンドのショートカット対応

  1. Kuro さん

    開発お疲れさまです。
    おかげさまで v2.7.4、快適に動作しています。相変わらず使っていて気持ちがいいです。

    少し要望を挙げさせてください。

    以下のタブを右クリックして選べるコマンドですが、ショートカットキー登録にさせられるように出来ないでしょうか?

    ・他のタブをすべて閉じる
    ・左のタブをすべて閉じる
    ・右のタブをすべて閉じる

    ご検討いただければ嬉しいです。

     |  yuko  |  返信
  2. 横から失礼します。
    > おかげさまで v2.7.4、快適に動作しています。相変わらず使っていて気持ちがいいです。
    はげしく同意です。 :D

    > ・他のタブをすべて閉じる
    > ・左のタブをすべて閉じる
    > ・右のタブをすべて閉じる
    をマクロにしてみました。よろしければ動作確認をしたうえでご利用ください。
    https://www.haijin-boys.com/wiki/すべて閉じる
    (既存のページに追加しました。アイコンはいつもの「マテリアルデザインっぽい」やつです)

     |  sukemaru  |  返信
  3. >> yuko さん
    > おかげさまで v2.7.4、快適に動作しています。相変わらず使っていて気持ちがいいです。
    ありがとうございます。
    スクロールバーマーカーは動作速度の点でまだ問題がありますが、そう言っていただけると救われます。

    > 以下のタブを右クリックして選べるコマンドですが、ショートカットキー登録にさせられるように出来ないでしょうか?
    タブを右クリックして表示されるメニューの部分は、現状では大人の事情で他のメニューの機能とは仕様が異なるため、ショートカットキー割り当てができないんです。

    >> sukemaru さん
    ご協力ありがとうございます。

    おー、もうマクロできてる!すごっ。

    > ・他のタブをすべて閉じる
    > ・左のタブをすべて閉じる
    > ・右のタブをすべて閉じる

    うーん、標準機能でショートカットキー必要でしょうかね…。ご要望が多ければ検討してみたいと思います。

     |  Kuro  |  返信
  4. > sukemaru さん

    なるほど、こうすれば実現できるわけですかー。
    タメになります。
    是非、利用させていただきます!

    > Kuro さん

    sukemaru さんのマクロがありますので、喫緊の必要性は無くなりましたが、他の方からも要望が上がるなら実装を期待したいところですねー。

    というのも、ワークスペース機能で無題のテキストも終了時に消えないようになりましたので、溜まってしまった一時メモを Mery 終了で一気に消すのではなく、他のタブを閉じる系の操作でザクッと消す機会が多くなったため、キーボードからも操作できたらなぁ…と思った次第です。

     |  yuko  |  返信
  5. >> yuko さん
    > なるほど、こうすれば実現できるわけですかー。
    実のところ「ほか/左/右」の3つそれぞれ用にきちんと切り分ければ、もっと簡潔になるはずとおもうのですが、あまり自信がなくて…。複数のタブを順々に閉じていくということで、ループ処理中に Editor.Documents コレクションの数が変動しつづけるという状況も初めてでしたから、投稿した「ほかのタブを閉じる」系マクロはエラー(あるいは無限ループ地獄?)にならないための保険をかけまくりなんです。

    「左」や「右」のコードも「ほかのタブをすべて閉じる」とおなじ程度の最小限(?)に切りつめられるようでして、この2日間、当方でテストしている範囲では、以下の while 文のコードでも問題なさそうです。Editor.Documents を「var ds = Editor.Documents;」のような変数に置き換えられる部分と置き換えられない部分があって、なんだかややこしいですが…。

    // 左側のタブをすべて閉じる
    var d = Document;
    while ( Editor.Documents.Item( 0 ) != d ) {
      Editor.Documents.Item( 0 ).Close();
    }
    d.Activate();
    
    // 右側のタブをすべて閉じる
    var d = Document;
    var ds = Editor.Documents
    while ( ds.Item( Editor.Documents.Count - 1 ) != d ) {
      ds.Item( Editor.Documents.Count - 1 ).Close();
    }
    d.Activate();
    
    // または
    // 右側のタブをすべて閉じる
    var d = Document;
    var ds = Editor.Documents
    for ( var i = ds.Count - 1; ds.Item( i ) != d; i -- ) {
      ds.Item( i ).Close();
    }
    d.Activate();

    「document.Activate();」をさいごに付け足しておくと、ループ処理中に保存の確認ダイアログが出てそれを「キャンセル」した場合でも、マクロ終了後に元のタブをアクティブにできるようです。
    もうしばらく様子をみて確実に「問題ない」と判断できてからか、あるいは Kuro さんか他の先達の方から「問題ない」とお墨付きをいただけるなら、マクロライブラリのほうもこちらの簡潔なコードに差し替えたいです。

    >> Kuro さん
    > おー、もうマクロできてる!
    はじめにすべて「var ds = editor.documents;」の「ds」で書いて動かそうとしたらタブひとつしか閉じられなかったり、いろいろアレンジしている最中にエラーが出たりしたので、マクロライブラリに投稿したような「冗長だけど安全なコード」(笑)になった次第でして、Editor.Documents コレクションの扱い方として上の「簡潔版」のコードで問題ないか教えていただきたいのですが、いかがでしょうか?

     |  sukamaru  |  返信
  6. 右や左のタブをまとめて閉じるテストをしていたら「最後に閉じたタブ」を開きなおす機能がないことに気がついて、また余計なマクロを作ってしまいました。
    さすがに「すべて閉じる」系マクロに統合するのはアレなので、「ファイルを読み直す・開きなおす」マクロに組み込みんでみました。別途で組み込み・スタンドアローン用のコード(長いですが)も投稿しましたので、よろしければ。

    「左/右側のタブを閉じる」は簡潔バージョンで問題なさそうですが…。

     |  sukemaru  |  返信
  7. >> yuko さん
    >> sukemaru さん
    ご返信ありがとうございます。

    > ワークスペース機能で無題のテキストも終了時に消えないようになりましたので、溜まってしまった一時メモを Mery 終了で一気に消すのではなく、他のタブを閉じる系の操作でザクッと消す機会が多くなったため、キーボードからも操作できたらなぁ…と思った次第です。
    そういうことでしたか。確かに、ワークスペース機能を使っているとついつい無題のタブや閉じ忘れているファイルがたまってきちゃうので、 [他のタブをすべて閉じる] の出番は以前よりも増えた気がします。

    私はマウス派なので気づきませんでしたが、キーボード派のかた向けに [他のタブをすべて閉じる] へのショートカットキー割り当てはできたほうが良さそうですね。

    sukemaru さんがマクロを作ってくれたところなので心苦しいのですが、標準機能として実装する方向で検討してみようと思います。

     |  Kuro  |  返信
  8. Kuro さん

    標準機能としての実装とのこと、ありがとうございます!
    今しばらくは sukemaru さんマクロを活用させていただきつつ、実装を楽しみにしております。

     |  yuko  |  返信
  9. > sukemaru さん

    再考していただいたマクロ、ありがとうございました。
    お手間を掛けて作っていただきましたので、使用後のご報告です。

    以下のうち、 while 版の方はちょっとしたバグがありました。
    閉じようとするタブでの「変更を保存しますか?」のダイアログでキャンセルすると、Editor.Documents.Count の値が変わらないために無限ループします。

    for 版の方は特に問題なさそうです。

    // 右側のタブをすべて閉じる
    var d = Document;
    var ds = Editor.Documents
    while ( ds.Item( Editor.Documents.Count - 1 ) != d ) {
      ds.Item( Editor.Documents.Count - 1 ).Close();
    }
    d.Activate();
    // または
    // 右側のタブをすべて閉じる
    var d = Document;
    var ds = Editor.Documents
    for ( var i = ds.Count - 1; ds.Item( i ) != d; i -- ) {
      ds.Item( i ).Close();
    }
    d.Activate();
     |  yuko  |  返信
  10. 動作検証していただき、ありがとうございます。 :)

    「キャンセル」でループする罠は、私も一昨日はまりました…。 :|
    「『左/右側をすべて閉じる』んなら途中で『キャンセル』するなよ!」と自分にツッコミを入れつつ、後ろ(右側)から順に Item( i ) をデクリメントしながらあたらないとダメなことを、ようやく理解した次第です。

    マクロライブラリ版はきちんと動作しますし、無理してループ処理の回数を削る意味はないのですが、悔しいのであらためて「左側でも1ループ」のコードを考えました。
    ループを2回まわすマクロライブラリのコードとくらべても、あまり長さが変わらないから、単なる自己満足…。 :D

    // 左側のタブをすべて閉じる
    var d = document;
    var dCount = editor.Documents.Count;
    var docu, hit;
    for ( var i = dCount - 1; i >= 0; i -- ) {
      docu = editor.Documents.Item( i );
      if ( docu == d ) { hit = 1; continue; }
      if ( ! hit ) { continue; }
      docu.Close();
    }
    d.Activate();

    右側用のコードも yuko さんのご指摘どおりなのですが、最終稿として。

    // 右側のタブをすべて閉じる
    var d = document;
    var dCount = editor.Documents.Count;
    for ( var i = dCount - 1; editor.Documents.Item( i ) != d; i -- ) {
      editor.Documents.Item( i ).Close();
    }
    d.Activate();
    
    // ※「while だからダメ」というわけじゃないので、一応...
    // 右側のタブをすべて閉じる
    var d = Document;
    var dCount = editor.Documents.Count;
    var i = dCount - 1;		//  <= コレと
    while ( editor.Documents.Item( i ) != d ) {
      editor.Documents.Item( i ).Close();
      i --;		//  <= コレが必要なので、結局は for 文のほうがシンプルですね
    }
    d.Activate();

    var ds = Editor.Documents; でも問題なく動いてくれていますが、ループ処理中に Documents の中身が変動していることをふまえると、やはり変数ナシのほうが正しい気がします。

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