ブックマーク設定を保持できる Mery 2.7 の置換メソッドが速すぎて辛い

  1. ブックマーク設定を保持できる Mery 2.7 の置換メソッドって、なんであんなに処理が速いのでしょうか? うちのローエンド機でもバリ速すぎて「ありえない」レベルです。 :?
    マクロライブラリに投稿してある「字上げ/字下げ」系マクロ(インデント/逆インデント/スペース×2追加/削除)をブックマーク対応できるようにいじっているのですが、行数が多いと「置換」パネルで「選択した範囲のみ」「すべて置換」したほうがループ処理の JavaScript よりも圧倒的に速い…。

    ブックマーク対応の「字下げ」マクロは Replace( "^(?!$)", "\t", meFindReplaceRegExp + meReplaceSelOnly + meReplaceAll ) にしてしまうほうがよさそうな感じなのですが、「字上げ」マクロ(逆インデント/スペース×2削除)の場合は行頭の字下げを一段階ずつ消すことができず「行頭空白文字の完全抹消」になってしまうのでモヤモヤしています。 :(
    「すべて置換」とは別に「1行にたいして1回まで」のようなオプションフラグがあればいいのに、とか恨めしくおもったり。

    それとも「ループ処理が遅いのはマシンスペックや JScript 5.8 のせいで、Chakra ならループ処理でも遅くないから気にするな」な案件ならよいのですが、どなたか、ご助力・ご助言をいただけないでしょうか。

    /**
     * 数百行、数千行の処理だとモッサリな
     * ブックマーク対応の「逆インデント」マクロのループ処理コード
     * (行頭の タブ文字×1 と 半角空白×1~2 と 全角空白×1 が対象)
     */
    // ty は選択範囲の先頭行、yy は選択範囲の末行
    var s = document.selection;
    var ty = s.GetTopPointY( mePosLogical );
    var yy = s.GetBottomPointY( mePosLogical );
    var reg = /(?:^\t|^[ ]{1,2}|^[ ])/;
    var line;
    BeginUndoGroup();
    Redraw = false;
    
    for ( var y = ty; y <= yy; y ++ ) {
      line = document.GetLine( y, 0 );
      if ( reg.test( line ) ) {
        s.SetActivePoint( mePosLogical, 1, y );
        s.SetAnchorPoint( mePosLogical, line.length + 1, y );
        s.Text = line.replace( reg , "" );
      }
    }
    
    Redraw = true;
    EndUndoGroup();
     |  sukemaru  |  返信
  2. > ブックマーク対応の「字下げ」マクロは

    んーと、ん?……えーと、んー?ちょっとよくわからないです

    > 「字上げ」マクロ(逆インデント/スペース×2削除)の場合は行頭の字下げを一段階ずつ消すことができず「行頭空白文字の完全抹消」になってしまう

    ここが話の肝でしょうか。1段階消すと2段階目が繰り上がってきて、2段階目は行頭じゃなかったのに、「行頭の」になってしまって、結果全部消えちゃうと

    > ブックマーク対応の「字下げ」マクロは Replace( "^(?!$)", "\t", meFindReplaceRegExp + meReplaceSelOnly + meReplaceAll ) にしてしまうほうがよさそうな感じ

    よさそうな感じというのが速度的に問題ないということであれば

    s.Replace( "^\t|^[ ]{1,2}|^[ ]", "@", meFindReplaceRegExp + meReplaceSelOnly + meReplaceAll );
    s.Replace( "@", "", meFindReplaceRegExp + meReplaceSelOnly + meReplaceAll );

    これでどうでしょうか?まぁ全置換が2回になるので字下げよりは遅いでしょうし、わかんないこともいっぱいあるのでアレですけれど、for文でぐるぐるするよりは速いと思います。……たぶん

     |  シリル  |  返信
  3. >> シリル さん
    ありがとうございます。
    2段階で置換をかけるとは! 目からウロコです。( Д ) ..._。..._。コロコロコロ…
    for 文ぐるぐるでキャレットを移動させるのとはくらべるまでもなく、うちのロースペXPでも速度的に実用レベルになりました。これぞ「BeginUndoGroup() があればこそ」の方法ですね。 :D

    誤爆回避のための temp 文字列の検討が必要そうですし、他の問題も残っているので、しばらくはこれで「自家用」扱いでテスト運用してみます。 :)

    BeginUndoGroup();
    var s = document.selection;
    var flags = meFindReplaceRegExp + meReplaceSelOnly + meReplaceAll;
    s.Replace( "^\t|^[ ]{1,2}|^[ ]", "@temp@", flags );
    s.Replace( "^@temp@", "", flags );
    s.Find( "", 0 );	// 検索文字列と検索オプションをリセット
    // document.HighlightFind = false;	// Find( "", 0 ) を入れてれば不要?
    EndUndoGroup();
     |  sukemaru  |  返信
  4. > 目からウロコです。( Д ) ..._。..._。コロコロコロ…

    ウロコじゃない!めんたまめんたま!やぁ、うまく行って良かったです
    今、1000行ほどにそれぞれ複数のタブがあるものに試したところ、私の環境ではfor文が0.8秒前後、全置換2回が0.03秒台でした。
    まぁ、簡易検索一覧マクロは、もっともっと、遥かに、桁違いに遅いです。言い訳がましく「簡易」と付けておいてよかった←、というか見直すの面倒ゴニョゴニョ

    > ブックマーク対応の

    複数行を範囲選択してTabやShift+Tabで、インデントや逆インデントが出来るのになんでマクロ作るんだろ?と思ってました
    その範囲内にブックマークがあると、ブックマークが消えちゃうんですね、やっと意味がわかりました、わかりましたが、そこまでする必要あるんだろうか……と、うーん、すごく思います

     |  シリル  |  返信
  5. > 私の環境ではfor文が0.8秒前後、全置換2回が0.03秒台でした。
    なっ…? スゴっ! 以前 Kuro さんが Chakra なら 20 倍(当社比)と言っていましたが、for 文のループ 1000 行で 0.8 秒とは! まさに 20 倍。
    私のばあい、自分の環境で少しでも早く動いてくれるようにとない知恵をしぼりながらちょこちょこ修正していますが、そんな素敵な数字が出る環境なら他の拙作マクロもパッパと動作しそうですね。 :|

    > 「簡易検索一覧」マクロ
    うちの XP だとかなり厳しかったですが、Chakra ならきっと速いんだろーなぁとおもっていました。シリルさんのPCでも遅めですか…。 :(
    ソースコードや英文なら禁則処理がきくのでうちの「検索ジャンプ」マクロの論理行処理でも実用に十分なのですが、表示行の場合に日本語の検索には不十分なのがくやしいかんじです(表示行ベースのコードはすでに3回ボツにしてます)。
    表示行ベースの全文検索で 2.7 のスクロールバーマーキング並みの高速処理ができるコードを作ってみたいものですが、まだまだ勉強不足でなにをどうしたものかまるで検討がつきません。 :?

    > ブックマーク対応の
    インデント/逆インデントをマクロ化してからは標準コマンドのインデント/逆インデントを利用していなかったのですが、いまのところ(2.7.4)標準コマンドのほうでもブックマーク設定を保持できないみたいですね。
    拙作マクロは複数行の選択範囲にたいする文字列操作のものも多いので、ブックマークをむやみやたらに使い出したこのごろでは、ブックマーク設定をこわさないようにと悩んでばかりです。

    > そこまでする必要あるんだろうか……と、うーん、すごく思います
    慣れ親しんだインデント/逆インデントではありましたが、選択範囲がないと1行相手に効かないとか、半角空白2文字で2段階以上の字下げしている行に対して「逆インデント」すると「タブのケタ数」(4文字や8文字)にあわせて一発で消されてしまい1段ずつ上げられないとか、まあそれなりに個人的な事情があるのです。 :(

     |  sukemaru  |  返信
  6. > ブックマーク設定を保持できる Mery 2.7 の置換メソッドって、なんであんなに処理が速いのでしょうか?
    遅いというマクロ、私も試させていただきましたが、これが遅いのはエディタエンジンの仕様ですね。というのも、論理座標 (mePosLogical) です。

    エディタエンジンの設計が物理座標ベースになっているため、論理座標への変換処理 (SetActivePoint + mePosLogical) 自体が遅いんです。

    現在の Mery ですと、表面上は論理座標の計算速度をある程度ごまかせるぐらいの仕組みを作ってはいますが、エディタエンジンの根本的な設計が変わったわけではないので、SetActivePoint を一回呼ぶだけでも遅いのにそれをループで呼び出しちゃうともう…。

    論理座標から内部で保持している物理座標への変換速度をいかに向上させるかは、Mery 開発当時からの最大の目標ではありますが、いまだに解が見つかっていません。

    どなたか TNotePad のソース (Mana2_2014 の NotePadString.pas の 1153 行目付近、LinesPosToWrapPos メソッド) を読んで論理座標から物理座標への変換速度の改善案を教えて欲しいです。

    SetActivePoint では内部で論理座標から物理座標への変換に LinesPosToWrapPos が呼ばれているので、ほぼ全行スキャンが走ってて非常に遅いですね。

    > 複数行を範囲選択してTabやShift+Tabで、インデントや逆インデントが出来るのになんでマクロ作るんだろ?と思ってました
    私もずっとそう思ってました。技術的な好奇心旺盛なんだなぁ、すごいなぁと… ^^;

    まさかインデントでブックマークが消えてたとは!

    確かに…、エディタエンジンのソースを確認してみたらインデントの処理は内部で一度選択範囲を削除してから挿入する仕組みになっていたので、ブックマーク吹き飛びますわな。

    その処理、私が作ったわけじゃないので気づきませんでした。(と言い訳を挟みつつ)

    他にも、大文字に変換とか、タブを空白に変換とかの処理でも吹き飛んじゃいますねぇ。これはちょっと、私も速度との戦いの精神と時の部屋にこもることになりそうです。

     |  Kuro  |  返信
  7. いろいろと分かりやすくご説明いただきまして、ありがとうございます。
    > 遅いというマクロ、私も試させていただきましたが、これが遅いのはエディタエンジンの仕様ですね。というのも、論理座標 (mePosLogical) です。
    > エディタエンジンの設計が物理座標ベースになっているため、論理座標への変換処理 (SetActivePoint + mePosLogical) 自体が遅いんです。
    「キャレットの移動回数」だけは最小限におさえたつもりでしたが、まさかの罠!
    でも SetActivePoint( mePosLogical ) ではなく、SetActivePos( pos ) で動作させれば少しは動作速度があがるかもしれないのかしら。
    とりあえず今夜のところは行頭の pos を取得するコードを作るまでしかできませんでしたが、さらしておきます。
    これを「字下げ/字上げ」に組み込んで速度があがればいいのですが。

    // 全論理行の行頭の位置( pos )の配列を取得する
    var pArray = LineTopArray();
    
    // 100 行目か 3 行目の先頭に移動
    document.selection.SetActivePos( pArray[100] || pArray[3] );
    // ※ここまでで 0.1 秒弱/ 9500行(33 万文字) @ winXP(32bit); JScript 5.8
    // 約 0.8 ~ 0.9 秒/ 6 万行(780 万文字)
    
    // OutputBar.Writeln( pArray.join( ", " ) );	// ※行数が多いと文字列の描画コストがかかる
    // Alert( "論理行数: " + ( pArray.length - 1 ) + " 行" );
    
    /**
     * 論理行の行頭位置( Pos )を配列で返す関数
     */
    function LineTopArray() {
      // index と 論理行番号を一致させるために array[0] にダミー要素を入れておく
      var array = [ "LineTopPos", 0 ];		// array[1] は1行目の行頭 pos = 0
      var dText = document.Text;
      for ( var pos = 0; pos >= 0; ) {
        pos = dText.indexOf( "\n", pos );	// \n の出現位置
        if ( pos < 0 ) { break; }
        else { array.push( ++ pos ); }		// pos = pos + "\n".length
      }
      return array;
    }

    > 論理座標から内部で保持している物理座標への変換速度をいかに向上させるかは、Mery 開発当時からの最大の目標ではありますが、いまだに解が見つかっていません。
    「キャレットの移動なしで論理座標や pos から表示座標に変換するマクロメソッドの開発をいつかお願いしようと思っていました」なんて言いづらい…。 :(

    > どなたか TNotePad のソース (Mana2_2014 の NotePadString.pas の 1153 行目付近、LinesPosToWrapPos メソッド) を読んで論理座標から物理座標への変換速度の改善案を教えて欲しいです。
    なにが書いてあるのかまるでわかりませんでしたー。 ← オ呼ビジャナイ

    > これはちょっと、私も速度との戦いの精神と時の部屋にこもることになりそうです。
    (・∀・)人(・∀・)ナカーマ

     |  sukemaru  |  返信
  8. var start = new Date();	// 所要時間計測(開始)
    BeginUndoGroup(); Redraw = false;
    // ※選択範囲の拡張・調整は割愛
    var s = document.selection;
    var ty = s.GetTopPointY( mePosLogical );
    var yy = s.GetBottomPointY( mePosLogical );
    var reg = /(?:^\t|^[ ]{1,2}|^[ ])/;
    var line;
    
    /**
     * 全論理行の行頭位置(pos)を取得 (◆2019/05/10 追加)
     * ※ ty から yy に範囲を限定しても速度的に大差ないので、とりあえず全行
     */
    var array = [ "", 0 ];	// a[y] で論理行 y の行頭の pos
    var dText = document.Text;
    for ( var pos = 0; ; ) {
      pos = dText.indexOf( "\n", pos );	// \n の出現位置
      if ( pos < 0 ) { break; }
      else { array.push( ++ pos ); }	// pos = pos + "\n".length
    }
    
    /* pos ベースでループ処理するので、下の行から順に (◆2019/05/10 変更) */
    for ( var y = yy; y >= ty; y -- ) {
      line = d.GetLine( y, 0 );
      if ( reg.test( line ) ) {
        // s.SetActivePoint( mePosLogical, 1, y );	// (◆2019/05/10 コメントアウト)
        // s.SetAnchorPos( s.GetActivePos() + line.length );
        s.SetActivePos( array[y] );	// (◆2019/05/10 追加)
        s.SetAnchorPos( array[y] + line.length );
        s.Text = line.replace( reg , "" );
      }
    }
    // 元の選択範囲を復帰
    s.SetActivePoint( mePosLogical, 1, yy ); 
    s.EndOfLine( false, mePosLogical );
    s.SetAnchorPos( array[ty] );
    Redraw = true; EndUndoGroup();
    
    var elapsedSec = ( ( new Date() - start ) / 1000 ).toFixed( 3 );
    Status = "[ " + elapsedSec.replace( /\./, ". " ) + " 秒 ]";

    昨夜のコードを組み込んでみましたが、最初に貼ったコードと変わらず 100 行で 0.9 ~ 1.0 秒、1000 行で 12 ~ 14 秒でした。
    これはやはり「ボツ」ですね。 :(

    c.f. Replace() 2回での処理なら 100 行で約 0.1秒、1000 行で 3.8 秒。
    ブックマークがふき飛ぶ JavaScript の replace( /^\t|^[ ]{1,2}|^[ ]/gm, "" ) なら 100 行で約 0.02秒、1000 行で 0.2 秒。(@低スペXP JScript 5.8)

    Chakra だと Kuro さんにご説明いただいたような事情があてはまるのかもしれませんが、私の環境では SetActivePoint( mePosLogical, x, y ) が足を引っぱっているわけではなさそうです。
    というか、そもそも行ごとに書き換え s.Text = s.Text.replace( reg, "" ); するあたりががイケテナイですね。X(

     |  sukemaru  |  返信
  9. > 拙作マクロは複数行の選択範囲にたいする文字列操作のものも多いので、ブックマークをむやみやたらに使い出したこのごろでは、ブックマーク設定をこわさないようにと悩んでばかりです。

    と自分で言っておきながら、またブックマーク対応していないマクロを投稿してしまいました。:P
    ベータ版 Ver 2.6.9 のコメント欄で papagoat さんにいただいた「大文字小文字変換」マクロをいじりながら使ってきましたが、このたび「全角半角変換」マクロといっしょにリニューアルさせていただきました。
    >> papagoat さん
    その節はたいへんありがとうございました。

    いただきもののマクロばかりを使っていたので気がつきませんでしたが、いまさらながら Mery ビルトインの大文字/小文字変換や JavaScript の toLowerCase()/toUpperCase() ってアルファベット A-Z 以外にもしっかり対応しているんですね。 :D

     |  sukemaru  |  返信
  10. 置換1回で済ますなら、これでどうでしょう。

    var s = document.selection;
    var flags = meFindReplaceRegExp + meReplaceSelOnly + meReplaceAll;
    s.Replace( "^(?:\t| {1,2}| )(.*+)$", "$1", flags );
    document.HighlightFind = false;

    > どなたか TNotePad のソース (Mana2_2014 の NotePadString.pas の 1153 行目付近、LinesPosToWrapPos メソッド) を読んで論理座標から物理座標への変換速度の改善案を教えて欲しいです。
    試しに眺めてみましたが、最大でも数百行の JavaScript マクロしか書いていない分際なので、うーん…。
    ひとつ思いついたのは、先頭からではなく途中からスキャン、でしょうか。論理座標≦表示座標の関係が常に成り立つなら、論理座標あたりからスキャンを始められないかな、と。

    > 論理座標や pos から表示座標に変換するマクロメソッド
    MeryWiki の 利用者:黄身 さんの KILI ライブラリにそういうメソッドがありましたね(KILI.selex.logicalToView とか KILI.selex.posToView とか)。
    「行並べ替え」マクロの折り返し行の探査高速化では参考にいたしました。

     |  masme  |  返信
  11. > 置換1回で済ますなら、これでどうでしょう。
    ありがとうございます。
    そんな逆転の発想はまるでありませんでした。
    100 行で 0.05 ~ 0.06 秒、1000 行で 2.4 秒。もはやお茶に手を伸ばすヒマもありません。 :D
    s.Find( "", 0 ); を足して最新の検索履歴だけ消して、これで運用していこうとおもいます(というか、masme さんの「字下げ/字上げ」がブックマーク対応版に更新されるのを期待したりとか…。 ウッシッシ)。
    「引用符/コメント」マクロや「カッコで囲う」マクロにも流用できそうなので、いろいろと手を入れなおさないと。

    > MeryWiki の 利用者:黄身 さんの KILI ライブラリ
    あぁ、こんな隠しページが!
    これを読み込むにはしばらくかかりそうですが、いままで自作したマクロが「イラナイ子」になってしまいそうな予感がします。 :|

     |  sukemaru  |  返信
  12. > 「字下げ/字上げ」がブックマーク対応版に更新されるのを期待したりとか…。
    Selection.Replace 版を試作してみましたが、インデントするだけで検索・置換の設定が変わるのが気がかりでどうしたものかと。
    検索文字列・置換文字列・フラグの設定を読み書きできるプロパティとか、Selection.Find/Replace にオフレコで実行する(記録しない)フラグとかがあればいいのですが…。

    自分の場合、ブックマークは「消えてもいい」前提で使わないと精神衛生上よろしくないので、一時的なジャンプ地点くらいでしか使わないんですよね…。
    用途により別のエディタを使うこともあるので、「行頭に * や ★ を置く」みたいな自分ルールで文書自体に目印を付けて、正規表現検索やアウトラインで頭出しすることが多いです。

     |  masme  |  返信
  13. >> sukemaru さん
    > > これはちょっと、私も速度との戦いの精神と時の部屋にこもることになりそうです。
    > (・∀・)人(・∀・)ナカーマ
    なんとか、高速なままブックマークを保持して [インデント] や [選択範囲の変換] できるようになりました。次のバージョンでは標準搭載できると思いますが、ちょっと自信ないです…。

    >> masme さん
    > ひとつ思いついたのは、先頭からではなく途中からスキャン、でしょうか。論理座標≦表示座標の関係が常に成り立つなら、論理座標あたりからスキャンを始められないかな、と。
    ご協力ありがとうございます。

    確かに論理座標から物理座標への変換なのでその理論は行けそうですね。
    試しに実装してみましたところ、高速化されたような気がします。行の折り返しが多いと恩恵は少なくなりそうですが、先頭からスキャンするよりはよっぽど良いですね。

     |  Kuro  |  返信
  14. >> masme さん
    > インデントするだけで検索・置換の設定が変わるのが気がかりでどうしたものかと。
    公開用マクロにする場合、Replace() メソッドをつかう方法は、最新の検索履歴が書きかわってしまうことがネックになりますよね。なので、いまのところは私も自家用としてこっそり活用するだけです。

    > 自分の場合、ブックマークは「消えてもいい」前提で使わないと精神衛生上よろしくないので、一時的なジャンプ地点くらいでしか使わないんですよね…。
    アウトライン用のマーキングルールや段組み構成ならエディタを渡り歩いても門でいないのでしょうが、ブックマークをつけてドキュメントを管理しようとすると、他のエディタで編集しちゃいけなくなってしまうという問題がありますよね。 :|
    私の場合は PC のスペックが低いため、アウトラインはタブの切り替えにすぐについてきてくれないので、ブックマークのほうが断然使いやすいかんじです。
    自家用の「ブックマークジャンプ」マクロには masme さんの「行並べ替え」マクロにあった do - while ループも取り入れてアウトライン以上に使いやすくなりましたから、ブックマーク沼にどっぷりとはまってます。

    編集モードの構文ファイルやマクロをしっかり仕込んで使っているエディタは Mery だけですので、もう Mery からはなれられなくなっています。サブのエディタも別ディレクトリに用意した Mery (w/ sp モード) です。 :)

    >> Kuro さん
    > なんとか、高速なままブックマークを保持して [インデント] や [選択範囲の変換] できるようになりました。
    ありがとうございます。
    XPユーザーとしては、こういう使い勝手の向上こそ大歓迎です!(目玉機能のビッグウェーブには乗れないことが多いので)
    ブックマークに対応していない「大文字/小文字/頭文字変換」「全角/半角変換」のマクロを投稿したばかりでしたが、Mery 標準コマンドを利用するかたちにしておいてよかったー。 :D

    > 確かに論理座標から物理座標への変換なのでその理論は行けそうですね。
    > 試しに実装してみましたところ、高速化されたような気がします。
    どうすればそんなことができるのが教わりたいところですが、KILI ライブラリの JavaScript ですらチンプンカンプンな私には、きっと難しすぎるのでしょうね。 :(

     |  sukemaru  |  返信
  15. > 置換1回で済ますなら、これでどうでしょう。

    おぉ、流石はmasmeさんです。私実は正規表現さっぱりわかんないんですよね、勉強になります

    > なんとか、高速なままブックマークを保持して [インデント] や [選択範囲の変換] できるようになりました。次のバージョンでは標準搭載できると思いますが、ちょっと自信ないです…。

    ちょっと目を離した隙にスレ伸びてると思ったら難しそうな問題だなぁと思ってました
    これは口を挟めないゾとモジモジしている間に、解決の目処が立ってた!流石はKuroさんです
    ぶっちゃけ消えても別に気にしなかったですけど、サ○ラや秀○は消えないようでした。インデントの後に続けて「戻す」をすると秀○は消えちゃうようです

    C:\xxx\xxx.txt(5,5)
    ところでF10の機能で、()の中身が物理座標でも飛べるような仕組みが実はすでにあったりとかしますか?

     |  シリル  |  返信
  16. > ところでF10の機能で、()の中身が物理座標でも飛べるような仕組みが実はすでにあったりとかしますか?
    それっぽく動作するようにマクロを書いてみましたが、あまりうまくいきませんでした。 :|
    ジャンプ元の文字列から「ファイルへ移動(F10)」可能な文字列と (y,x) 座標を判別しようとするのは厄介だったので、「ファイルへ移動」してからゴニョゴニョする仕様にしました。 …っていうか、「ファイルへ移動」コマンドのファイルパスと座標の判定ルールがルーズすぎて、再現しづらかった。 X(

    一応、コードはマクロライブラリの「実験マクロ」のところに置いておきましたが、

    1. アウトプットバーの文字列からは表示座標ジャンプができない
     アウトプットバーにフォーカスがあるときは、ショートカットキーでマクロを起動することができません。
     アウトプットバーにフォーカスがあるときにツールバーアイコンでマクロを起動しても、論理行での F10 ジャンプのままになります(アウトプットバーの文字列を取得する方法がわかりませんでした)。

    2. 折り返しの多いファイルではうまく機能しないので、なにか失敗しているっぽい?
     とくに「指定文字数で折り返し」のばあい、論理行でジャンプしたまま終わってしまいます。
     GetActivePointY() の mePosView/mePosLogical が同じ値を返してきますし、すでに開いているファイルへの実行ならきちんと表示行でジャンプするので、よくわかりません。 :(

    うまく動作しない場合があるのは「オマ環」案件かもしれませんが、アウトプットバーから使えないのでシリルさん的にアウトですよね?
    https://www.haijin-boys.com/wiki/ファイルへ移動(物理座標ジャンプ)

     |  sukemaru  |  返信
  17. ひとつ思いついたのは、変更点を配列にぶっ込んでおき(書き換えは後で)
    配列データに従って後ろから処理
    (後ろからやれば座標は変わらないのでとりあえずそのままのデータを使える)

    論点違ってる可能性w

     |  クリ廃止  |  返信
  18. > https://www.haijin-boys.com/wiki/ファイルへ移動(物理座標ジャンプ)
    のマクロ
    > 2. 折り返しの多いファイルではうまく機能しないので、なにか失敗しているっぽい?
    >  とくに「指定文字数で折り返し」のばあい、論理行でジャンプしたまま終わってしまいます。
    >  GetActivePointY() の mePosView/mePosLogical が同じ値を返してきますし、すでに開いているファイルへの実行ならきちんと表示行でジャンプするので、よくわかりません。 :(
    については、Mery 2.7.5 でも(Mery 2.6.7 でも)おなじく物理行には飛んでくれず、Output にも正しい座標が返ってこないですね。2.6.7 だと「右端で折り返し」でも失敗することが多いような。
    うちだけ「オマ環」なのかしら? :(

     |  sukemaru  |  返信
  19. 返事が遅くなってしまってすみません

    > うまく動作しない場合があるのは「オマ環」案件かもしれませんが、アウトプットバーから使えないのでシリルさん的にアウトですよね?

    そうですね、残念ながらアウトです
    折角、マクロを作ってくれたらしいのに、申し訳ない限りですが、F10についてちょっと聞きたかっただけなので、マクロはいらないんです

    更に申し訳ないんですが「物理座標」を勘違いしてました
    あの、Posのことだと思ってたんです、文書の先頭からの文字数の奴です
    いやぁスレを読んでいるのにこの勘違いは我ながら酷いと思いますが

    > でも SetActivePoint( mePosLogical ) ではなく、SetActivePos( pos ) で動作させれば少しは動作速度があがるかもしれないのかしら。

    これを私も考えたんです。
    YahooAPIがPosを返してくるのでMeryのPosと混ぜて使って論理座標にしてますが、Posのまま飛べたら論理座標にしなくていいな、ひょっとしてF10にそんな隠し機能があるんじゃないかなと思った次第だったわけです

    まぁインデント等々の操作でブックマークは消えなくなりましたし、検索などの速度も余程、意地悪な条件でわざと負荷をかけなければミリ秒単位で終わりますし、そもそも絞れない検索に意味はないですしね、余計な質問でした

     |  シリル  |  返信
  20. > ところでF10の機能で、()の中身が物理座標でも飛べるような仕組みが実はすでにあったりとかしますか?

    そもそも私がこのご質問に答えていなかったようですね、すみません。sukemaru さんがマクロを開発してくださっていたので、解決したのかなーと思っておりました。

    F10 にそのような隠し機能は用意していないです。そして、物理座標というのは文字のインデックス位置 (Pos) のことだったのですね。

    > YahooAPIがPosを返してくるのでMeryのPosと混ぜて使って論理座標にしてますが、Posのまま飛べたら論理座標にしなくていいな、ひょっとしてF10にそんな隠し機能があるんじゃないかなと思った次第だったわけです

    そういうことでしたら、SetActivePos を使ってインデックス位置でタグジャンプするマクロを作って F10 キーに割り当てる、というのもアリでしょうか。

    YahooAPI の仕様を知らないので、Mery の Pos と一致するのかどうかはわかりませんが…。

     |  Kuro  |  返信
  21. >> Kuro さん
    > sukemaru さんがマクロを開発
    そのマクロについてですが、折り返しの多い文書のばあいには表示座標でのジャンプが効かないことがあります。
    マクロのコードは単純な仕組みで、
    ①ジャンプ元になる行の文字列を小文字変換して取得しておく
    ②F10 ジャンプを実行(ExecuteCommandByID)
    ③F10 ジャンプ実行後のアクティブタブのファイル名(小文字化)と ① の文字列を比較して、じっさいにジャンプが実行されたかを判別
    ④ジャンプしていた場合は、① の文字列から (y,x) があれば y,x を取得して SetActivePoint( mePosView, x, y ) を実行
    ※OutputBar.Writeln の部分をアンコメントするとアウトプットバーにログを出力

    散文、小説などのように改行までに複数回の折り返しのある行が多い文書では、SetActivePoint(mePosView, x, y) が正しく処理されず、F10 ジャンプ後の論理座標から移動しないことが多いようです。
    また、その場合は、最後の OutputBar.Writeln() で GetActivePointY(mePosView) と GetActivePointY(mePosLogical) が同じ値を返してきます。
    ジャンプ先のファイルがすでに開かれている状態であれば正常に物理座標に移動してくれるようで、物理座標ジャンプが失敗するのは F10 で新規にタブを開いたときにかぎって起きます。
    ※マクロライブラリのコードでは省いてありますが、ExecuteCommandByID() のあとに Sleep(2000) でウェイトを入れてもダメでした。← ログを確認すると、ウェイトなしでもジャンプ先のタブのファイル名 editor.ActiveDocument.Name を正常に取得できているので、ウェイトの必要性はないと判断しました。

    ベータ 2.7.7 のコメント欄で
    > マクロの GetLine メソッドの内部での論理行と物理行の変換処理が誤っているため、それらを使っているプラグインやマクロに影響が及んでいます。
    と書かれていましたが、このマクロの不具合とは関係なさそうですよね。マクロのコード上の不備ならよいのですが、Mery 本体側の不具合かもしれませんのでご確認いただけないでしょうか?
    ----
    また、勘違いを元にマクロを起こしたので、ジャンプ元になる "ファイルパス(y,x):" の文字列を返すマクロとして「簡易検索一覧などをアウトプット」を想定していたのですが、そもそもアウトプットバーの文字列を対象にマクロを実行したり、アウトプットバーにフォーカスがある状態でマクロを起動することができません。 :(
    将来的にアウトプットバーとマクロの連携を強めていただくことをご検討いただければとおもいます。

    > F10 にそのような隠し機能は用意していないです。そして、物理座標というのは文字のインデックス位置 (Pos) のことだったのですね。
    > そういうことでしたら、SetActivePos を使ってインデックス位置でタグジャンプするマクロを作って F10 キーに割り当てる、というのもアリでしょうか。
    Yahoo API との連携ということなので「校正支援アウトプット」マクロのアウトプットバーへの出力結果から SetActivePos なのでしょうね。
    これについても、上に書きましたように、マクロからアウトプットバーの文字列を取得する機能が必要そうな案件だとおもいます。

    マクロを書くさいにいろいろ試してみたら、F10 ジャンプっていい意味で "かなりあいまい" な仕様なようで(どうなってるの? というかんじですね)。
    相対パスは予想の範疇でしたが、半角数字 y,x 以外の文字列が挟まっていたりカッコが閉じてなくても関係なしだったりで、元の文字列から y, x を取得する正規表現を F10 ジャンプの仕様どおりにあわせることは断念しました。 :D

    >> シリル さん
    > そうですね、残念ながらアウトです
    まあ、予想していたとおりの結果です。lol

    > でも SetActivePoint( mePosLogical ) ではなく、SetActivePos( pos ) で動作させれば少しは動作速度があがるかもしれないのかしら。
    これについては、すでにこのトピック内に貼ったコードで確認したかぎりでは、マクロの動作内容にも夜かもしれませんが実効上で有意な差はなさそうです。
    5月10日のコードは masme さんに紹介していただいた KILI クラスを利用したものよりも処理速度が速いのですが、たいした役には立ちませんでした。

    まさに ↓ コレ ↓ ですね。
    > まぁインデント等々の操作でブックマークは消えなくなりましたし、検索などの速度も余程、意地悪な条件でわざと負荷をかけなければミリ秒単位で終わりますし
    100行ぐらいまでならループ処理での文字列操作でも1秒以内(@xp)で終わるので、「n万行で…」とかやらない私においては実用上「無問題」とおもっています。 :)

     |  sukemaru  |  返信
  22. ご返信ありがとうございます。

    > ベータ 2.7.7 のコメント欄で
    > > マクロの GetLine メソッドの内部での論理行と物理行の変換処理が誤っているため、それらを使っているプラグインやマクロに影響が及んでいます。
    > と書かれていましたが、このマクロの不具合とは関係なさそうですよね。マクロのコード上の不備ならよいのですが、Mery 本体側の不具合かもしれませんのでご確認いただけないでしょうか?

    これはフォントサイズを変更した場合で、折り返し位置が変わる状況下で発生する問題なので直接関係しているかどうかはわかりませんが、修正バージョンが出たら試してみてくださいね。

    なるべく早くリリースできるように努力しますので、今しばらくお待ちくださいませ。

    > 将来的にアウトプットバーとマクロの連携を強めていただくことをご検討いただければとおもいます。

    ああ、確かにアウトプットバーは出力専用となっていますね。プラグインのほうはアウトプットバーの内容を取得するメソッドが用意されています。この辺りはマクロとプラグインの差別化といった感じでしょうね。

    > マクロを書くさいにいろいろ試してみたら、F10 ジャンプっていい意味で "かなりあいまい" な仕様なようで(どうなってるの? というかんじですね)。

    あれはプログラムでゴリゴリ解析処理をしていますので、正規表現で同じロジックを再現するのは難しいと思います。

    > ※マクロライブラリのコードでは省いてありますが、ExecuteCommandByID() のあとに Sleep(2000) でウェイトを入れてもダメでした。← ログを確認すると、ウェイトなしでもジャンプ先のタブのファイル名 editor.ActiveDocument.Name を正常に取得できているので、ウェイトの必要性はないと判断しました。

    Sleep は処理待ちではなくただのフリーズなのであまり意味はないでしょうね。

    エディタエンジンの仕様で、ファイルを開いてからエディタウィンドウの幅が決定されて画面に描画されるまでは折り返し位置の計算がされていないようなのでそのせいかもしれないですね。(この仕様は現在のところ直し方がわかりませんので、ワークスペース機能でカーソル位置の復元を作るときにハマりました)

     |  Kuro  |  返信
  23. ご返信いただき、ありがとうございます。
    マクロを投稿した時点で使用上の制限や不具合内容も書いていたのですが、Kuro さんからもシリルさんからもコメントがなかったので、さびしかったです。
    表示座標ベースで動作させるマクロということで個人的には「どうでもいいや」なかんじでしたし、実験マクロとしても失敗作なので「まあいいや」でもありましたが。 lol

    > これはフォントサイズを変更した場合で、折り返し位置が変わる状況下で発生する問題なので直接関係しているかどうかはわかりませんが、修正バージョンが出たら試してみてくださいね。
    > Sleep は処理待ちではなくただのフリーズなのであまり意味はないでしょうね。
    > … (この仕様は現在のところ直し方がわかりませんので、ワークスペース機能でカーソル位置の復元を作るときにハマりました)
    諒解しました。
    Sleep については、以前、別のマクロの試作中にそれに思い当たることがありました。「オマエいま何もしてないだろ?」みたいなかんじでハマったような…。
    まさか本当に一服していただけだったとは。

    > ああ、確かにアウトプットバーは出力専用となっていますね。プラグインのほうはアウトプットバーの内容を取得するメソッドが用意されています。この辺りはマクロとプラグインの差別化といった感じでしょうね。
    ウィキで活動中のマクロ職人さんすら数少ないというのに…。
    モニター越しに芝居がかった口調で「汝がプラグイン。嗚呼、なんと高き壁! 狭き門よ!」と叫んでみました。聴こえましたでしょうか?

    > あれはプログラムでゴリゴリ解析処理をしていますので、正規表現で同じロジックを再現するのは難しいと思います。
    がっちり定型で "フルパス(行,桁):" に限定されていても問題なさそうな部分なのに、余計な文字列があってもジャンプすることに驚かされました。 実はものすごく気合の入った機能だったのですね! :o
    でしたら、いっそ F10 ジャンプの機能に「Mery では開けない拡張子のファイルパスなら既定のプログラムに投げる」ような機能を加えていただいたりは? …なんていうお願いをしたくなってしまいます。

     |  sukemaru  |  返信
  24. おおっと、ちょっと目を離すとスレが進む進む
    こんな風にレスポンスが早いのもMeryの大きな魅力の1つですよね、会社なんかだとなかなか難しいと思います。無理しないで下さいねKuroさん。sukemaruさんも。

    > そもそも私がこのご質問に答えていなかったようですね、すみません。sukemaru さんがマクロを開発してくださっていたので、解決したのかなーと思っておりました。

    いえ、質問が変だったのでエスパーして回答するのは至難だと思います、すみませんでした

    > マクロを投稿した時点で使用上の制限や不具合内容も書いていたのですが、Kuro さんからもシリルさんからもコメントがなかったので、さびしかったです。

    寂しい思いをさせてしまってすみませんでした

    > マクロを書くさいにいろいろ試してみたら、F10 ジャンプっていい意味で "かなりあいまい" な仕様なようで(どうなってるの? というかんじですね)。

    そうそう、余分な文字がくっついていたり、座標のところが ()←小括弧じゃなくて、[]←大括弧?でもちゃんと飛べたりとかは確認してたんです。でも探り探りでは仕様を見切るのは無理だなと思い、ひょっとして {}←中括弧ならPosで飛べる?とか、妄想に至ってしまい……。

    > 将来的にアウトプットバーとマクロの連携を強めていただくことをご検討いただければとおもいます。

    私は要望はしてないですからね。ちょっと聞いただけです。Posで飛ぶ機能は無いと回答いただけましたので満足しています。機能があるなら使うけど無いなら無いで困ってはいません
    「校正支援アウトプット」マクロでは論理座標にしてから出力していますので、これをPosで出力した上で使用者の方にF10を差し替えるマクロをさらに導入させるとなると不便極まりないですから。
    まぁ……そのぅ……「校正支援アウトプット」は、私しか使用してないかもしれませんが……。

    アウトプットバーってパワーシェルとか外部ツールの使用に利用するのがたぶん本筋なので、変則的な利用の仕方だと思います

    あ、でももし要望できるならアウトプットバーの文字のサイズを変更したいです。隠し機能で構わないので。いや、以前にもチラッと要望したことはあったので「しつこいシリル」なのですが、たぶんかなり難しい事も薄々感じてはいますので、【却下】でも構わないので開発室の項目に加えて頂けると嬉しいです。> Kuroさん
    (結局要望するんかい!っていう)

    > モニター越しに芝居がかった口調で「汝がプラグイン。嗚呼、なんと高き壁! 狭き門よ!」と叫んでみました。聴こえましたでしょうか?

    sukemaruさんならひょいと乗り越えられそうです

    > YahooAPI の仕様を知らないので、Mery の Pos と一致するのかどうかはわかりませんが…。

    作成時、ざっと確認した限りでは問題なかったのでたぶん平気だと思いますが、まぁ不安を感じている部分です。問題が起きたらその時考えます。

     |  シリル  |  返信
  25. > 「校正支援アウトプット」マクロでは論理座標にしてから出力していますので、これをPosで出力した上で使用者の方にF10を差し替えるマクロをさらに導入させるとなると不便極まりないですから。

    なるほど、F10 キーの隠し機能というのはそういう意味だったのですね。Ctrl を押しながら F10 キーを押したら Pos ジャンプ、とかかと思っていました。

    書式 (例えば "{5}" みたいな) によって Pos ジャンプ形式みたいな隠し機能じゃないと意味ないですね ^^;

    一般的な Grep の形式で Pos で指定する書式があるのなら採用しても構いませんがちょっと探してみましたけど見当たりませんでした。

    >アウトプットバーってパワーシェルとか外部ツールの使用に利用するのがたぶん本筋なので、変則的な利用の仕方だと思います

    そうなんですよね。そもそもアウトプットバーはコマンドラインの出力専用に作ってあるのでメモ代わりや独自機能の目的では使えないと思います。内部でかなり特殊なことをやってるので… ^^;

    > あ、でももし要望できるならアウトプットバーの文字のサイズを変更したいです。隠し機能で構わないので。いや、以前にもチラッと要望したことはあったので「しつこいシリル」なのですが、たぶんかなり難しい事も薄々感じてはいますので、【却下】でも構わないので開発室の項目に加えて頂けると嬉しいです。> Kuroさん

    一応、開発室のリストに追記しておきましたが、何故、アウトプットバーの部分の文字サイズを変更したいのかを教えていただけると開発の参考になります。(エディタ部分と揃っていたほうが美しいと思うので ^^;)

    > > YahooAPI の仕様を知らないので、Mery の Pos と一致するのかどうかはわかりませんが…。
    > 作成時、ざっと確認した限りでは問題なかったのでたぶん平気だと思いますが、まぁ不安を感じている部分です。問題が起きたらその時考えます。

    Mery の Pos は改行コード (\r\n とか \n とか \r に関係なく) を 1 として計算すると思うので、YahooAPI 側の改行コードの数え方次第で変わってくる気がしますが、そもそも Mery のタグジャンプで Pos 計算方式を採用しない限り議論の必要はなさそうですね… (w

     |  Kuro  |  返信
  26. > 一般的な Grep の形式で Pos で指定する書式があるのなら採用しても構いませんがちょっと探してみましたけど見当たりませんでした。

    そうですよね、変な質問をしてしまってすみません

    > 一応、開発室のリストに追記しておきましたが、何故、アウトプットバーの部分の文字サイズを変更したいのかを教えていただけると開発の参考になります。(エディタ部分と揃っていたほうが美しいと思うので ^^;)

    私はエディタ部分を等幅フォントの18ptで表示しています。ちょっと大きいですよね、もう少し小さくても見えないわけでは無いのですがこのくらいが楽です。
    そしてアウトラインはMeiryoKeのUIゴシックの12ptにしています。アウトラインにはルーラーがあるわけでもないしUIフォントなら限られたスペースでも極限までキュッと縮まってより多くの情報を表示できるかなと思ってます。
    テキストはタイトルバーやメインメニュー、タブバーにもあるわけですけれど、どれもこれも大きくするには表示スペース的にも限りがありますし、一番よく見るのはエディタ部分ですし、Zenモードの場合はそれらが消えるわけですし、やはり作業の快適さを考えると私はエディタ部分だけをちょっと大きめにしたいのですが、それに連動してアウトプットバーまでも大きくなってしまうと表示できる量が減ってしまって困るというか、サブ的な位置付けの物は小さくても頑張って見るので情報量の利便性を取りたい、メインのエディタ部分は目に優しく大きく表示したいという感じなんです。

    ちょっとくどくなっちゃいましたが許してください
    届いて欲しいのです、この思い!←

    開発室のリストに追記して頂いてありがとうございます
    これだけで満足かもしれません、もし気が向いたらご検討頂ければと思います

     |  シリル  |  返信
  27. ご返信ありがとうございます。

    なるほど、アウトプットバーの文字サイズ変更の件、用途はわかりました。

    というのも、文字サイズ変更といってもいくつかパターンがありまして、それによっては開発にかかる時間が結構変わってきますので、確認させていただいた次第です。

    例えば…

    (1) 【標準機能】文字サイズのみ変更する
    (2) 【標準機能】フォントも文字サイズも変更する
    (3) 【隠し機能】文字サイズのみ変更する
    (4) 【隠し機能】フォントも文字サイズも変更する

    (3) か (4) だと 1 ~ 2 日ぐらいで作れると思いますが、(2) だと新たに設定画面を開発しないといけないので数日かかります。

    (1) は、現在のアウトライン機能を右クリックしたときの [文字のサイズ] の機能と同等でよければ開発期間は短縮できるので、これなら実装できるかなと思ったのですが、サイズだけじゃなくてフォントを別のフォントにしたいとなると、これが流用できないのです。

    アウトラインのフォントを MeiryoKe にしているとのことなので、エディタ部分とは別のフォントを指定して、なおかつサイズも小さくということだと思いますので、やるとしたら (2) か (4) のパターンになりそうですね。

    文字のサイズを部分的に変更するのは、マルチディスプレイ環境における Per-Monitor DPI との兼ね合いで開発と検証に時間がかかるので、(1) のパターンであれば、動作検証済みなので実装しやすいところなのですけど…。

     |  Kuro  |  返信
  28. > 例えば…
    > (1) 【標準機能】文字サイズのみ変更する
    > (2) 【標準機能】フォントも文字サイズも変更する
    > (3) 【隠し機能】文字サイズのみ変更する
    > (4) 【隠し機能】フォントも文字サイズも変更する

    提示頂き、ありがとうございます
    私の希望は、(4)です。あ、正直言うと、ちょっと欲張りました。(3)でも平気です、すみません。
    アウトラインはそのエリアが縦長なので横に縮める効果が顕著に現れますけれど、アウトプットバーは横長なので、等幅かプロポーショナルのUIか、という違いよりも全体的に小さくなって行数が増えるところを期待しています。
    あ、でもフォントによっては行間が広くなったりするんでしたっけ、フォントは奥が深くて難しいです、そうするとやはり(4)が嬉しいです

    (1)ですと動作検証済みということですし、アウトラインと操作感が揃うでしょうし、良いことが多そうですけれど、18ptを基準に(小)または(最小)を選ぶ形だと、思ったサイズにならなさそうなので、それは困ります

    [Outline]
    FontName=MeiryoKe_UIGothic
    FontSize=12

    ini ファイルに上記を設定して使用しています。(1)ではデフォルトで(中)に設定されているようですが、これを(小)に設定して、タブを移動して、そしてタブを戻ると(中)に戻っているようです(今試していて気が付きました)。

    これはちょっと困るのでやはり(4)が嬉しいです。

    Kuroさんの貴重な時間を削ってしまい、大変申し訳ないですが、もし気が向いて実装頂けるのであれば(4)が嬉しいです。もしもKuroさんの興味が他に移った時はそちらを優先してください。のんびり待ちます

    スレッドの内容と外れてきてしまって申し訳ありません
    どうぞよろしくお願いいたします

     |  シリル  |  返信
  29. > これを(小)に設定して、タブを移動して、そしてタブを戻ると(中)に戻っているようです(今試していて気が付きました)。

    自己レスですが、設定した後Meryを閉じたり、iniファイルを編集するなりすればその設定のままで固定できるんですね、失礼しました。訂正いたします

     |  シリル  |  返信
  30. ご返信ありがとうございます。
    なるほど、その要件ですと (4) ですね。

    > これを(小)に設定して、タブを移動して、そしてタブを戻ると(中)に戻っているようです(今試していて気が付きました)。

    あー、確かに ^^; 文字サイズの変更は、アウトラインの文字サイズを簡単に一時的に変更したいというご要望だったので、即席でプロ生ちゃんプラグインから移植したものですから、保存のタイミングとかまで考慮してなかったですね。

    > Kuroさんの貴重な時間を削ってしまい、大変申し訳ないですが、もし気が向いて実装頂けるのであれば(4)が嬉しいです。もしもKuroさんの興味が他に移った時はそちらを優先してください。のんびり待ちます

    ありがとうございます。(4) ならたぶんすぐに実装できると思いますので、次のバージョンではこっそり搭載しておきます。

    でも隠し機能なので、設定方法は [Mery と遊ぼう] にてこっそり公開しますね。

     |  Kuro  |  返信
  31. > ありがとうございます。(4) ならたぶんすぐに実装できると思いますので、次のバージョンではこっそり搭載しておきます。
    >
    > でも隠し機能なので、設定方法は [Mery と遊ぼう] にてこっそり公開しますね。

    ありがとうございます、この件はすっごく大変なんだろうなぁと、なんとなく思っていたので、このように前向きなお返事をいただくことが出来てすごく嬉しいです。
    楽しみにしていますが、どうぞ無理をなさらず、よろしくお願いいたします

     |  シリル  |  返信
スポンサーリンク