マルチカーソル実装によるマクロなどへの影響

  1. 個人的にマルチカーソルの実装は難しいのではと考えていたため、Twitter 上の開発画面にはおみそれいたしました。バージョンアップが楽しみです。

    さて、マルチカーソルはマクロとの相性もあり初期無効とする予定だそうですが、有効にした場合マクロにどのような影響がありそうでしょうか?
    特に、複数選択時に「Selection.Text = 文字列」などで選択文字列を書き換えたときの挙動が気になるところです。
    複数選択は選択箇所すべてを書き換え、矩形範囲があれば表示行単位で書き換えという挙動だと対応しやすいかなぁと考えているのですが…。

     |  masme  |  返信
  2. Twitter 見ていただきありがとうございます。

    そうなんですよね…。ノリと勢いでマルチカーソルの開発を始めてしまったものの、開発の難易度が予想以上に高くて苦戦しました。

    一応、何事もなければ今週末のリリースを予定しています。

    > さて、マルチカーソルはマクロとの相性もあり初期無効とする予定だそうですが、有効にした場合マクロにどのような影響がありそうでしょうか?

    当初はデフォルト無効にしようと思っていたのですが、最近の MS Word とかも普通に複数選択に対応しているようなので、デフォルト有効で行くことにしました。

    マクロへの影響ですが、カーソルを複数配置している状態や、選択範囲が複数ある状態でマクロを実行すると影響があります。

    また、マルチカーソルが有効でも、カーソルを複数配置していない状態や、選択範囲が一つの状態なら従来どおり動作します。

    > 特に、複数選択時に「Selection.Text = 文字列」などで選択文字列を書き換えたときの挙動が気になるところです。

    document.selection.Text = ""; などの文字列編集や、document.selection.CharRight(); などのカーソル移動はそれぞれのカーソルに対して動作します。

    document.selection.SetActivePos(0, true); などのカーソル位置を絶対値で指定するメソッドはマルチカーソルを解除して移動します。

    あとは、複数選択の状態で var s = document.selection.Text; で文字列を取得すると、すべての選択範囲の文字列が改行区切りで返ります。

    このあたりの仕様はマクロを書く人からすると賛否両論ありそうですが、マクロの記録・実行を使う場合は基本的な操作がマルチカーソルに対しても有効です。

    ちなみに、document.selections のような複数形のプロパティを用意して、それぞれのselectionに対して操作できるようにするというのも考えたのですが、選択範囲が重複する場合はマージされる仕様なのでselectionsの数が保証されないため実用的ではなかったり…。

    マルチカーソルに対応している海外製のコードエディターでもマクロやエクステンションはマルチカーソルが考慮されていないものが多いようなので、仕組み的にも仕方ないのかなーとも思っています。

    > 複数選択は選択箇所すべてを書き換え、矩形範囲があれば表示行単位で書き換えという挙動だと対応しやすいかなぁと考えているのですが…。

    複数選択は選択箇所をすべて書き換え、矩形選択の場合は論理行単位ですが選択範囲に含まれる行をすべて書き換えという仕様です。

    でも、これで決定というわけではなく試行錯誤の段階ですね。とりあえずリリースしてみてから怒られようかと… (w

     |  Kuro  |  返信
  3. 横から便乗で失礼します。

    そもそも「選択範囲の変換」系の標準コマンドや「ブックマークを設定/解除」などとの絡みもあるわけですから、なんかものすごくたいへんな機能ですよね。 :)
    ほかのエディタのマルチカーソル機能を知らないため、まったく想像が付きません。
    個人的には、「行頭コメントアウト」や「インデント」などのような、複数行の選択範囲を自動的に行単位へ拡張してから編集操作をするマクロとの相性が気になっています。

    マクロ用に「複数選択状態を取得できるプロパティ」もご用意いただけるとよいのですが、いかがでしょうか…?
    e.g. Selection.IsMultiple プロパティとして

    var multi = Document.Selection.IsMultiple;

    みたいなかんじで、 IsEmpty プロパティと同じように。

    もし Selection.IsMutiple のようなプロパティが利用できれば、たとえば「行コメント」マクロでは選択範囲が複数のときには範囲拡張した各行頭にたいしてではなく、各選択範囲の先頭に任意の文字列を挿入(または置換削除)するための Prompt() を表示させるような条件分岐ができそうですよね。

    さすがに「行を複製(複数行可)」や「行を上下に移動」マクロなどは対応させるのはややこしそう。 複数の選択範囲の各開始/終了位置や XY を取得するプロパティなんていうのは、さすがにナシのようですね(あったとしても、コーディングしたくないですし)。
    むしろ、その辺のマクロは「作ったのがマルチカーソル機能のない時代でよかった~」とホッとするべき、ということになる気がします。 :D
    でも、「マルチカーソルモードの有効/無効」が Mery.ini から読みこめないと、現状だと予期せぬ挙動みたいになりそうで怖いですが、Undo 1回で元に戻せますよね。

    「選択範囲の始点終点を交替」マクロや「文字数カウント」系のマクロ、「カッコで囲う」、「引用符を追加/削除」マクロなどもどうなるのかしら…? 昨年は「位置情報を保存してから『すべて選択/選択解除』(非スクロール) 」や「位置を復帰/保存」なんていうマクロもつくりましたが、それらもどうなることやら、楽しみです。 :?

    あ、ゼロ幅選択状態のとき Selection.IsEmpty プロパティの戻り値ってどうなるんでしょう?
    興味は尽きないというかんじですね。 X)

    > Kuro さん
    ご回答は「気が向いたら検討するので黙って待ってろ」でけっこうです。はい。

     |  sukemaru  |  返信
  4. スレッドの主旨とは関係ないのですが、
    > 最近の MS Word とかも普通に複数選択に対応しているようなので
    これ、知らなかったです…。Word も進化してるんですね…(昔からあった?^^;)

     |  yuko  |  返信
  5. > Selection.IsMutiple

    実際の名称は Kuro さんにお任せするとして、確かにマルチカーソル発動中かどうかを判別する手段があると、マクロ側で回避策を盛り込める可能性があるのでいいですね。

     |  yuko  |  返信
  6. >> sukemaru さん

    > そもそも「選択範囲の変換」系の標準コマンドや「ブックマークを設定/解除」などとの絡みもあるわけですから、なんかものすごくたいへんな機能ですよね。 :)

    そうですねー、すべての機能がマルチカーソルに対応しているわけではないのでその点はあらかじめご了承ください。一応、ブックマーク機能は対応しています。

    マクロから複数選択かどうかを判定するプロパティは用意しています。

    document.selection.Mode

    定数は以下です。

    meModeStream
    meModeBox
    meModeMulti

    ストリーム選択、矩形選択、複数選択を取得・設定できます。(通常の選択のことをストリーム選択というらしいです。MS のサイトにそう表記されていたので準拠しました)

    とりあえず document.selection.Mode = meModeStream; をマクロの最初に書いておけば、複数選択が解除 (最後に追加した選択範囲のみ選択状態となる) されますので、マクロは従来どおり動作すると思います。

    また、選択範囲の数を取得するプロパティも用意しています。

    document.selection.Count

    複数選択がある場合は 1 以上の値が返ります。通常選択の場合は 0 が返ります。

    数が取得できたからと言ってそれぞれの選択範囲に対して操作ができるわけではないのであまり意味はないんですけどね (w

    > あ、ゼロ幅選択状態のとき Selection.IsEmpty プロパティの戻り値ってどうなるんでしょう?

    selection.IsEmpty は複数選択の場合、すべての選択範囲がゼロ幅なら true が返ります。

    >> yuko さん

    > > 最近の MS Word とかも普通に複数選択に対応しているようなので
    > これ、知らなかったです…。Word も進化してるんですね…(昔からあった?^^;)

    昔はなかったような気もしますが、Word 2019 だと Ctrl を押しながら選択すれば複数選択になりますね。ただ、一括で編集ができるわけではなく、文字色や背景色を一括で変更できるだけのようですが… (w

     |  Kuro  |  返信
  7. ご返信いただき、ありがとうございました。 :)

    > マクロから複数選択かどうかを判定するプロパティは用意しています。
    > …

    > とりあえず document.selection.Mode = meModeStream; をマクロの最初に書いておけば、複数選択が解除 (最後に追加した選択範囲のみ選択状態となる) されますので、マクロは従来どおり動作すると思います。
    > …

    条件分岐や回避処理などの方向性が見えたかんじですが、あとは私自身が投稿済みのマクロでマルチカーソルによる影響を受けるものすべてにおいて対応できるかどうかですね…。 :|

    文字列編集処理の前に「選択範囲のサイズを変更」したり、「ブックマーク状態の検索処理」などでマクロ実行前の選択範囲をいったんキャンセルしているものなどありますから、もっぱら
    > document.selection.Mode = meModeStream; をマクロの最初に書いて …
    これに頼ることになりそうです。
    (拙作の「ニッチなマクロ」を利用している人は少ないでしょうから、「利用者ご自身で対処してください」というわけには…?)

    関与しているマクロライブラリ内のページ数が 50 ぐらいで、いくつかのページには複数のコードを投稿していますので、まずは変更の要否の切り分け作業からでしょうね。
    もしかして、『小マクロ集』所収の「メニュー項目をアイコン化する小マクロ(標準コマンドのマクロ化)」まで対処が必要だったりすると、詰みそう? X(
    ref.
    https://www.haijin-boys.com/wiki/利用者:Sukemaru
    https://www.haijin-boys.com/wiki/マテリアルデザインっぽいアイコンと『小マクロ集』#目次
    OMG... 「桑原くわばら」とすっとぼけるわけには … いかないっぽいですよね。

     |  sukemaru  |  返信
  8. > document.selections のような複数形のプロパティを用意して、それぞれのselectionに対して操作できるようにするというのも考えたのですが、選択範囲が重複する場合はマージされる仕様なのでselectionsの数が保証されないため実用的ではなかったり…。
    なるほど、複数選択ができると重複の問題がありましたか。個人的には、Selection の列挙順がどうなるか(ソートが不要な「選択した順」か、ソートが必要な「上/下から順」か)を考えていました。

    > マルチカーソルに対応している海外製のコードエディターでもマクロやエクステンションはマルチカーソルが考慮されていないものが多いようなので、仕組み的にも仕方ないのかなーとも思っています。
    マルチカーソルは国産では Em や秀丸が対応されていますが(流石は有償)、マクロについてはどうなんでしょう…。

    > document.selection.Mode
    > meModeBox
    矩形選択の判定・対処が割と辛かったので、これはありがたい…。

    > 複数選択の状態で var s = document.selection.Text; で文字列を取得すると、すべての選択範囲の文字列が改行区切りで返ります。
    > selection.IsEmpty は複数選択の場合、すべての選択範囲がゼロ幅なら true が返ります。
    従来のゼロ幅矩形選択だと、Selection.Text は選択行数分の改行が返り、Selection.IsEmpty は false になるので、ここは仕様変更点ですかね(Selection.Mode で分岐が書けるので対処は楽ですが)。

    > これで決定というわけではなく試行錯誤の段階ですね。とりあえずリリースしてみてから怒られようかと… (w
    やはり実際に触ってみないと何とも言えないところがありますよね。カーソル移動や範囲選択はエディタの基本操作ですから影響範囲が大きいですし。

    ここまでの話から要望が1点浮かんだのですが、リリースが近いようですし、まずは触ってみてからですかね。

     |  masme  |  返信
  9. > なるほど、複数選択ができると重複の問題がありましたか。個人的には、Selection の列挙順がどうなるか(ソートが不要な「選択した順」か、ソートが必要な「上/下から順」か)を考えていました。

    そうなんですよね。他のエディターの実装がどうなっているのかはわかりませんが、Mery ではソートが必要な「上から下」で管理しています。

    複数箇所を編集するときは上から下に向かって変更を反映させたほうが整合性が取りやすく動作速度も速いですし、描画においても画面外の選択範囲までチェックすることなくリストの走査を打ち切れますからね。

    とは言え、それだけでは実装できない機能もあるので「選択した順」も情報としては持っていますから、必要があれば選択した順のリストを返すことも可能です。

    > マルチカーソルは国産では Em や秀丸が対応されていますが(流石は有償)、マクロについてはどうなんでしょう…。

    うーん、どちらのエディターもマクロの仕様はマルチカーソルを考慮していないように見えますね。

    複数の選択箇所に反映されるメソッドもありますが、マルチカーソルを解除して動作するメソッドも混在している状態で、マルチカーソルを明示的に操作できる機能は用意されていないようです。

    > 従来のゼロ幅矩形選択だと、Selection.Text は選択行数分の改行が返り、Selection.IsEmpty は false になるので、ここは仕様変更点ですかね(Selection.Mode で分岐が書けるので対処は楽ですが)。

    仕様変更と言えばそうかもしれませんが、従来、ゼロ幅で、目には見えない矩形選択になっていたのはバグですね。その状態で文字を入力すると行頭に文字が挿入されちゃったりしていました。

    この問題は修正され、ゼロ幅の矩形選択もきちんと見えるようになります。

    矩形選択における selection.Text や selection.IsEmpty の仕様は従来どおりで変更はありません。

    > ここまでの話から要望が1点浮かんだのですが、リリースが近いようですし、まずは触ってみてからですかね。

    週末にリリースと申しましたが開発が間に合いませんでした…。楽しみにしていただいているのに申し訳ございません。

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