複数の無題タブを識別する方法について

  1. Kuroさん

    開発お疲れさまです。

    「無題タブを識別・選択する方法」がもしあれば、ご教示いただきたいです。

    必要となった経緯ですが…
    今、VSCodeで「Sublime Text Keymap and Settings Importer」という拡張機能を入れた場合の「Alt+-」「Alt+Shift+-」キーの機能、「前に戻る」「次に進む」のような機能をMeryでも使えるように、マクロを作っています。(おそらく Sublime Text でも同じキーマップで同じ機能があるものと思われます)

    実現方法としては、
    ・カーソル移動時のイベントで window.Tag に位置情報(対象document及び行番号)を push していくイベント処理用マクロ
    ・window.Tag から位置情報を読み出し、ジャンプするマクロ(前に戻る、次に進む用をそれぞれ)
    を用意する算段です。

    ほぼ完成したのですが、ジャンプ先のdocumentを特定する際、無題タブでは難しいことに気付きました。

    以下はそのdocumentを取得する際の概念コードです。

    // 以下の previousPos には、0番目に行番号、1番目に document.FullName のフルパスが入っていると思って読んでください
    
    // 直前に開いていたdocumentオブジェクトを取得する
    var destDoc = null;
    for (var i = 0; i < editor.documents.Count; i++) {
      var d = editor.documents.Item(i);
      if (d.FullName == previousPos[1]) {
        destDoc = d;
        break;
      }
    }
    
    // 直前に開いていたdocumentに移動する
    destDoc.Activate();
    destDoc.selection.SetActivePoint(mePosLogical, 1, previousPos[0]);

    上記の previousPos という配列には行番号とフルパスが入っている想定です。
    無題タブの場合、document.FullName で空文字が返ってくるので previousPos[1] も空文字が入っています。
    そうなると「if (d.FullName == previousPos[1])」のところで問題が起こります。常に「先頭の無題タブ」で True になってしまうのです。
    これは無題タブが1つの場合は document.FullName が空文字になる document も1つだけなので問題ありませんが、複数存在する場合に問題となってきます。

    そこで前述の「無題タブを識別・選択する方法」が必要となりました。

    例えば、今の仕様であれば無題タブには常にユニークな連番「無題-n」が付いているので、
    (1) 無題タブであること
    (2) 無題タブ名
    の2つが document から取得できれば、判定できると考えています。

    (1)については「document.FullName が空文字」で判定できるので、(2)ができる方法があれば…と考えています。(むしろ(2)ができるようなメソッド・プロパティがあったら、それ1つで完結しそうではありますが)

     |  yuko  |  返信
  2. こんばんは、タイ語の件ではご協力ありがとうございました。

    > 「無題タブを識別・選択する方法」がもしあれば、ご教示いただきたいです。

    考えてみたのですが、現在のマクロの機能ですと簡単にはできないようですね。

    例えば、previousPos[2] に document.TextLength を入れておいてテキストの長さも条件として判別するとか。ユニークではないので確実ではないですが…。

    > (1)については「document.FullName が空文字」で判定できるので、(2)ができる方法があれば…と考えています。(むしろ(2)ができるようなメソッド・プロパティがあったら、それ1つで完結しそうではありますが)

    現在のところそういった機能はないのですが、やるとしたら document.Name プロパティを使って、無題の場合は「無題-x」なタブ名を返すようにするというのはいかがでしょうか?

    無題の場合、

    ・document.FullName は空
    ・document.Name は「無題-x」

    みたいな感じです。

    > (1) 無題タブであること
    > (2) 無題タブ名
    > むしろ(2)ができるようなメソッド・プロパティがあったら、それ1つで完結しそうではありますが

    document.FullName も「無題-x」を返すようにしても良さそうですが、既存のマクロで無題かどうかの判断を document.FullName が空文字かどうかで判断してるものもありそうですよね。

    document.Name もそういった用途で使われてるかもしれませんが、document.FullName よりは需要がなさそうですから。

     |  Kuro  |  返信
  3. > タイ語の件ではご協力ありがとうございました。

    他国の言語となると、対応に難儀しますね…。UNICODEに詳しそうな方がサポートに加わってくださってるのがせめてもの救いですね。

    タイ語は私もさっぱりですが、「結合文字」というのがあのトピックでちらほら出たのと、自身で結合文字のグリフを見ていたら何となく仕組みが分かってきて、HackGenでも持っていた(でもって放置していた)問題を解消するに至りました。なんだか逆にありがとうございます、という感じですw
    https://twitter.com/tawara_san/status/1397457633984974849?s=20

    > 例えば、previousPos[2] に document.TextLength を入れておいてテキストの長さも条件として判別するとか。ユニークではないので確実ではないですが…。

    なるほど、それは見当もつきませんでした。確実ではないものの、現状よりは格段に確度が上がりますね。

    > 現在のところそういった機能はないのですが、やるとしたら document.Name プロパティを使って、無題の場合は「無題-x」なタブ名を返すようにするというのはいかがでしょうか?
    > ・document.FullName は空
    > ・document.Name は「無題-x」

    いいと思います!
    というか、実はそういう風に一瞬組んで失敗したりしてましたw「document.Name はしれっと無題のタブ名返してくれるんじゃ…?」と思いまして。

    ただ、もしも「document.Name が空文字か」で無題を判定しているとか、日常的に「無題-x」という拡張子無しのファイル名で保存するような使い方をしているような人がいたら、マクロの動作に影響が出るかもしれませんね。
    …とはいっても、いずれもあまり無さそうなケースですし、上記案なら document.FullName に差し替えてもらうだけで動くでしょうから、そこまで大きな影響は出ないだろうなーと個人的にも思います。

     |  yuko  |  返信
  4. > 例えば、previousPos[2] に document.TextLength を入れておいてテキストの長さも条件として判別するとか。ユニークではないので確実ではないですが…。

    一旦この方式で暫定的に対処できるかなと思ってやってみたのですが、上手くいきませんでした…😅

    例えば「無題-1」で数個前の履歴に格納されていた document.TextLength と、編集したあとの document.TextLength では値が変わってしまっているのでうまく document を取れないので、やはり無題タブ名などでしっかり特定できないとダメそうです。

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