cessen / ropey

A utf8 text rope for manipulating and editing large texts.
MIT License
1.04k stars 46 forks source link

[Question] Can I keep track of cursor positions while editing a `Rope`? #97

Closed balthild closed 1 month ago

balthild commented 1 month ago

For example, yrs (another Rust CRDT library) provides StickyIndex API for cursor positioning. Is there a way to do similar things with ropey?

cessen commented 1 month ago

There's no built-in functionality for this, but it's not particularly hard to implement yourself based on the edits made.

(The reason it's not built-in to Ropey is because there's no "right" way to do it, as you'll likely discover if you take a crack at implementing it yourself. It depends on how you model cursors, among other things. So it seemed best to leave that up to the application rather than forcing a particular model. Omitting it also keeps Ropey more focused in its scope: it's just about representing the text itself, not any metadata about it.)

balthild commented 1 month ago

Thanks for the explanation. Could you give me some ideas how to implement it? I'm not familiar with rope data structure and the only way I can think of is adding/subtracting the index according to inserted text's position and length. I'm not sure if this is correct for rope because it seems like a way for normal text buffers (like Vec<u8>).

cessen commented 1 month ago

Sure, I have a simple implementation in my toy text editor that you can take a look at:

https://github.com/cessen/led/blob/8a9388e8166e3e076f8bc8e256327bee9cd177b7/sub_crates/backend/src/marks.rs#L75-L102

You can also look at Helix for a more sophisticated implementation. I think this is the code:

https://github.com/helix-editor/helix/blob/b18a471ed189fb326a781181a28f3073f5c1fe1e/helix-core/src/selection.rs#L475-L500

balthild commented 1 month ago

Thank you!