cessen / ropey

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

Best way to go from char_idx to (line_idx, column_idx) #27

Closed jessegrosjean closed 4 years ago

jessegrosjean commented 4 years ago

I have a char_index and I would like to convert to a (line, column) point.

Untested but right now I think something like this will work:

fn char_to_point(char_idx: usize, rope: &Rope) -> (usize, usize) {
  let line_idx = rope.char_to_line(char_idx);
  let line_char_index = rope.line_to_char(line_idx);
  (line_idx, char_idx - line_char_index)
}

I wonder if there's a more efficient approach though... seems that internally char_to_line probably already has easy/efficient access to the the column offset information. Could it (or maybe there's some other method) just return the line and offset so that the second call to line_to_char isn't necessary.

jessegrosjean commented 4 years ago

Never mind... chunk api is what I needed.

cessen commented 4 years ago

In case you're still watching this issue:

  1. Personally, I would probably stick with your first solution above until you find it to be a bottleneck. Sure, Ropey will be doing some redundant work that way, but those functions are pretty fast and it's easy to change later.
  2. In general, making the assumption that a single char == a column isn't correct. It's probably fine for many use-cases, and your use-case may be one of them. But in the general case you need to think about handling graphemes, double-wide characters (e.g. kanji and chinese characters) etc. Correct text handling is hard.