Closed cxxxr closed 7 years ago
テキストは古くからあるエディタでよく使われている行単位双方向連結リストで管理していて、 N行目を得る方法はバッファの先頭、後尾、最後に得た行から一番近い位置から辿っていく。 最後に得た行はキャッシュしているので局所的な行の取得は、 大体O(1)で済むようにはなってる。(でも関数コールが深くなるからあまり速くは無いかもしれない)
このテキストの位置を表す方法が色々あって整理されていないので、ここをどうにかしないといけない。 lemでは位置は(cons 行番号 先頭行からのオフセット)で表すのを一番よく使っていて この形で使う場合と行番号だけを指定する場合、バッファの先頭からのオフセットの場合、マーカの場合が あるのでとてもややこしい。
(cons 行番号 先頭行からのオフセット)
(cons 行番号 先頭行からのオフセット)で位置を表すと emacsの整数を使う方法では気にしなくてもよかった問題が出てくる。 位置を一つずらす関数は、整数を一つ足すだけでは駄目で、バッファ毎に行数は違うし どの行も同じ文字数とは限らないので、バッファとその位置の二つを知っている必要がある。
zmacsやhemlock、climacsで使われているDrei、lispworks editorではマーカを 引数にしてテキストの編集と位置の移動の関数を実装していて これを参考にするのはどうかと思っている。
全部マーカにまとめると位置だけの情報はマーカに統合されることになる。 これでバッファと位置を二つ指定する関数が一つにまとめられるし 位置が違うバッファを差してたということが無くなる。
バッファのテキストの管理方法にも依存しないはずなので あとで別の実装に変えやすいのも良い点。
それと現在マーカは行番号と先頭行からのオフセットで位置を指してるが 行構造体を直接指せば一々バッファの行番号を指定して とってこなくても良くなるのと、 バッファのある行に文字を挿入してその行のマーカがずれるときに 計算がその行だけになるのでここは変更したい。 これをやると構文走査が遅くならないために生のlineを扱っている箇所がmarkerでまとめられるので コードがまとまって綺麗になるのも良い点。
バッファを操作する関数の仕様がマーカを指定する形に変わるので 互換性の無い変更は多そうだけど、バッファを操作するときは常に 現在の位置を操作したい場合がほとんどなので、 マーカを指定する関数をラップした現在のマーカ(バッファのカーソル位置)に 対して操作する関数をつければうまくいくはず。 (edi weitz氏のlw-add-addonsではchar-beforeなどのemacsと互換性がある、現在位置に何かをする関数がいくつか定義されている)
位置を動かしたり挿入する全ての関数にマーカを指定するようにして 引数にnil(もしくはt)ならバッファのカーソル位置のマーカにするのはどうなんでしょう
できるだけemacsと互換性がある方がいいのか、無いほうがいいのか悩み所
テキストは古くからあるエディタでよく使われている行単位双方向連結リストで管理していて、 N行目を得る方法はバッファの先頭、後尾、最後に得た行から一番近い位置から辿っていく。 最後に得た行はキャッシュしているので局所的な行の取得は、 大体O(1)で済むようにはなってる。(でも関数コールが深くなるからあまり速くは無いかもしれない)
このテキストの位置を表す方法が色々あって整理されていないので、ここをどうにかしないといけない。 lemでは位置は
(cons 行番号 先頭行からのオフセット)
で表すのを一番よく使っていて この形で使う場合と行番号だけを指定する場合、バッファの先頭からのオフセットの場合、マーカの場合が あるのでとてもややこしい。(cons 行番号 先頭行からのオフセット)
で位置を表すと emacsの整数を使う方法では気にしなくてもよかった問題が出てくる。 位置を一つずらす関数は、整数を一つ足すだけでは駄目で、バッファ毎に行数は違うし どの行も同じ文字数とは限らないので、バッファとその位置の二つを知っている必要がある。zmacsやhemlock、climacsで使われているDrei、lispworks editorではマーカを 引数にしてテキストの編集と位置の移動の関数を実装していて これを参考にするのはどうかと思っている。
全部マーカにまとめると位置だけの情報はマーカに統合されることになる。 これでバッファと位置を二つ指定する関数が一つにまとめられるし 位置が違うバッファを差してたということが無くなる。
バッファのテキストの管理方法にも依存しないはずなので あとで別の実装に変えやすいのも良い点。
それと現在マーカは行番号と先頭行からのオフセットで位置を指してるが 行構造体を直接指せば一々バッファの行番号を指定して とってこなくても良くなるのと、 バッファのある行に文字を挿入してその行のマーカがずれるときに 計算がその行だけになるのでここは変更したい。 これをやると構文走査が遅くならないために生のlineを扱っている箇所がmarkerでまとめられるので コードがまとまって綺麗になるのも良い点。
バッファを操作する関数の仕様がマーカを指定する形に変わるので 互換性の無い変更は多そうだけど、バッファを操作するときは常に 現在の位置を操作したい場合がほとんどなので、 マーカを指定する関数をラップした現在のマーカ(バッファのカーソル位置)に 対して操作する関数をつければうまくいくはず。 (edi weitz氏のlw-add-addonsではchar-beforeなどのemacsと互換性がある、現在位置に何かをする関数がいくつか定義されている)