ペインごとのカーソル位置と保存判定

  1. Ver.3.1.0で確認しました

    カーソル位置がずれる
    両方のペインで発生します
    再現方法
    1.ペインAはn行目にカーソルを置く
    2.ペインBはn+1行目以降にカーソルを置く
    3.ペインAで文字を入力する
    4.ペインBのカーソルが、入力した文字数分手前にずれる
    文字を削除した場合はずれないようです
    ただし、IMEで確定していない文字を削除した場合は、その分ズレます

    保存判定がおかしい
    下(右)ペインで編集した場合、上(左)ペインに戻った時に
    「外部でファイルが変更されています。再読込しますか?」
    が出ることがある
    100%再現できる方法が見つかりませんでした
    Ver.3.0.4では一度も発生した記憶がありません

     |  かずら  |  返信
  2. ご確認ありがとうございます。

    > カーソル位置がずれる

    別窓でそれぞれカーソル位置を同期するのは結構重いので、文字入力の場合は選択範囲がある場合のみ同期するように制限をかけていたのですが、やはり気になりますよね。

    > 保存判定がおかしい

    こちらは現象を再現することができませんでした。再現手順がわかりましたら教えていただけますと、改めて調査してみたいと思います。

     |  Kuro  |  返信
  3. > > カーソル位置がずれる
    >
    > 別窓でそれぞれカーソル位置を同期するのは結構重いので、文字入力の場合は選択範囲がある場合のみ同期するように制限をかけていたのですが、やはり気になりますよね。

    [a|bc、ab|c] =別ペインで"b"削除=> a|c =巻戻し=> a|bcかab|c どちらに巻き戻せば正しいのか判断できない。
    範囲 a|>b|c ="b"削除=> a|c でも同じことが言える。
    これらを正しく巻き戻すには削除したときにキャレット・範囲が変化したという記録も履歴に含める必要がありそう。

    しかし、画面分割、別ペインが必要とされてる点は編集地点から離れた位置の参照や
    ちょっとした修正のためが大体で、近地点の編集のためというのは少ないと思う。
    別ペインの範囲を維持したまま、同範囲を編集したいというようなのはまた別の機能では?

    なので別ペインの編集による範囲の維持はしなくても問題が少ないように思います。
    それよりはキャレット(カーソル)のズレがない方がメリットかと。
    なので
    キャレット(非範囲選択)への影響
    ・削除:deltop < caret, shiftnum = min(|dellen|, caret-deltop) * -1;
    ・追加:addtop <= caret, shiftnum = addlen;
    範囲選択[rngtop,rngbtm)への影響
    ・追加->範囲終端rngbtmのみ:addtop < rngbtm, shiftnum = addlen;
    ・他はキャレットと同じ。
    という逐次処理だけで済まないでしょうか。
    キャレットや範囲が編集地点と十分に離れていれば(上の例なら"a"の削除)、復元でもズレに対するシフトだけで済むので。

    上記は矩形(Box)選択はbeg,endの形なのかbeg,wid,hgtの形で保持してるのか推測できないし
    計算が難しそうなので考慮してませんが。

    あとMeryがどのようなカーソル情報を保持してるのか分からない。
    カーソル前方を削除した場合は正しく保持されて、前方に向かいシフトされるが
    カーソル前方に追加した場合は保持されずに後方にシフトせず、その場に留まる。
    IMEオンで入力追加すると更に前方にシフトしてくるので、なんらかのカーソルシフトは行っている?

    しかし自分はF6:次のペインへの移動を使用していない!!!今回の追加機能を見るためにしか!
    自分の中のメリットとしては別ペインで参照してる部分を範囲選択しといて目に留めやすくしとくくらい。
    大量の改行を追加した後、後方参照してるのが画面から流れてしまってもスクロールして見つけやすい?かも?

     |  MM  |  返信
  4. コメントありがとうございます。

    > [a|bc、ab|c] =別ペインで"b"削除=> a|c =巻戻し=> a|bcかab|c どちらに巻き戻せば正しいのか判断できない。

    そうなんですよね。選択範囲の履歴も取るようにすれば技術的には可能なのかもしれませんが、これが実現できているエディターは Sublime Text ぐらいだと思います。

    > 別ペインの範囲を維持したまま、同範囲を編集したいというようなのはまた別の機能では?

    確かに、従来のウィンドウ分割の機能を流用する方向で考えていくと壁に当たってしまいますので、別機能としてゼロから開発するべきものなのかもしれません。

    > それよりはキャレット(カーソル)のズレがない方がメリットかと。

    まさに、問題はそこなんですよね。

    秀〇エディタさん、E〇Editor さん、サク〇エディタさんでもキャレットの同期はできていないので仕方ないかなと思って Mery でも妥協してしまった部分ですが、動作速度的に実用レベルになれば対応したいとは考えています。

    > 逐次処理だけで済まないでしょうか。

    そうですねー、技術的な話になってしまいますが…

    単純なテキストファイルでキャレット位置が、ファイルの先頭からの位置のみを保持している場合はそれで問題ないと思いますが、テキストエディターの場合はそうもいかなくて。

    例えばキャレット位置の桁をルーラー上に表示したり、キャレット位置の行を強調表示したりする必要があるので先頭からの位置以外にも、キャレット位置の行と列 (X と Y 座標) も常に再計算が必要なんです。

    この座標計算は編集が発生した箇所を基準にしてなるべく少ない計算で済むように工夫はしていますが、それでも負荷は無視できないレベルです。(マルチカーソルを使うとさらに負荷は数倍になります)

    この負荷が、別窓を開いているだけで、選択範囲もない状態なのに文字を入力・削除するたびに必ず発生することになるわけなので、そんなに必要とされていない機能であれば、同期しないほうが快適なのになぁと思う感じですね。

    > しかし自分はF6:次のペインへの移動を使用していない!!!今回の追加機能を見るためにしか!

    私もです ^^; どのエディターでもマウスでペイン移動すると、選択範囲やカーソル位置は解除されてしまいますね。

    > 大量の改行を追加した後、後方参照してるのが画面から流れてしまってもスクロールして見つけやすい?かも?

    なるほど。そもそもウィンドウ分割の機能自体を使っていなかったので参考にさせていただきたいと思います。

     |  Kuro  |  返信
  5. > 例えばキャレット位置の桁をルーラー上に表示したり、キャレット位置の行を強調表示したりする必要があるので先頭からの位置以外にも、キャレット位置の行と列 (X と Y 座標) も常に再計算が必要なんです。

    そうですよねー、単純にしか考えられないから色々見逃してしまいます。
    例えば改行ストリームも自動折り返し機能が付くと中で更にサブストリームを用意すればいいのか?と混乱して、こういうのも実際に作ってない自分だとどうXY描画座標(2次元)を算出すればいいか、ストリームを表す1次元座標範囲の生成タイミングとか再計算フローとか思いつかないですし。

    > この座標計算は編集が発生した箇所を基準にしてなるべく少ない計算で済むように工夫はしていますが、それでも負荷は無視できないレベルです。(マルチカーソルを使うとさらに負荷は数倍になります)
    >
    > この負荷が、別窓を開いているだけで、選択範囲もない状態なのに文字を入力・削除するたびに必ず発生することになるわけなので、そんなに必要とされていない機能であれば、同期しないほうが快適なのになぁと思う感じですね。

    別窓なんだから描画放棄して、もういっそタスクとしてスタックできてタイマーとかカーソル移動とか限定した操作タイミングまで描画系計算だけでもほっとければいいんでしょうけどね、そんなふわっとしたこと言ってもしょうがない。
    シンプルエディタは応答性がなんぼですしね。いやー想像するのも難しいw頭が上がりませんorz

     |  MM  |  返信
  6. > 別窓なんだから描画放棄して、もういっそタスクとしてスタックできてタイマーとかカーソル移動とか限定した操作タイミングまで描画系計算だけでもほっとければいいんでしょうけどね、そんなふわっとしたこと言ってもしょうがない。

    理にかなっていると思います。

    秀〇エディタさんはまさにその方式を採用されているようで、別窓のリアルタイム描画は放棄していて、フォーカスが別窓に移ったタイミングで再描画される感じになってますね。

    テキストエディターという性質上、動作速度を最優先したいという気持ちはありつつも、負荷にならない範囲でコードエディターのように重い機能をいかに軽く実装できるかという興味もありますので、どこまできっちり実装するかは難しいところですね。

     |  Kuro  |  返信
  7. > > 保存判定がおかしい
    > こちらは現象を再現することができませんでした。再現手順がわかりましたら教えていただけますと、改めて調査してみたいと思います。

    保存後、編集していないのに読み直しダイアログが出たので、ファイルを確認してみました。
    すると、ファイルの更新日時よりアクセス日時が新しかった場合に、読み直し判定が出ているんだと思います。
    うちの環境はBGでクラウド同期を行っているから発生したんだと思います。
    ただ、以前のバージョンでは出た例しがないので、謎です。

     |  かずら  |  返信
  8. ご報告ありがとうございます。

    うーん、謎ですね。強制的にファイルのアクセス日時のみ更新してみても、再現されませんでした。

    そもそもファイルのアクセス日時は Vista 以前ですとファイルを開くだけでも更新されていましたから、もしアクセス日時のみで判定がされていた場合は検証段階で気づくと思いますし…。

    ちなみに PowerShell でのアクセス日時のみ更新コマンドは以下のとおりです。

    Set-ItemProperty C:\Temp\Mery.txt -name LastAccessTime -value $(Get-Date)
    

    > ただ、以前のバージョンでは出た例しがないので、謎です。

    ファイルの更新日時チェックにおける処理は以前のバージョンから変更していません。

    クラウド同期をご利用とのことですので、何らかのタイミングで同期が走ってファイルの更新日時が一時的に新しいものになり、その後、同期が完了して更新日時が元に戻るといった動作は考えられますね。

    たとえば、Mery で [上書き保存] を実行し、その後、普通にテキスト編集をしているつもりでも、裏ではクラウド同期が走っています。

    回線の速度によってはクラウド同期に数分かかった場合など、同期が完了してからローカルに保存してあるファイルの更新日時がアップデートされるまでにタイムラグが発生しますので、更新したつもりがないタイミングでファイルの更新チェックにひっかかるといったことは考えられます。

     |  Kuro  |  返信
  9. 分割していないときは平和そのものなのに、分割した途端に時々発生するんですよね。
    再現できないのなら、また様子をみてみます

     |  かずら  |  返信
  10. ファイルの更新チェックはタイマーではなく、タブの切り替えやペインの移動など、エディターのフォーカス状態が変化したタイミングで行われます。

    分割していない場合は発生せず、分割した場合に発生するのはペイン間での移動によってファイルの更新チェックが動作しているためだと思います。

    クラウド同期のソフトによって一時的にファイルの更新日時が変更されることがあるのなら、たまたまそのタイミングでペインの移動を行ってファイルの更新チェックにひっかかってしまったというのは考えられますね。

    そういった場合は、「外部でファイルが変更されています。読み直しますか?」というダイアログボックスで Ctrl キーを押しながら [いいえ] を押すと、そのファイルを閉じるまでは更新チェックをオフにできますので、対症療法ではありますがお試しくださいませ。

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