Mery 3 !!!

  1. Mery ベータ版 「3.0.0」 公開、おめでとうございます。

    記事を読み返しつつ矩形選択とマルチカーソルの使い方をおぼえようと頑張っているところですが、さすがメジャーバージョンコードがあがっただけあって他にも変更箇所が多く、なにもかもが手探り状態で楽し~。 :D
    自作マクロのメンテができるようになるのはまだまだ先になりそうです。 LOL

    さて、早速ながら ver 3.0.0 で気になった部分についてのご報告をさせていただきます。
    ご確認お願いします。

    【不具合?】
    ➀ [オプション] >> [表示] 設定のカスタム色
    - カスタム設定してあった「水平罫線」の色がリセットされた

    また、
    - 「色の設定パネル」の「色の作成」の RGB 値の入力欄に各数値を直接入力した色が反映されない ( [ ... ] ボタンを Ctrl+クリックして HTML カラーの16進数を入力すれば正常に反映された)
    - 「色の設定パネル」の「色の追加」で保存してあったパレット内の色のいくつかも正常に反映されない

    ※ WinXP につき DirectWrite なし
    ※ 「色の設定パネル」がらみの問題が ver 3.0.0 固有のものかは不明

    ➁ クリップボード
    矩形選択から「コピー」した文字列データが、「クリップボード履歴」一覧の先頭や、マクロの ClipboardData.GetData( 0 ) に正常に反映されない(「クリップボード履歴」プラグインも同様)

    ※ 引数なしの ClipboardData.GetData() には反映され、Ctrl+V での矩形ペーストはできる

    ➂ ショートカットキー
    ver 3.0.0 で新規に追加されたショートカットキーとユーザー設定による既存のショートカットキーがバッティングしているばあい、同じ組み合わせキーにふたつの機能が登録された状態になる (キーボードマップでソートしたら、いくつかダブってました)

    ※ 別トピックで yuko さんが報告済みですね。 :P
    https://www.haijin-boys.com/discussions/5231

    p.s.
    【要望】
    - [編集] カテゴリのメニュー項目として「ひらがなに変換」と「カタカナに変換」コマンドがほしいです…

    ※ 現状では既存の「ひらがな/カタカナ変換」マクロをマルチカーソル対応させるのは難しいっぽいので。
    もしかすると、カーソル移動系メソッドとループ処理を使えばどうにかできるのかしら?
    マクロの枠組み内で解決できそうでしたらヒントをいただければとおもいます。

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

    > 変更箇所が多く、なにもかもが手探り状態で楽し~。 :D

    そうなんですよね。今回は "その他、細かい修正" に含めさせていただいた点もいくつかあるので、ご不明な点は都度ご質問いただければ回答させていただきたいと思います。

    > ➀ [オプション] >> [表示] 設定のカスタム色
    > - カスタム設定してあった「水平罫線」の色がリセットされた

    これは不具合ではなく、不具合の修正で INI ファイルの設定項目の誤字を修正したためですね。(テーマファイル .metheme のほうはあってました)

    お手数をおかけしますが設定しなおしてやってください。

    旧)

    [Display]
    CareForeColor=
    CareBackColor=
    CareStyle=0
    

    新)

    [Display]
    CaretForeColor=
    CaretBackColor=
    CaretStyle=0
    

    > - 「色の設定パネル」の「色の作成」の RGB 値の入力欄に各数値を直接入力した色が反映されない ( [ ... ] ボタンを Ctrl+クリックして HTML カラーの16進数を入力すれば正常に反映された)
    > - 「色の設定パネル」の「色の追加」で保存してあったパレット内の色のいくつかも正常に反映されない

    これは現象を再現することができませんでした。すべての項目に対して反映されませんか?それとも特定の項目だけでしょうか?

    他に再現するための条件などお気づきの点がございましたら教えていただけますと助かります。

    > ➁ クリップボード
    > 矩形選択から「コピー」した文字列データが、「クリップボード履歴」一覧の先頭や、マクロの ClipboardData.GetData( 0 ) に正常に反映されない(「クリップボード履歴」プラグインも同様)

    これは従来からの仕様ですね。

    矩形選択からのコピーは MSDEVColumnSelect、行コピー (未選択で Ctrl+C) は MSDEVLineSelect という特殊なクリップボード形式となっていますが、Mery のクリップボード履歴機能は単純なテキスト形式しか扱えないのでご了承ください。

    > ➂ ショートカットキー
    > ver 3.0.0 で新規に追加されたショートカットキーとユーザー設定による既存のショートカットキーがバッティングしているばあい、同じ組み合わせキーにふたつの機能が登録された状態になる (キーボードマップでソートしたら、いくつかダブってました)
    > ※ 別トピックで yuko さんが報告済みですね。 :P
    > https://www.haijin-boys.com/discussions/5231

    そうですね、これはユーザー設定を強制的に削除するわけにもいかないのでどうするのが正解なのか悩ましいところです。

    > - [編集] カテゴリのメニュー項目として「ひらがなに変換」と「カタカナに変換」コマンドがほしいです…
    > マクロの枠組み内で解決できそうでしたらヒントをいただければとおもいます。

    マクロで対応できるといいですが、現在のところマクロはマルチカーソルを完全に操作できるわけではないので難しいと思います。

    document.selection.Text= で記事で紹介した [マルチカーソル貼り付け] みたいな挙動をするようにすればなんとかなりそう?

     |  Kuro  |  返信
  3. Mery 3 開発お疲れ様です。

    > > - 「色の設定パネル」の「色の作成」の RGB 値の入力欄に各数値を直接入力した色が反映されない ( [ ... ] ボタンを Ctrl+クリックして HTML カラーの16進数を入力すれば正常に反映された)
    > > - 「色の設定パネル」の「色の追加」で保存してあったパレット内の色のいくつかも正常に反映されない
    >
    > これは現象を再現することができませんでした。すべての項目に対して反映されませんか?それとも特定の項目だけでしょうか?
    >
    > 他に再現するための条件などお気づきの点がございましたら教えていただけますと助かります。

    この記事を拝見して自分も前に似たようなことがあったのを思い出して、少し調べてみました。

    再現するための条件は、
    - 「作成した色」のまだ作成していないパレットをクリックしたとき
    - 「透明」から「カスタム」に切り替えたとき
    のいずれかです。

    空のパレット(見た目は同じだけど黒のパレットではない)をクリック、または、「透明」から「カスタム」に切り替えて「色の設定」を立ち上げると、
    - 赤:255 緑:255 青:255
    - 「色 | 純色」の部分は黒
    になります。

    この状態でパレットをクリックしたりスライダーを操作せず、直接数値を打ち込むとスライダーには反映されるのに「色 | 純色」には反映されず黒のままです。

    このまま「色の追加」や「OK」を押すと、スライダーと数値に関係なく黒扱いになってしまいます。

    以上、何か参考になれば幸いです。

     |  ucky  |  返信
  4. 動作検証のご協力ありがとうございます。

    頂いた条件で現象を再現することができました。

    調査してみましたところ、どうも色選択ダイアログに空っぽの色を渡すとこの現象が発生するようです。

    どうも開発環境上の問題のようで、Mery に限らず単純に色選択するだけのプログラムを作って試してみても同様の現象が発生しました。

    Ver 3.0.0 での問題ではなく過去のバージョンからずっと抱えている問題のようです。

    開発環境のバージョンを上げても改善されていないようなので対症療法となってしまいますが、次のバージョンでは何らかの対策をしておこうと思います。

     |  Kuro  |  返信
  5. こんばんは。

    > ※ 現状では既存の「ひらがな/カタカナ変換」マクロをマルチカーソル対応させるのは難しいっぽいので。
    > もしかすると、カーソル移動系メソッドとループ処理を使えばどうにかできるのかしら?
    > マクロの枠組み内で解決できそうでしたらヒントをいただければとおもいます。

    トグル機能には対応できていませんが、マルチカーソルに対応させる例として「ひらがな/カタカナ変換」を少しカスタマイズしてみました。

    https://www.haijin-boys.com/wiki/ひらがな/カタカナ変換#ひらがな/カタカナ_マルチカーソル対応版_(トグル変換未対応)_by_Kuro

    現状ですとマクロからマルチカーソルを設置することができないので、マルチカーソルが 1 度解除されてしまうとどうしようもないですね… ^^;

     |  Kuro  |  返信
  6. ご返信、ありがとうございます。

    > > - カスタム設定してあった「水平罫線」の色がリセットされた
    > これは不具合ではなく、不具合の修正で INI ファイルの設定項目の誤字を修正したためですね。(テーマファイル .metheme のほうはあってました)
    なるほど。INI に新しいキーができていましたので旧キーからコピペして修復できました。

    > > - 「色の設定パネル」の「色の作成」の RGB 値の入力欄に各数値を直接入力した色が反映されない ( [ ... ] ボタンを Ctrl+クリックして HTML カラーの16進数を入力すれば正常に反映された)
    > > - 「色の設定パネル」の「色の追加」で保存してあったパレット内の色のいくつかも正常に反映されない
    > これは現象を再現することができませんでした。すべての項目に対して反映されませんか?それとも特定の項目だけでしょうか?
    再現条件がみつからないのですが、発見したきっかけが上の「水平罫線」のカスタム色の再設定をしようとしたときなので、すでにカスタム色が設定されているアイテム(水平罫線以外でも)でも保存済みパレット色の一部が黒い四角になってしまっています。 RGB 値の入力欄にカスタム値は入っているのに黒になってしまうんです、としか…。

    かといって保存パレット内のすべての枠が黒になってしまっているのではなく、色つきの枠のカスタム色は RGB 入力欄の数値を変更しても問題なくて…。
    あと、パレット内の未変更のはずの枠内(RGB=255,255,255)はすべて黒で表示されています。

    色設定をいじること自体が久しぶりで、はたして ver 3.0.0 が原因かも不明なので、とりあえず以下のようなテストもしてみました。
    - パレットが壊れた Mery.ini で旧バージョン(ver 2.7.8 - 2.8.8)のいくつかを起動してみたら、いずれもパレットが壊れた状態になりました。
    - 2019年11月にバックアップをとってあった Mery.ini で ver 2.8.8 を起動してもパレットの同じ位置が壊れていました。
    …そもそもカスタムパレットって OS 側が管理してたりとか?

    > > ➁ クリップボード
    > これは従来からの仕様ですね。
    あらら。すみません、これまで 矩形選択機能を使っていなかったので気がついていませんでした。 :(

    > > - [編集] カテゴリのメニュー項目として「ひらがなに変換」と「カタカナに変換」コマンドがほしいです…
    > document.selection.Text= で記事で紹介した [マルチカーソル貼り付け] みたいな挙動をするようにすればなんとかなりそう?
    「ひらがな/カタカナ トグル変換」マクロのブックマーク検索/復帰処理などのキャレット移動をともなう部分をすべて削除してマルチカーソル選択範囲と矩形選択で試してみましたが、うまくいきませんでした。
    また、上のクリップボードの件と絡むのかもしれませんが、ClipboardData.SetData( document.selection.Text,replace( /hoge/g, "fuga" ) ); document.selection.Paste(); だとマルチカーソル選択範囲ではうまくいきますが、矩形選択で実行したときには変テコな結果に…。 :?

    「ひらがな/カタカナ トグル変換」マクロは replace() メソッドによる置換処理なので、単純化すると以下のようなかんじです(「t」が頻出するコードなので、「t」を「@@@」に置換させるコードにしてみました)。

    // 「ひらがな/カタカナ トグル変換」マクロを単純化したかんじのサンプルコード
    // → マルチカーソル選択範囲と矩形選択範囲のどちらもダメ
    var tmp = document.selection.Text.replace( /t/g, "@@@" );
    document.selection.Text = tmp;
    
    // マルチカーソル貼り付けっぽいコード?
    // → マルチカーソル選択範囲は OK / 矩形選択範囲はダメ
    var tmp = document.selection.Text.replace( /t/g, "@@@" );
    ClipboardData.SetData( tmp );
    document.selection.Paste();
    

    あらためて document.selection.Count や document.selection.Mode を使った条件分岐の方向で試行錯誤してみようとおもっていますが、はたしてどうなることやら? :|

    p.s.
    今日は一日中サポートにかかりきりだったのでしょうか?
    たくさん投稿してしまい、すみませんでした。

     |  sukemaru  |  返信
  7. ああ、またもや例のごとく…

    > トグル機能には対応できていませんが ...
    > 現状ですとマクロからマルチカーソルを設置することができないので、マルチカーソルが 1 度解除されてしまうとどうしようもないですね… ^^;
    改編コードを作っていただき、ありがとうございます。 :D
    GetTopPointX、GetTopPointY、GetBottomPointX、GetBottomPointY が(期待どおりに)バージョンアップしてますね。
    まだコードを仔細に解析していまんが、なるほど、やはり今までのメソッドから進化する必要があったと! 8)

    でも、カーソル移動をともなう処理(ブックマーク)をはずしても、矩形選択のときにはストリーム選択範囲として処理されてしまうようですので、さらに研究をしないといけないようで…。
    JavaScript で replace() メソッドを介して document.selection.Text = ... だと選択範囲を維持できないんですよね。 :(

    いまのところ ClipboardData を経由させる方法でも矩形選択への対応ができないようですので、どうも私の手にはあまる高難度の課題のような気がしてなりません。 XD
    矩形選択の各行内の位置情報の取得/復帰手段とマルチ選択範囲を再設定できる手段があればループ処理を駆使できるかも? ということみたいなので、当分は「ひらがな/カタカナ トグル変換」マクロは棚上げするしかなさそうな。

    > 複数の選択範囲に対して変換処理を行うときに、ひらがな・カタカナ変換のように行数が変化しないものはこのようにシンプルに書けますが、変換前と変換後で行数が変わる場合は複数選択の位置を再計算してやる必要があるのでもう少し大変だと思います。
    逆に変換前後で文字数が変化する「全角/半角 トグル」マクロは Mery ネイティブの変換機能を利用しているので、選択範囲は解除されず、手直しの必要がなさそうなかんじなんです。 :)
    「ひらがな/カタカナ」も同じ処理にできればとおもって、標準コマンド化のお願いをしたという。

    p.s.
    ver 3 用マクロのサンプルとして色々と研究させていただきますので、改造版コードはマクロリファレンスが更新されるまで残しておいてくださいね。

     |  sukemaru  |  返信
  8. Meryの開発お疲れ様です。

    今回の新バージョンの説明を読んでいて、Meryには以前から矩形選択機能があるのを
    初めて知りました。編集メニューには項目がないだけのようです。
    ○○パッドにも矩形選択、矩形貼り付けという項目が堂々と表示されています。
    別に隠し機能ではないと思いますので、編集メニューに表記された方が親切な気がします。
    誰もが使う機能ではないと思いますが、Meryを使い込んでいくうちに試したくなる機能だと思います。

     |  tisi  |  返信
  9. バージョンアップ作業、お疲れさまでした。ありがとうございます。

    マルチカーソル機能はなかなか興味深い動作ですが、現状の私のテキストエディタの使い方では、使う機会が余りないような気もします。
    しかし、おもしろそうですので機会を見つけて使っていきたいと思います。

    地味に、「行末を超えて移動」がありがたいです。

    「変更していない状態まで戻したときに変更マーク (*) を消すようにした」のは、私にとってはどちらでも構わないのですが、その影響なのか、新規のテキストで「元に戻す」ではなく「削除」などですべてのテキストを削除した場合、変更マーク (*) は消えなくなったのですね。
    それで不都合があるということではなく、これはこれで、実際に変更しているので仕様として正しい動作なんだろうなと思います。

     |  774  |  返信
  10. >> sukemaru さん

    > 改編コードを作っていただき、ありがとうございます。 :D

    いえいえ。私も現状のマクロ仕様でどこまでできるのか興味があったもので ^^

    > GetTopPointX、GetTopPointY、GetBottomPointX、GetBottomPointY が(期待どおりに)バージョンアップしてますね。

    引数を追加したのはこの 4 つだけですが、ある程度はなんとかなるものですね。

    > でも、カーソル移動をともなう処理(ブックマーク)をはずしても、矩形選択のときにはストリーム選択範囲として処理されてしまうようですので、さらに研究をしないといけないようで…。
    > JavaScript で replace() メソッドを介して document.selection.Text = ... だと選択範囲を維持できないんですよね。 :(

    それはそうですね。半角から全角への置換など、置換の内容によっては行ごとに文字の幅が変わって選択範囲が矩形 (長方形) じゃなくなるケースがありますから、置換後に矩形選択の状態を維持し続けることはできません。

    一応、矩形選択状態を復元する方法はあって、普通に SetActivePos などでストリーム選択の開始と終了をセットしてから、

    document.selection.Mode = meModeBox;
    

    こんな感じで矩形選択を指定してやれば、再び矩形選択の状態にすることはできます。

    もちろん矩形からはみ出した部分は選択外となりますが。

    > いまのところ ClipboardData を経由させる方法でも矩形選択への対応ができないようですので、どうも私の手にはあまる高難度の課題のような気がしてなりません。 XD

    ClipboardData を経由すれば複数選択や矩形選択への対応は可能です。

    ただ、上で書いたとおり矩形選択の状態を維持したまま文字列編集や置換を行うことはできないため、一度、ストリーム選択 (複数選択化) に展開してやる必要があります。

    // 矩形選択を複数選択にする
    document.selection.Mode = meModeMulti;
    
    // マルチカーソル貼り付けっぽいコード?
    // → マルチカーソル選択範囲は OK / 矩形選択範囲はダメ
    var tmp = document.selection.Text.replace( /t/g, "@@@" );
    ClipboardData.SetData( tmp );
    document.selection.Paste();
    

    > 矩形選択の各行内の位置情報の取得/復帰手段とマルチ選択範囲を再設定できる手段があればループ処理を駆使できるかも? ということみたいなので、当分は「ひらがな/カタカナ トグル変換」マクロは棚上げするしかなさそうな。

    複数選択を設置できる手段があれば色々と捗りそうですが、他のエディターでもマクロやエクステンションからマルチカーソルを操作できるものは見当たらないですね。正直、マクロをどんな仕様にすればマルチカーソルに対応できるのか思い浮かばないといった感じです。

    > 「ひらがな/カタカナ」も同じ処理にできればとおもって、標準コマンド化のお願いをしたという。

    そうするのが一番簡単ですが、それをやってしまうと、ではソートも、では重複除去も、などと多機能系への道をまっしぐらですからね… ^^;

    > ver 3 用マクロのサンプルとして色々と研究させていただきますので、改造版コードはマクロリファレンスが更新されるまで残しておいてくださいね。

    了解しました。勝手に sukemaru さんのページに追記させていただきましたので、必要なくなれば削除してやってください。

    マクロリファレンスは正式版の Ver 2.6.7 の状態を保持しておかないといけないので、いつになるやら… (w

    >> tisi さん

    こんばんは。記事を読んでいただきありがとうございます。

    > 初めて知りました。編集メニューには項目がないだけのようです。

    そうなんですよね。Mery は初心者さんでも使えるシンプル志向のテキストエディターということで、ユーザーさんの中にはメモ帳しか使ったことのない人もいますから、なるべく余計な機能を見せびらかさないようにしています。

    矩形選択なんてその言葉の響きだけでも難しそうなイメージありますからね (w

    そういえば VSCode はこの 2 月のアップデートで矩形選択 (列選択モード) がメニューに追加されました。

    確かに、機能をたくさん並べると色々できることは分かるかもしれませんが、機能を使わない人の邪魔にならないようにすることのほうが重要だと考えています。

    それでいて、機能を使う人は出来るかどうか試してみたら普通に出来た、ぐらいが Mery のコンセプトです。

    だったら記事で紹介するなとツッコミが入りそうですが、Mery にはマニュアルがないので解説記事はその点をフォローするためのものでもあります。

    もちろん、せっかく作ったので誰かに使ってもらいたい気持ちもありますが ^^;

    そういうわけですぐに対応というわけにはいきませんが、ご意見は今後の開発の参考にさせていただきたいと思います。

    >> 774 さん

    Mery Ver 3.0.0 をお試しいただきありがとうございます。

    > しかし、おもしろそうですので機会を見つけて使っていきたいと思います。

    使いどころのイメージがなかなかつかみづらいのはありますね。私も最初は何に使うんだろう?と思っていました。

    ときどき、お、ここはマルチカーソル使えるんじゃね?というシーンに出くわすと嬉しくなりますが、やはり少々慣れが必要かもしれませんね。

    > 地味に、「行末を超えて移動」がありがたいです。

    これ、以前のバージョンでも Alt+マウスクリックで一応できることはできていたのですが、今回はキーボード操作に対応したのと、マウス使用時もなんか引っ掛かりがあったのを改善しました。

    > 「変更していない状態まで戻したときに変更マーク (*) を消すようにした」のは、私にとってはどちらでも構わないのですが、その影響なのか、新規のテキストで「元に戻す」ではなく「削除」などですべてのテキストを削除した場合、変更マーク (*) は消えなくなったのですね。

    そうですね。従来は変更していない状態まで戻したときに変更マークを消す仕組みがなかったので、"せめて「無題 (新規文書)」で空っぽまで元に戻したら変更マークを消してほしい" というご要望があり、暫定対応で常にテキストの内容を監視して「無題」で空っぽの状態になったら変更マークを消すという仕組みを入れていました。

    今回、「変更していない状態まで戻したときに変更マーク (*) を消すようにした」ので、とりあえずそのご要望は満たしていると判断し、暫定対応だったテキストの内容を監視する処理を外したというわけです。

    しかしこの仕様、気になったので調べてみたところエディターによってさまざまですね。

    ▼「無題」で、「削除」を使ってすべて削除したときに [未変更] になるエディター
    Visual Studio Code
    Atom
    Mery Ver 2.8.8

    ▼「無題」で、「削除」を使ってすべて削除したときは [変更済み] のままのエディター
    秀〇エディタさん
    サク〇エディタさん
    TeraP〇d さん
    Visual Studio 2019
    ワードパッド
    Brackets
    Mery Ver 3.0.0

    ▼「無題」で、「削除」を使ってすべて削除したときは [変更済み] だけど、閉じるときに確認ダイアログを出さないエディター
    メモ帳
    Notepad++
    Sublime Text

    というわけで、マイクロソフト製品の中でも仕様がブレているようで、どの仕様が正しいのかは判断が難しいところです。

    個人的には「削除」ですべて削除したときは変更マークが残り、閉じるときにも確認ダイアログが表示されたほうが安全だとは思います。

    メモ書きなどで「無題」を新規作成して適当に書いたあと、すべて削除して書き直すということはよくある操作ですから、そういった操作の途中で、たまたま内容が空になったときに、[閉じる] で確認ダイアログなしで消滅してしまう可能性が残りますからね。

    反対意見としては「無題」で空っぽなのに閉じるときにいちいち確認ダイアログを表示しないで欲しいというのもあると思いますが…。

     |  Kuro  |  返信
  11. ご返信、ありがとうございます。

    > > 地味に、「行末を超えて移動」がありがたいです。
    > これ、以前のバージョンでも Alt+マウスクリックで一応できることはできていたのですが、今回はキーボード操作に対応したのと、マウス使用時もなんか引っ掛かりがあったのを改善しました。

    そうでしたか。知りませんでした。

    > > 新規のテキストで「元に戻す」ではなく「削除」などですべてのテキストを削除した場合、変更マーク (*) は消えなくなったのですね。
    > この仕様、気になったので調べてみたところエディターによってさまざまですね。

    お手数をおかけしました。
    それぞれのエディターで動作はさまざまなのですね。

    > 個人的には「削除」ですべて削除したときは変更マークが残り、閉じるときにも確認ダイアログが表示されたほうが安全だとは思います。

    私もそう思います。
    [閉じる] もそうですが、従来は、1度編集されていて今は空っぽの「無題 (新規文書)」の文書が表示されているときに、新たなファイルを開くと「無題 (新規文書)」は消えてしまいますしね。

    > 反対意見としては「無題」で空っぽなのに閉じるときにいちいち確認ダイアログを表示しないで欲しいというのもあると思いますが…。

    そういった意見が多数ある場合は、隠しオプションで対応して欲しいです。

    そういえば、私のPCは、
    『Ctrl + Alt + ↑ or ↓ のショートカットキーは、お使いのグラフィックカードのドライバーによっては、画面の回転などに割り当てられている場合がありますのでご注意ください。』
    に引っかかってしまったようです。
    縦書きは使用しないので、とりあえず、Ctrl + ↑ or ↓ に割り当てましたが。

     |  774  |  返信
  12. Mery 3.0.0 リリースおつかれさまです。
    早速、私も触ってみてますが、何から語ればいいものか…。
    ひとまず更新履歴の「SetAnchorPoint、SetAnchorPos の挙動がおかしかったのを修正」が気になります。何か不具合ありましたっけ?

    > 「ひらがなに変換」と「カタカナに変換」

    3年前、矩形選択に暫定対処したマクロを書いたものの、MeryWiki への投稿を見送ったことを思い出しました。
    このままお蔵入りもなんなので、この機会に複数選択でも一応動作するように大雑把に改造したものを晒してみます。

    //■カタカナに変換
    main: {
    var MARK = "\u0080\uFFFD\u007F"; // 目印
    var MAP = (function(){ // 変換用関数
      var re = /[ぁ-ゖゝゞ]/g;
      var map = {
     "ぁ":"ァ","ぃ":"ィ","ぅ":"ゥ","ぇ":"ェ","ぉ":"ォ"
    ,"あ":"ア","い":"イ","う":"ウ","え":"エ","お":"オ"
    ,"か":"カ","き":"キ","く":"ク","け":"ケ","こ":"コ"
    ,"が":"ガ","ぎ":"ギ","ぐ":"グ","げ":"ゲ","ご":"ゴ"
    ,"さ":"サ","し":"シ","す":"ス","せ":"セ","そ":"ソ"
    ,"ざ":"ザ","じ":"ジ","ず":"ズ","ぜ":"ゼ","ぞ":"ゾ"
    ,"た":"タ","ち":"チ","つ":"ツ","て":"テ","と":"ト"
    ,"だ":"ダ","ぢ":"ヂ","づ":"ヅ","で":"デ","ど":"ド"
    ,"な":"ナ","に":"ニ","ぬ":"ヌ","ね":"ネ","の":"ノ"
    ,"は":"ハ","ひ":"ヒ","ふ":"フ","へ":"ヘ","ほ":"ホ"
    ,"ば":"バ","び":"ビ","ぶ":"ブ","べ":"ベ","ぼ":"ボ"
    ,"ぱ":"パ","ぴ":"ピ","ぷ":"プ","ぺ":"ペ","ぽ":"ポ"
    ,"ま":"マ","み":"ミ","む":"ム","め":"メ","も":"モ"
    ,"ゃ":"ャ","ゅ":"ュ","ょ":"ョ","っ":"ッ","ゎ":"ヮ"
    ,"や":"ヤ","ゆ":"ユ","よ":"ヨ","ゝ":"ヽ","ゞ":"ヾ"
    ,"ら":"ラ","り":"リ","る":"ル","れ":"レ","ろ":"ロ"
    ,"わ":"ワ","ゐ":"ヰ","ゑ":"ヱ","を":"ヲ","ん":"ン"
    ,"ゔ":"ヴ","ゕ":"ヵ","ゖ":"ヶ"
      };
     return function(str){ return str.replace(re, function(s){return map[s] || s}); };
    }());
    var Sel = Document.Selection;
    if (Sel.IsEmpty) break main; // 非選択時は中止
    var acp = Sel.GetActivePos();
    BeginUndoGroup(); // アンドゥ履歴対策
    Sel.Replace("^([\\s\\S]+)$", MARK+"$1"+MARK, meFindReplaceRegExp+meReplaceSelOnly+meReplaceAll);
      // ↑ 選択範囲の先頭/末尾に目印を挿入
    Sel.StartOfDocument();
    Status = "";
    var re = new RegExp(MARK+"([\\s\\S]+?)"+MARK,"g");
    do {
      Sel.Find(MARK+"([\\s\\S]+?)"+MARK, meFindReplaceRegExp+meFindNext);
      Sel.Text = Sel.Text.replace(re, function(_,$1){return MAP($1)});
      // ↑ 目印の区間を対象に処理し、目印を除去
    } while (!Status);
    EndUndoGroup();
    Document.HighlightFind = false;
    Status = "";
    Sel.SetActivePos(acp);
    }
    

    で、投稿を見送ったのは、この方法には無視できない難点があるからでして。
    a. 検索/置換の設定が変更される。
    b. 目印となる文字列が文書内ですでに使用されていた場合、目印の区間を誤判定する。そのため見慣れない文字列を目印に使うわけだが、そうすると検索/置換文字列に見慣れない文字列が表示される問題が。
     → Find/Replace メソッドに設定を変更(記録)しないフラグ meFindReplaceOffRecord (仮称) が欲しい。
    c. 選択範囲を維持できない(マクロで矩形/複数選択を実現できないため)。「大文字/小文字に変換」「半角/全角に変換」などは維持されるので余計にツラい。
     → Find で目印の区間をすべて検索し、Replace で目印を除去すれば、選択範囲を維持したように見せられるかも。
    d. 「選択範囲の先頭/終端を行頭/行末とみなさない」がオンの場合、先頭行/終端行に目印が挿入されない恐れ。
     → "(?:^|\\A)([\\s\\S]+)(?:$|\\z)" でイケそう。
     → みなさない設定の判別手段がないので今後問題になりそう。フラグが欲しい(設定を記録しないフラグと併用すれば、ユーザー環境を汚さずマクロ側で挙動を制御できる)。

    当時は、矩形選択になんとか対処するには Replace で目印を付けておく方法しかなかったんですが、今なら、もうちょっとでなんとかなりそうな気がしますね。

    > 複数選択を設置できる手段があれば色々と捗りそうですが、他のエディターでもマクロやエクステンションからマルチカーソルを操作できるものは見当たらないですね。正直、マクロをどんな仕様にすればマルチカーソルに対応できるのか思い浮かばないといった感じです。

    「マルチカーソル実装によるマクロなどへの影響(https://www.haijin-boys.com/discussions/5182)」で挙げられていた Selections (複数形) 案はどうなんでしょう? すでに Editor(s) / Document(s) があるので構造的にはキレイそうですが…。
    先のトピックでは本題から脱線しそうで掘り下げませんでしたが、範囲が重複する場合はマージされるので Selection の数が保証されないとどういう問題がありそうでしょうか。

    他に思いつくこととしては、Selections(複) にも Selection(単) のメソッドを持たせて、複数選択すべてを操作する場合は複数形を、個別に操作する場合は単数形を使うというのはどうだろうか、と。
    たとえば、Selections(複).CharRight はカーソルすべてを右に、Selection(単).CharRight はカーソルを個別で右に移動。Selections(複).Text は範囲すべての文字列を改行区切りで返し、Selection(単).Text は個別の範囲の文字列を返す。という具合で。

     |  masme  |  返信
  13. Mery Ver 3.0.0 をお試しいただきありがとうございます。

    > ひとまず更新履歴の「SetAnchorPoint、SetAnchorPos の挙動がおかしかったのを修正」が気になります。何か不具合ありましたっけ?

    これはちょっと分かりづらい点だと思いますが、従来は SetAnchorPos で一旦選択範囲が解除されたのち、アンカーポイント (選択開始位置) が移動していました。

    本来、意図していた動作としては SetAnchorPos はアンカーポイント (選択開始位置) をただ移動させるだけ。が正しいです。

    > 「マルチカーソル実装によるマクロなどへの影響(https://www.haijin-boys.com/discussions/5182)」で挙げられていた Selections (複数形) 案はどうなんでしょう? すでに Editor(s) / Document(s) があるので構造的にはキレイそうですが…。
    > 先のトピックでは本題から脱線しそうで掘り下げませんでしたが、範囲が重複する場合はマージされるので Selection の数が保証されないとどういう問題がありそうでしょうか。

    そうなんですよね。言語仕様としてはそれが理想的なのですが、マルチカーソルの仕様としてはこれが非常にやっかいで、マルチカーソルに対応している他のエディターもマクロ側が対応できていないのはここが問題なのだと思います。

    selections の数が保証されないというのは、実際の操作でマルチカーソルを使って Ctrl を押しながら選択範囲をいくつか重ね合わせていただけると分かりやすいかと思います。

    マルチカーソルの仕様上、選択範囲が重複した場合、それらはマージされて 1 つの選択範囲になります。

    つまり、selections 案を採用した場合、例えば以下のような for 文です。

    for (var i = 0; i < document.selection.count; i++) {
    	// 選択範囲開始
    	document.selections[i].SetActivePos(p, false);
    	// 選択範囲終了
    	document.selections[i].SetActivePos(q, true);
    }
    

    p と q はランダムとします。

    マルチカーソルによる複数選択のそれぞれの箇所をランダムな選択範囲に散らす感じの処理というイメージですが、本来、言語仕様としては document.selection.count の数は変化してはいけません。

    しかし、マルチカーソルの仕様上、選択範囲が重なるとマージされて 1 つの選択範囲になりますから、ループの最中に選択範囲がマージされて selection.count の数が減ってしまう可能性があるわけです。

    > 他に思いつくこととしては、Selections(複) にも Selection(単) のメソッドを持たせて、複数選択すべてを操作する場合は複数形を、個別に操作する場合は単数形を使うというのはどうだろうか、と。

    上記の理由から selections 複数形を持たせることは難しいと思います。

    では選択範囲をマージしなければ良いのでは?と思われるかもしれませんが、選択範囲が重複した場合にマージしないようにすると、複数の選択範囲が重複している部分のテキストデータをどう扱うかというさらに大きな問題が出てきます。

    と、こういった理由から、Ver 3.0.0 のマルチカーソルの仕様を考えました。

    現状、他のエディターでもマクロやプラグインからマルチカーソルを操作できる仕組みはなさそうなので、これが実現できれば面白いですよね。

     |  Kuro  |  返信
  14. ご返信ありがとうございます。

    > そういった意見が多数ある場合は、隠しオプションで対応して欲しいです。

    そうですね、一応、この仕様なエディターが多そうなので理由になりますし、その方向で対応させていただこうと思います。

    > そういえば、私のPCは、
    > 『Ctrl + Alt + ↑ or ↓ のショートカットキーは、お使いのグラフィックカードのドライバーによっては、画面の回転などに割り当てられている場合がありますのでご注意ください。』
    > に引っかかってしまったようです。

    実は私の Mery 開発用 PC がこの仕様に引っ掛かったので、そのうえで注意書きをしていました。

    この現象は割と有名なようで、マイクロソフトの VSCode のマルチカーソルも Ctrl + Alt + ↑ or ↓ に割り当てられているのですが、操作マニュアルに同様の注意書きがあります。

    Mery のショートカットキーを変更する方法もありますし、グラボのホットキーを無効にするという方法もあります。

    引っ掛かりそうなユーザーさんも多そうなので、記事中の注意事項にグラボ側の設定変更の方法が記載されている外部サイトへのリンクを追記させていただきました。

    私のブログではないのでサポートはできませんが、この方法で私の PC では改善されました。
    https://at.sachi-web.com/blog-entry-999.html

     |  Kuro  |  返信
  15. >> masme さん
    > > 「ひらがなに変換」と「カタカナに変換」
    「テキスト整形」マクロでも「全角に変換」や「大文字に変換」は Mery ビルトインメソッドを使用していて、「ひらがなに変換」と「カタカナに変換」は独自実装なんですよね。
    それぞれ単独コマンドとして右クリックメニューに登録したかったので当初は StrConv.Dll を使用していましたが(『小マクロ集』にもリンクを入れてありますが)、某巨大掲示板で StrConv.Dll は32ビット専用と書かれていましたので masme さんの「テキスト整形」から切り出すかたちでマクロライブラリに単独ページを設けちゃいました。

    私はこれまで自作マクロで矩形選択からの実行をいっさい考慮しない方針でしたので文字列操作のトグル変換マクロもなんとかなっていた?のですが…。
    矩形選択やマルチカーソルが表立った機能となりましたからこれからは無視しづらいのですけど、いまのところは対応できそうにないという(← 個人的スキルの問題)。 :(

    >> Kuro さん
    > マルチカーソルによる複数選択のそれぞれの箇所をランダムな選択範囲に散らす感じの処理というイメージですが、本来、言語仕様としては document.selection.count の数は変化してはいけません。
    サンプルコードでは

    for (var i = 0; i < document.selection.count; i++) {

    となっていますが、こういったループ処理の条件を書くときは

    for (var i = 0, c = document.selection.count; i < c; i++) {

    のようにするものではないでしょうか?
    document.selection.count の値の変化に追従させたいときはブロック内か条件文の第3セクション?で c++ とか c-- すればよいとおもうので、選択範囲がマージされる基本仕様に あわせる/あわせない はマクロ側のコーディング次第だとおもいます。
    マージされた部分はもともと「1行分」として取得されているとおもうので、文字列を加工して返すときにも齟齬は生じなくなるんじゃないかしら? と。 :)
    SetActivePont などで選択範囲を復帰させるのは加工した文字列を文書に反映させたあとですから、マージで交差した角を Get/Set 出来る仕組みさえあれば(Set したあとの再マージは Mery 本体側になりますが)、あとはマクロ製作者側でどうにか…。

    > > 「ひらがな/カタカナ」も同じ処理にできればとおもって、標準コマンド化のお願いをしたという。
    > そうするのが一番簡単ですが、それをやってしまうと、ではソートも、では重複除去も、などと多機能系への道をまっしぐらですからね… ^^;
    もうすでに十二分以上に多機能すぎて、スーパーサ●ヤ人3以上にスカウター振り切っています! XD
    「ひらがな」「カタカナ」「昇順」「降順」コマンドは表面的に実装されても「選択範囲の変換」サブメニュー配下になるはずですし、ポップアップメニューやショートカット登録専用の潜在的実装であったとしても、初心者の方からマクロ廃人のお兄様お姉様方まで「あると嬉しい♡」機能だとおもいます。 :)

    矩形選択状態 ⇔ ストリーム選択 についていただいたサンプルコードにつきましては、マクロライブラリの改編版コードとあわせて、後日、腰をすえて研究させていただきます! (サクサク理解できるスキルがなくてゴメンナサイです)。 :)

    > グラボのショートカットキー
    ほかのソフトでは Alt+ をふくめて矢印がらみのショートカットをたくさん登録してますが、矢印がらみのホットキーってとりあえず登録しておいたけどどれがどれだか忘れちゃうからあれこれ叩きますし、不如意にデスクトップが回転してビックリすることになるので、グラボ設定で切っちゃいました。 :D

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

    グラフィックボードのホットキーを無効化することで、[Ctrl]+[Alt]+矢印キーが使えるようになりました。
    ショートカットキーを設定するダイアログでは[Alt]+矢印キーが効かないので、設定を戻すのに Mery.ini を直接編集する必要がありましたが。

    画面の回転はここ(https://www.intel.co.jp/content/www/jp/ja/support/articles/000005491/graphics-drivers.html 私のPCは「インテル®グラフィックス・メディア・アクセラレーター・ドライバー」のところ)で設定できるみたいですが、そもそも私のPCは画面の回転ができないのに、[Ctrl]+[Alt]+矢印キーは予約されているみたいです。
    https://light.dotup.org/uploda/light.dotup.org638614.png

     |  774  |  返信
  17. >> masme さん

    すみません、先日は時間の都合ですべての内容に返信できておらず、取り急ぎ書けた部分のみ投稿させていただきました。

    > このままお蔵入りもなんなので、この機会に複数選択でも一応動作するように大雑把に改造したものを晒してみます。

    なるほど、目印をつけるというアイデアは面白いですね。

    実は Mery のマルチカーソルもそれと同じような仕組みで、実際にカーソルや選択範囲が複数あるわけではなく、編集予定の箇所に目印をつけているだけなんです。

    で、編集を実行したときに上から順番にシングルカーソルで編集しているだけという (w

    > Find/Replace メソッドに設定を変更(記録)しないフラグ meFindReplaceOffRecord (仮称) が欲しい。

    これはときどきご要望をいただくことがあります。

    普段の更新ではマクロの仕様変更はなかなか気が進まないのですが、Ver 3.0.0 でメジャーバージョンが上がりましたし、ここに含めるのもアリかもしれませんね。

    > 「選択範囲の先頭/終端を行頭/行末とみなさない」がオンの場合、先頭行/終端行に目印が挿入されない恐れ。

    確かに、これはフラグで設定できたほうが良さそうですね。フラグ追加の方向で検討してみます。

    > たとえば、Selections(複).CharRight はカーソルすべてを右に、Selection(単).CharRight はカーソルを個別で右に移動。

    そうですね、「すべてのカーソルを右に」のような動作は実現できると思いますし、現状の selection.CharRight() がそうなっています。

    問題は Selection(単).CharRight のほうでして、例えば Selection(単).CharRight でカーソルを個別に右に 3 回移動させるとして、2 回目で別の選択範囲とぶつかったとします。

    // 1 回目
    Selection(単).CharRight();
    // 2 回目
    Selection(単).CharRight(); // ここで別の選択範囲とぶつかると…
    // 3 回目
    Selection(単).CharRight(); // すでに Selection(単) は存在しない
    

    2 つの重なり合う選択範囲 (実際は重なりあうのと同時にマージされるので重なり合った状態は存在しませんが) は結合されて新たな 1 つの選択範囲になりますので、もとの Selection(単) は消滅してしまいますから、上のような書き方が成立しないんです。

    > Selections(複).Text は範囲すべての文字列を改行区切りで返し、Selection(単).Text は個別の範囲の文字列を返す。という具合で。

    上記の理由から Selection(単).Text のような書き方も、Selection(単) がいつ消えてしまうかわかりませんから、実装したとしても扱いが非常に難しくなると思います。

    >> sukemaru さん

    > document.selection.count の値の変化に追従させたいときはブロック内か条件文の第3セクション?で c++ とか c-- すればよい

    はい、やりようはいくらでもあると思います。while 文でも構わないと思いますし。

    例として挙げたのはループを回す方法がないという意味ではなく、そこに Count プロパティがあれば普通の人は for 文でぐるぐる回してしまうよね、という意味です。

    一般的に for 文で回すときはループの途中でループ範囲が変化しないほうがいいですし、ループ範囲が変化するなら for 文を使わないほうが良いと思います。

    Count プロパティが変化することを前提とした場合でも、ユーザー側が意図した操作によって Count プロパティが変化するか、そうでない場合でも最低限、Count プロパティが変化したことをユーザー側が知ることができなければいけません。

    しかし、マージは Mery 内部で独自のアルゴリズムとタイミングで行われますので、Count プロパティが変化するタイミングをユーザー側で知ることができないため、言語仕様として穴となる、というわけです。

    > SetActivePont などで選択範囲を復帰させるのは加工した文字列を文書に反映させたあとですから、マージで交差した角を Get/Set 出来る仕組みさえあれば(Set したあとの再マージは Mery 本体側になりますが)、あとはマクロ製作者側でどうにか…。

    どうもマージという言葉の意図が上手く伝わっていないような気がするので、ちょっと補足説明させていただきます。

    選択範囲が複数あるとどうしても重複する箇所が出てきます。その重複した箇所の扱いをどうするかというと、2 つの選択範囲の重複した部分を結合して 1 つの選択範囲にする、という動作を意図してマージという言葉を選びましたが、それだとマージされる前は「2 つの選択範囲が重複した状態」もあり得るという意味にも取れますものね。

    そういう意図で、「マージで交差した」と書かれている気がするのですが、そもそも交差することがないのです。

    選択範囲が重複した状態そのものが存在しないので、ユーザーが Set した選択範囲をすぐに Get してもその選択範囲はもうそこには存在しないという状況が発生します。

    ただ、おっしゃるとおり選択範囲を復元するだけの目的であれば Set のみの一方通行なので問題ないと思いますけどね。

    選択範囲を復元するという用途のみに限定すると、

    document.selection.Add(iStart, iEnd);
    

    みたいな感じで iStart (選択開始位置)、iEnd (選択終了位置) を指定して選択範囲を追加できるメソッドを用意するといった方法は考えられます。

    > 「ひらがな」「カタカナ」「昇順」「降順」コマンドは表面的に実装されても「選択範囲の変換」サブメニュー配下になるはずですし、ポップアップメニューやショートカット登録専用の潜在的実装であったとしても、初心者の方からマクロ廃人のお兄様お姉様方まで「あると嬉しい♡」機能だとおもいます。 :)

    ご要望が多ければ検討してみたいと思いますが、多機能化は Mery のコンセプトとは方向性が違ってくるので、なるべくマクロで実現できる方法を考える方向でご協力いただければ幸いです。

    >> 774 さん

    うまく行ったようで良かったです。

    画面の回転の情報、ありがとうございます。私の PC だと記事の参考サイトと同じ方法で行けましたが、グラボのドライバーによって色々ありそうですね。

    聞いた話では、インテルも反省してここ数年の PC はホットキーが効かないように仕様変更されているらしいです。

    > ショートカットキーを設定するダイアログでは[Alt]+矢印キーが効かないので、設定を戻すのに Mery.ini を直接編集する必要がありましたが。

    そうですね、Alt + 矢印は矩形選択に割り当てられているという理由もあって設定ダイアログでキー割り当てができません。

    Ctrl + Alt + 矢印キー に戻すということでしたら、設定ダイアログでキー割り当てを削除して、未割り当ての状態にしてやれば OK ですよ。

    未割り当て状態だとデフォルトで Ctrl + Alt + ↑・↓ が使えますし、縦書きにすると Ctrl + Alt + ←・→ に切り替わる特殊仕様です。

    縦書きは使わないとのことですから、そのままでも問題はないですが ^^;

     |  Kuro  |  返信
  18. ご返信、ありがとうございます。

    > Ctrl + Alt + 矢印キー に戻すということでしたら、設定ダイアログでキー割り当てを削除して、未割り当ての状態にしてやれば OK ですよ。

    なるほど。それで良かったのですね。
    了解しました。ありがとうございました。

     |  774  |  返信
  19. ご回答ありがとうございます。範囲のマージで生じる問題はおおよそ分かりました。

    実のところ私としては、選択範囲を個別操作したいという欲はなく(実現できれば面白そう、程度)、むしろ一括操作を手軽に行うメソッドを拡充するほうに欲がありまして。
    たとえば、GetActivePosList(仮称)でリスト(配列)を返すものはどうだろうかと。で、取得したリストをマクロ言語側(JavaScript など)で加工して、SetActivePosList(仮称)に渡すことでマルチカーソルを置く、と。
    Selection.TextList(仮称)から文字列をリストで取得→マクロ側で加工→代入すると、複数選択の上から順に書き換えていって…と「マルチカーソル貼り付け」ならぬ「マルチカーソル書き換え」ができるかなと。

    > 普段の更新ではマクロの仕様変更はなかなか気が進まないのですが、Ver 3.0.0 でメジャーバージョンが上がりましたし、ここに含めるのもアリかもしれませんね。

    是非お願いします。それから「すべて検索」するフラグも…(Replace メソッドには meReplaceAll があるので合体して meFindReplaceAll を追加するとか)
    [マクロの記録]中に「すべて検索」が記録されなくてアレ?となったので。

    > なるほど、目印をつけるというアイデアは面白いですね。
    > 実は Mery のマルチカーソルもそれと同じような仕組みで、実際にカーソルや選択範囲が複数あるわけではなく、編集予定の箇所に目印をつけているだけなんです。

    思いがけずマルチカーソル実装の裏話が!

    目印をつける方法は当時から苦肉の策(公開するには難点が多い)だったのですが、マルチカーソル実装に伴い「すべて検索」が実装されたので目印を検索して複数選択するという使い方もできるようになりましたし、「設定を記憶しないフラグ」「すべて検索するフラグ」「先頭/終端の扱いフラグ」の3つが実装されれば、かなり応用が効くかもしれません。

     |  masme  |  返信
  20. ご返信ありがとうございます。

    > たとえば、GetActivePosList(仮称)でリスト(配列)を返すものはどうだろうかと。

    これは私も考えたのですが、扱うデータがテキストという連続するデータなので、複数選択の箇所をリストで返すのはあまり有効ではないと思います。

    というのも、例えば GetActivePosList(仮称)を実装した場合、複数の ActivePos がリスト (配列) で返って来るとします。

    var selections = document.selection.GetActivePosList();
    

    リストを取得したあとにその配列の 1 つめの要素 selections[0] のカーソル位置に対して変更を加えた場合、それより後に続く selections[1] 以降が指す位置がすべてズレてしまいます。

    そういうわけで、リストで返すメリットは少なく、リストは必要に応じてユーザーさん側で作成できるようにしておくだけで良いのではないかと思います。

    また、SetActivePosList(仮称)のほうも考えてみますと、例えば SetActivePosList(仮称)を実装した場合、こちらはリストを作成するのはユーザーさん側ということになります。

    var selections = [2, 3, 5, 7, 11];
    document.selection.SetActivePosList(selections);
    

    それはそれで構わないと言えばそうなのですが、これは GetActivePosList で取得した範囲を自由に加工したあとに SetActivePosList するというイメージが前提となっているため、GetActivePosList が有効でないとなると SetActivePosList のようにリストを経由して渡す必要性もなくなってしまいます。

    > Selection.TextList(仮称)から文字列をリストで取得→マクロ側で加工→代入すると、複数選択の上から順に書き換えていって…

    これは私も、このスレッドの返信の中で "[マルチカーソル貼り付け] みたいな挙動ができる document.selection.Text" ということで提案させていただいてますね。

    最初は便利かなーと思ったものですが、この方法には欠点があって、文字列を加工するのが完全にスクリプト側になるため、普通のマクロのように Mery 側の機能を使って文字列を加工することができないんです。

    まぁ、別タブを開いてそこに一時データとして退避してから Mery 側の機能を使って加工して再び戻す、のような方法が考えられないことはないですが… ^^;

    こういった理由を踏まえて、その後、私も考えてみたのですが、

    1) 選択範囲のリストは必要に応じてユーザーさん側で作成できれば良い
    2) 従来どおり Mery 側の機能を使って文字列を加工できれば良い
    3) 既存のマクロをで少ない手順でマルチカーソルに対応できれば良い

    これらの条件を満たす方法としてひとつ面白い案が浮かんだので、ちょっと長いのですが記載させていただきます。

    -
    まず、Ver 3.0.0 ですでに実装されていますが、GetTopPointX, Y と GetBottomPointX, Y は第 2 引数 (省略可能) に 0 以上のインデックスを指定することで複数選択の位置を取得することができます。(以下、コードの書き方が冗長なのは表現のほうを重視しているためなのでご容赦ください)

    var selections = [];
    for (var i = 0; i < document.selection.Count; i++) {
    	selections.push({
    		tx: document.selection.GetTopPointX(mePosLogical, i),
    		ty: document.selection.GetTopPointY(mePosLogical, i),
    		bx: document.selection.GetBottomPointX(mePosLogical, i),
    		by: document.selection.GetBottomPointY(mePosLogical, i)
    	});
    }
    

    さて、ここからが新しい仕様の案ですが、↑の仕様を GetActivePos、GetAnchorPos にも採用します。

    document.selection.GetActivePos([Sel = -1]);
    document.selection.GetAnchorPos([Sel = -1]);
    

    こんな感じで、GetActivePos と GetAnchorPos も省略可能な引数 Sel で 0 以上のインデックスを指定して複数選択の位置を取得できるようにします。

    選択範囲のリストが欲しい場合は以下のようにユーザーさん側で作れますから、条件 1) は満たせます。

    var selections = [];
    for (var i = 0; i < document.selection.Count; i++) {
    	selections.push({ s: document.selection.GetActivePos(i), e: document.selection.GetAnchorPos(i) });
    }
    

    選択範囲の追加はリストを経由するメリットがなさそうなので、以下のように単純な Add メソッドで選択開始と選択終了を指定して追加します。

    document.selection.Add(StartPos, EndPos);
    

    新しく追加する仕様としては上記の 2 点のみです。

    これだけでどうにかなるものか?と思われるかもしれませんが、ここからが面白いところです。

    条件 2) と 3) を解決する方法として以下のようなものを考えました。

    ① まず、GetActivePos と GetAnchorPos で複数選択のリストを作成します
    ② そのリストを上から順に SetActivePos で、「シングルカーソル」で範囲選択します。この段階で複数選択は解除され、通常のマクロ操作が可能となります
    ③ <ここで通常のマクロの機能を使って普通に編集などを行います>
    ④ 処理を行った後の選択範囲をリストに反映し、これをリストの最後まで繰り返します
    ⑤ そのリストを上から順に document.selection.Add(StartPos, EndPos) で複数選択として復元します

    ③ の部分がポイントで、マルチカーソルを意識することなく普通の書き方でマクロを記述することができます。

    これをコードに置き換えると、(書き方が下手なのはご愛嬌ということで…w)

    function doMultiAction(fn) {
    	var d = document, s = d.selection;
    	s.Mode = meModeMulti;
    	// ① まず、GetActivePos と GetAnchorPos で複数選択のリストを作成します
    	var selections = [{ s: s.GetAnchorPos(), e: s.GetActivePos() }];
    	if (s.Count > 0) {
    		selections = [];
    		for (var i = 0; i < s.Count; i++)
    			selections.push({ s: s.GetActivePos(i), e: s.GetAnchorPos(i) });
    	}
    	var p = 0;
    	var q = 0;
    	for (var i = 0; i < selections.length; i++) {
    		// ② そのリストを上から順に SetActivePos で、「シングルカーソル」で範囲選択します。この段階で複数選択は解除され、通常のマクロ操作が可能となります
    		s.SetActivePos(selections[i].s + p);
    		s.SetActivePos(selections[i].e + p, true);
    		q = d.Text.length;
    		// ③ <ここで通常のマクロの機能を使って普通に編集などを行います>
    		fn();
    		p += d.Text.length - q;
    		// ④ 処理を行った後の選択範囲をリストに反映し、これをリストの最後まで繰り返します
    		selections[i] = { s: s.GetAnchorPos(), e: s.GetActivePos() };
    	}
    	// ⑤ そのリストを上から順に document.selection.Add(StartPos, EndPos) で複数選択として復元します
    	for (var i = 0; i < selections.length; i++)
    		s.Add(selections[i].s, selections[i].e);
    }
    

    実際は Mery のバージョンチェックをしたほうが良いですし、q = d.Text.length; の部分でテキスト全体を取得しているのでオーバーヘッドがありますから、この案を採用する場合は document.TextLength のような専用プロパティを設けたほうが良いなどの改善点はありますが、とりあえずそれは置いといて。

    仕様としては GetActivePos、GetAnchorPos の改変と Add を追加しただけですが、fn(); の部分が ③ に該当し、そこの中では完全にシングルカーソルなので従来のマクロがそのまま使えます。

    さらに面白いのが、doMultiAction を別ファイル (doMultiAction.js) にして include するようにすれば、既存のマクロに以下のような 3 行を追加するだけでそれ以外は変更を加えることなくマルチカーソルに対応できる、というところです。

    #include "doMultiAction.js"
    doMultiAction(function() {
    
    // ここは既存のマクロの内容そのまま
    
    });
    

    試しにこのスレッドで話題に上がっていた sukemaru さんの「ひらがな/カタカナ変換」や「カッコで囲う」、MeryWiki にご投稿いただいている yuko さんの「選択範囲を広げる」や、ks さんの「選択範囲を上下に移動」など、いくつかのマクロをまるっと doMultiAction で囲んでみましたが、変更なしでそのまま動作しました。

    この方法だと、ユーザーさんはシングルカーソル・マルチカーソルをあまり意識せずにスクリプトが書けますし、マルチカーソルに対応したい場合にも新たなメソッドを覚える必要もありませんし、おまけにマルチカーソルを使ってもっと複雑なことをしたい場合も自由度が高いと思います。

    ついでに Mery 側の仕様変更も少ないので、後からやっぱりきちんとマルチカーソルを操作できる仕組みが必要だ、となった場合でも影響範囲が少ないというメリットもあります (最後に本心が漏れてるわけではないですが…w)
    -

    > 是非お願いします。それから「すべて検索」するフラグも…(Replace メソッドには meReplaceAll があるので合体して meFindReplaceAll を追加するとか)
    > [マクロの記録]中に「すべて検索」が記録されなくてアレ?となったので。

    はい、私もさっき Find メソッドのフラグの実装をしていて、そういえば「すべて検索」もいるな、と思って追加したところでした (w

    互換性のため meReplaceAll を削除するわけにはいかないので、meReplaceAll は残したまま meFindAll を追加する方向です。

    「設定を記憶しないフラグ」は meFindKeepOptions、「先頭/終端の扱いフラグ」は meFindNotBOL, meFindNotEOL の予定です。

     |  Kuro  |  返信
  21. なるほど。シングルカーソルに分解、ですか。
    マージの問題があり Selection でループを回せないとなると、Selection のメソッドを利用するのは難しいと諦めてしまってましたね、私は。

    > リストを取得したあとにその配列の 1 つめの要素 selections[0] のカーソル位置に対して変更を加えた場合、それより後に続く selections[1] 以降が指す位置がすべてズレてしまいます。

    そうですね。Selection でループを回せずマクロ側で回すのであればズレるのは避けられないので、マクロ側で頑張って補正するほかないかと。その代わり、リストを受け渡しすることで手間を軽減できないかな、と考えたわけです。
    Kuro さんにならってコードで説明すると、私の考えは下記のような感じでした。

    var d = document, s = d.selection;
    // ↓ リストを取得
    var anchorPosList = s.GetAnchorPosList(); // アンカー位置
    var activePosList = s.GetActivePosList(); // カーソル位置
    var textList = s.TextList; // 文字列
    
    var len, topGap = 0, btmGap = 0;
    for (var i=0; i<textList.length; i++) {
      var invertPos = activePosList[i] < anchorPosList[i]; // カーソルがアンカーより前にあるか
      topGap  = btmGap;
      len     = textList[i].length;
      textList[i] = func(textList[i]); // マクロ言語側で文字列を加工
      btmGap += textList[i].length - len;
      if (invertPos) { activePosList[i] += topGap; anchorPosList[i] += btmGap; }
      else           { anchorPosList[i] += topGap; activePosList[i] += btmGap; } // 位置を補正
    }
    // ↓ Mery に渡す
    s.TextList = textList;
    s.SetActivePosList(activePosList);
    s.SetAnchorPosList(anchorPosList);
    

    利点としては、Mery 側のメソッドを呼ぶ回数が少なく、ループ文が一個で済むので速度面で有利になる点。選択範囲を復元する必要がないなら TextList(仮称)だけでできる点があります(でも、復元しないとやはり不便…)。
    欠点はご指摘のとおり、文字列の加工に Mery 側のメソッドを利用できない点。リストを扱う仕様が必要になる点です。

    新メソッド/プロパティを用意するのではなく、引数に数値/文字列を渡したか配列を渡したかで処理を分けたり、選択範囲の数で返り値を変えたり、という仕様も可能かなと思いつきました。(下記のようなコード)
    ただ、Mery 側のメソッドを利用できないのは変わりませんし、型で挙動が変わると混乱を招く懸念もありますね。

    var s = Document.Selection;
    var pos = s.GetActivePos(); // 複数選択時は数値の配列、それ以外は数値を返す
    var text = s.Text; // 複数選択時は文字列の配列、それ以外は文字列を返す
    if (s.Count > 1) {
      // 複数選択時の処理
    } else {
      // それ以外の処理
    }
    s.Text = text; // 配列を渡すとマルチ書き換え、文字列を渡すと従来動作
    s.SetActivePos(pos); // 配列を渡すとマルチ、数値を渡すと従来動作
    

    > ついでに Mery 側の仕様変更も少ないので、後からやっぱりきちんとマルチカーソルを操作できる仕組みが必要だ、となった場合でも影響範囲が少ないというメリットもあります (最後に本心が漏れてるわけではないですが…w)

    下手に仕様変更して後々苦労するのは避けたいですからねw
    そのあたりは Kuro さんの裁量にお任せします。

    > q = d.Text.length; の部分でテキスト全体を取得しているのでオーバーヘッドがあります

    ズレの計算なら Selection.Text.length でもイケそうですが、オーバーヘッドは変わらないですかね?
    と考えたところで Mery 側のメソッドも加工に使えるなら、メソッドによっては選択解除されて加工後の Selection.Text.length が取れない可能性があるわけですね。

    ところで Selection.Count を試していたところ、非選択で 0 は当然として、通常選択(ストリーム)でも 0 になるのは意図したものなのでしょうか。選択範囲の数としては 1 のほうが自然かと思いまして。
    (…いや待てよ、非選択を1個のゼロ幅選択と考えると、非選択が 0 になるほうが特殊なのか…?)

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

    > Kuro さんにならってコードで説明すると、私の考えは下記のような感じでした。

    コードでのご説明、ありがとうございます。

    そうですね。私が貼ったコードでも 1 度リストにしているのでギャップ調整 (位置の補正) を行っていますが、リストを使う以上、この工程は必須ですね。

    > 利点としては、Mery 側のメソッドを呼ぶ回数が少なく、ループ文が一個で済むので速度面で有利になる点。選択範囲を復元する必要がないなら TextList(仮称)だけでできる点があります(でも、復元しないとやはり不便…)。

    確かに、ユーザーさん側からすると TextList を渡す 1 度の操作で複数箇所が同時に書き換えられるように見えますから速度的に有利だと感じるかもしれません。

    これは先日すこし触れた Mery のマルチカーソルの実装の裏話と関連しますが、たとえ TextList というかたちで一括で Mery 側に投げたとしても、テキストデータという性質上、すべての選択箇所を同時に書き換えられるわけではなく、Mery の内部では上から順番にシングルカーソルで処理、つまり masme さんが貼ってくださったコードと同じこと (複数選択のリストを回して部分文字列を書き換えてギャップを調整して…) をしなければならないので、結果的に同じことを 2 度やっているかたちになってしまいます。

    先日私が貼った doMultiAction でも、ループを回してギャップ調整、といった感じで似たようなことをしていますが、これは Mery 側に投げていないので、リストを回して文字列の加工とギャップ調整という一連の処理が 1 度だけ済みます。

    > 新メソッド/プロパティを用意するのではなく、引数に数値/文字列を渡したか配列を渡したかで処理を分けたり、選択範囲の数で返り値を変えたり、という仕様も可能かなと思いつきました。(下記のようなコード)
    > ただ、Mery 側のメソッドを利用できないのは変わりませんし、型で挙動が変わると混乱を招く懸念もありますね。

    面白い案だと思いますが、ActiveScript (JavaScript、VBScript など) の変数はバリアント型 (平たく言うと、型がなくて必要に応じて自動的に型が選択される感じ) で、型を意識せずプログラミングができるというメリットと、型があやふやというデメリットがありますが、そこに敢えて型指定で挙動を変えるメソッドを使わせることはユーザーさんに少し迷惑がかかりそうに思います… ^^;

    > ズレの計算なら Selection.Text.length でもイケそうですが、オーバーヘッドは変わらないですかね?
    > と考えたところで Mery 側のメソッドも加工に使えるなら、メソッドによっては選択解除されて加工後の Selection.Text.length が取れない可能性があるわけですね。

    そうなんですよね。マクロを書く側が変換後の選択範囲をきちんと返してくれる前提なら selection.Text.length のほうがオーバーヘッドが少なくて良いと思います。

    > ところで Selection.Count を試していたところ、非選択で 0 は当然として、通常選択(ストリーム)でも 0 になるのは意図したものなのでしょうか。選択範囲の数としては 1 のほうが自然かと思いまして。
    > (…いや待てよ、非選択を1個のゼロ幅選択と考えると、非選択が 0 になるほうが特殊なのか…?)

    はい、これは意図的にそうしています。

    プロパティの名前からすると若干分かりづらいかもしれませんが、複数選択をループでどうのこうのする場合を考えると通常選択と複数選択の数を混ぜないほうが扱いやすいと思います。

    複数選択の仕組みがなかなかつかみづらいと思いますが、複数選択は、通常選択が複数あるわけではありません。

    イメージとしては通常選択と複数選択は同列ではなく、「通常選択」の上にもう 1 つ「複数選択」という別のレイヤーがある感じを想像していただけると分かりやすいかと思います。

    つまり、通常選択と複数選択は同時に存在できるわけで、複数選択というのは複数の選択箇所に目印をつけておくための機能というわけです。

    編集するときはその目印に従って上から順番に、いわゆるバッチ処理を行う感じですね。

    そういうわけで、selection.Count は選択範囲の数ではなく、複数選択の数を返すプロパティなので、通常選択はカウントしないようにしています。

     |  Kuro  |  返信
  23. Kuro さん

    Ver.3.0.1 公開お疲れさまでした。

    マルチカーソルの対応がいい感じに出来ると聞きつけ、「選択範囲を広げる」マクロで早速試してみました。(& wiki にその対応版も追記しました)

    本スレッドの doMultiAction(fn) に

    ・document.selection.Add(e, s) を document.selection.AddPos(e, s) に変更
    ・document.Text.length を document.TextLength に変更

    の修正を加え、当該マクロに組み込みました。
    無事、いい感じに動いていて感動しました~!

    ところで、document.selection.Count もたぶん今回の新機能なのかなと思っているのですが、3.0.1 の更新履歴に載っていなかったので、記載漏れかもです。

     |  yuko  |  返信
  24. Mery 3.0.1 リリースお疲れ様です。

    Ver 3.0.1 で「透明」から「カスタム」に切り替えたときのケースで入力した値が反映されているのを確認しました。

    しかし、「作成した色」のまだ作成していないパレットをクリックしたときのケースでは修正されていないようです。

     |  ucky  |  返信
  25. >> yuko さん

    早速、お試しいただきありがとうございます。

    > マルチカーソルの対応がいい感じに出来ると聞きつけ、「選択範囲を広げる」マクロで早速試してみました。(& wiki にその対応版も追記しました)
    > 無事、いい感じに動いていて感動しました~!

    ワーイ!しかし、このスレッドに貼り付けた doMultiAction.js はただの例なのでまだ実験段階ですし、実践投入は早すぎますっ(w

    でも、たぶん「選択範囲を広げる」マクロであれば、この doMultiAction.js でも大丈夫な気はします。

    今のところ分かっている問題点としては、fn(); の中で選択範囲を変更してから書き換えを行うようなマクロだとうまく動かない場合があります。

    一応、私の手元の doMultiAction.js は Mery のバージョンチェックや Undo のグループ化などが実装済みでもう少しマシなものとなっていますが、上記の問題はまだ解決できていません。

    別のスレッドのほうで、そういった問題への対策が施された doMultiAction (改) をご提案いただいてます。
    https://www.haijin-boys.com/discussions/5295#discussion-5317

    まだ Ver 3.0.1 のリリース前の段階だったので、ご提案いただいたコードがそのまま Ver 3.0.1 で動くわけではありませんが、原理としては選択範囲の変更と書き換えも考慮されたものとなっており、マルチカーソルの夢が広がります。

    > ところで、document.selection.Count もたぶん今回の新機能なのかなと思っているのですが、3.0.1 の更新履歴に載っていなかったので、記載漏れかもです。

    ご指摘ありがとうございます。

    これは Ver 3.0.0 ですでに実装済みなので Ver 3.0.1 の記載漏れというわけではないのですが、どこかに記載しておいたほうが良さそうですね。

    他にもいくつか Ver 3.0.0 で実装済みのものがありますが、その時点ではまだマクロ仕様の方向性が見えなかったので、中途半端な情報を出してユーザーさんを混乱させないよう、あえて記載せず表向きは「マルチカーソルはマクロ未対応」としていました。

    フォーラムでマクロの仕様を検討させていただける機会があれば、「実はこんなのあるけどどうでしょう?」とこっそり公開するつもりだったのですが、Ver 3.0.0 の機能のみで既存のマクロのマルチカーソル化を始めらるかたもいらっしゃって、これはやばいと思い、急遽、試験的にマクロ仕様を追加した Ver 3.0.1 をリリースしたというわけです。

    以上、document.selection.Count がどこにも記載されていない言い訳でした (長っw

    >> ucky さん

    ご確認いただきありがとうございます。

    > Ver 3.0.1 で「透明」から「カスタム」に切り替えたときのケースで入力した値が反映されているのを確認しました。

    直っているようで安心しました。

    > しかし、「作成した色」のまだ作成していないパレットをクリックしたときのケースでは修正されていないようです。

    ご報告ありがとうございます。

    [色の選択] ダイアログは私が開発したものではなく Windows の色選択機能 (ChooseColor) を呼び出しているだけなので、ご指摘のケースにおいて発生するのは Windows の仕様な可能性が高く、今のところ有効な対策が見つかっていません。

    技術的な話で恐縮ですが、一応、ChooseColor のフラグに CC_SOLIDCOLOR を渡してやると改善されるっぽいのですが、このフラグの意味については情報が少なく、選択できる色が 256 色になるとか書かれているところもあるので、今回は対策を見送りました。

    調査のほうは引き続き行いますが、修正は対策が見つかり次第とさせていただければと思います。

    ちなみに、他のソフトやエディターも確認してみたのですが、Windows の色選択機を使っているものは未作成の色をクリックするとこの現象が発生するようです。

    TeraP〇d さんは未対策、秀〇さんは自前の色選択ダイアログ、サク〇エディターさんは未作成の色は白で埋めてましたが、もしかして白で埋めるのが正解…!?

     |  Kuro  |  返信
  26. 自分の使っているソフトでも少し調べてみました。

    Firefox や Chrome の <input type="color"> で出てくるダイアログは黒、WinMerge は白で埋めてました。

    あまりソフト名を挙げるのもアレなので割愛しますが、黒か白で埋めてるソフトが多く、自分が使用しているソフトでは黒で埋めてるものが多く感じました。

     |  ucky  |  返信
  27. ユーザー側でできる対策を考えてみました。

    Mery.ini の [Display] セクションの CustomColors の ColorA〜ColorP の値が、正常に追加されたものは六桁です。黒扱いになってるものは八桁になっているので、先頭の FF を削除して六桁に変更します。

    これで、黒扱いになってるものは数値が反映された色になります。結果的に未作成の色は白になります。

    素人考えで恐縮ですが、未作成の色は元々アルファチャンネル付きの白だと思うので、白で埋めるのが正解かもしれません。

    解決策につながるか分かりませんが、上記の対策を確認しているときに、未作成の色の不思議な挙動を発見しました。

    [色の選択] ダイアログで未作成の色をクリックし、緑に 0 を入力します。その後、赤に 1〜19 を入力すると「色 | 純色」が黒ではなくなるのですが、実際の数値とかなり異なった色になります。

    赤:1 緑:0 青:255 は maroon
    赤:2 緑:0 青:255 は green
    赤:3 緑:0 青:255 は olive

    といった具合に赤が 1 違うだけで大幅に色が変わります。

     |  ucky  |  返信
  28. 情報ありがとうございます。

    うーん、謎ですね。確かに、(赤, 緑, 青) が (1, 0, 0) とか (2, 0, 0) だと Windows の標準色?みたいな 16 色が選択できますね。昔の Windows の名残か互換性維持のためなのかわかりませんが…。

    > 素人考えで恐縮ですが、未作成の色は元々アルファチャンネル付きの白だと思うので、白で埋めるのが正解かもしれません。

    そうですね。まったく情報が見つからないので、Mery 側でできそうなことといえば、未作成の色は白か黒で埋めることぐらいになりそうです。

    > 黒扱いになってるものは八桁になっているので、先頭の FF を削除して六桁に変更します。

    8 桁になってしまった状態 (FFFFFFFF 以外) でパレットを保存されてしまってるかたもいるかもしれませんが、ちょっとそのケースに対応するのは難しそうです。

    次のバージョンで完全に INI 設定を別の名前に仕様変更して、一度すべてパレットを初期化してしまえば綺麗になりそうですが、さすがにそれも怒られそうなので…。

    やるとしたら、すでに INI に保存されてしまっている色 FFFFFFFF を 000000 に強制的に置き換える対策と、初めて Mery を起動する人 (INI なし) の初期値を FFFFFF (白) にする対策、になりそうです。

    FF808080 とか、中途半端な値になって保存されてしまってるかたもいるかもしれませんが、そのときはお問い合わせがあったら個別に対応させていただくかたちとさせていただければと思います。

     |  Kuro  |  返信
  29. Mery 3.0.2 リリースお疲れ様です。

    > やるとしたら、すでに INI に保存されてしまっている色 FFFFFFFF を 000000 に強制的に置き換える対策と、初めて Mery を起動する人 (INI なし) の初期値を FFFFFF (白) にする対策、になりそうです。

    Ver 3.0.2 にて、上書き時の未作成の色(黒)と新規 INI での未作成の色(白)で入力した値が反映されることを確認しました。

    対策していただき、ありがとうございました。

     |  ucky  |  返信
  30. ご確認ありがとうございます。

    > Ver 3.0.2 にて、上書き時の未作成の色(黒)と新規 INI での未作成の色(白)で入力した値が反映されることを確認しました。

    すでに INI が出来てしまってるかたは、違和感をなるべく抑えるため黒に。

    はじめて Mery を使われるかたは白に、ということで対策をしてみました。

    根本的な問題は解決できていないので、INI ファイルの値を直接変更されたり、すでに FF 始まりの 8 桁 (FFFFFFFF 以外) になってたりする場合は効果が現れませんが、そこはご容赦いただければと思います ^^;

     |  Kuro  |  返信
  31. > 黒扱いになってるものは八桁になっているので、先頭の FF を削除して六桁に変更します。
    [Display] セクションの CustomColors=ColorA= ... ColorP=000000 がカスタムパレットだったんですね。
    保存済みなのに黒枠になっているパレットは八桁になっていましたので、Mery.ini の直接編集で六桁に直したら保存済みのパレットの枠が正しい色で表示されるようになりました。 :)

    選択範囲(複数選択)に通常選択と別色を指定できることも別件で教わるまで気付きもしませんでしたが、なんかマルチカーソルを色々便利に使えるようになれそうで素敵なかんじです。

    … マルチカーソルへの自作マクロの対応についてはまだ全然着手していないのですが、私のマクロのばあいはブックマークの取得/復元処理を入れていますので、選択範囲ひとつひとつの編集ごとにブックマーク関係の処理をさせないで済むようにしたほうがいいのかどうか。
    そろそろ着手せねばとおもっているのですが、AddUndo() メソッドは便利そうでいて使いどころがむずかしいなとか、Googleで検索コマンドが選択範囲なしでも使えるようになってるなとか、余計なところばかり突いて逃避しているこのごろです。 :|

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