rust/crates/ra_editor/src/line_index.rs

63 lines
2.2 KiB
Rust
Raw Normal View History

2018-08-10 20:13:39 +02:00
use superslice::Ext;
2018-10-15 19:05:26 +02:00
use crate::TextUnit;
2018-08-10 20:13:39 +02:00
2018-10-07 12:18:25 +02:00
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
2018-08-10 20:13:39 +02:00
pub struct LineIndex {
newlines: Vec<TextUnit>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct LineCol {
pub line: u32,
pub col: TextUnit,
}
impl LineIndex {
pub fn new(text: &str) -> LineIndex {
let mut newlines = vec![0.into()];
let mut curr = 0.into();
for c in text.chars() {
curr += TextUnit::of_char(c);
if c == '\n' {
newlines.push(curr);
}
}
LineIndex { newlines }
}
2018-08-10 21:23:17 +02:00
pub fn line_col(&self, offset: TextUnit) -> LineCol {
2018-08-10 20:13:39 +02:00
let line = self.newlines.upper_bound(&offset) - 1;
let line_start_offset = self.newlines[line];
let col = offset - line_start_offset;
2018-08-10 21:23:17 +02:00
return LineCol { line: line as u32, col };
}
pub fn offset(&self, line_col: LineCol) -> TextUnit {
//TODO: return Result
self.newlines[line_col.line as usize] + line_col.col
2018-08-10 20:13:39 +02:00
}
}
#[test]
fn test_line_index() {
let text = "hello\nworld";
let index = LineIndex::new(text);
2018-08-10 21:23:17 +02:00
assert_eq!(index.line_col(0.into()), LineCol { line: 0, col: 0.into() });
assert_eq!(index.line_col(1.into()), LineCol { line: 0, col: 1.into() });
assert_eq!(index.line_col(5.into()), LineCol { line: 0, col: 5.into() });
assert_eq!(index.line_col(6.into()), LineCol { line: 1, col: 0.into() });
assert_eq!(index.line_col(7.into()), LineCol { line: 1, col: 1.into() });
assert_eq!(index.line_col(8.into()), LineCol { line: 1, col: 2.into() });
assert_eq!(index.line_col(10.into()), LineCol { line: 1, col: 4.into() });
assert_eq!(index.line_col(11.into()), LineCol { line: 1, col: 5.into() });
assert_eq!(index.line_col(12.into()), LineCol { line: 1, col: 6.into() });
2018-08-10 20:13:39 +02:00
let text = "\nhello\nworld";
let index = LineIndex::new(text);
2018-08-10 21:23:17 +02:00
assert_eq!(index.line_col(0.into()), LineCol { line: 0, col: 0.into() });
assert_eq!(index.line_col(1.into()), LineCol { line: 1, col: 0.into() });
assert_eq!(index.line_col(2.into()), LineCol { line: 1, col: 1.into() });
assert_eq!(index.line_col(6.into()), LineCol { line: 1, col: 5.into() });
assert_eq!(index.line_col(7.into()), LineCol { line: 2, col: 0.into() });
2018-08-10 20:13:39 +02:00
}