aboutsummaryrefslogtreecommitdiff
path: root/libeditor
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-10 19:13:39 +0100
committerAleksey Kladov <[email protected]>2018-08-10 19:13:39 +0100
commit120789804d5483f14c9682b2b777adf6d2992547 (patch)
treebccbe4a72e648516f838499b91e5158484b5cbcd /libeditor
parent1be7af26a83b79863efb0d66a77b1fb7c0235bd2 (diff)
Add line index
Diffstat (limited to 'libeditor')
-rw-r--r--libeditor/Cargo.toml3
-rw-r--r--libeditor/src/lib.rs2
-rw-r--r--libeditor/src/line_index.rs56
3 files changed, 60 insertions, 1 deletions
diff --git a/libeditor/Cargo.toml b/libeditor/Cargo.toml
index 750d80038..fedcf790a 100644
--- a/libeditor/Cargo.toml
+++ b/libeditor/Cargo.toml
@@ -5,5 +5,6 @@ authors = ["Aleksey Kladov <[email protected]>"]
5publish = false 5publish = false
6 6
7[dependencies] 7[dependencies]
8libsyntax2 = { path = "../" }
9itertools = "0.7.8" 8itertools = "0.7.8"
9superslice = "0.1.0"
10libsyntax2 = { path = "../" }
diff --git a/libeditor/src/lib.rs b/libeditor/src/lib.rs
index 4e9631a8b..9da71743f 100644
--- a/libeditor/src/lib.rs
+++ b/libeditor/src/lib.rs
@@ -1,6 +1,8 @@
1extern crate libsyntax2; 1extern crate libsyntax2;
2extern crate superslice;
2 3
3mod extend_selection; 4mod extend_selection;
5mod line_index;
4 6
5use libsyntax2::{ 7use libsyntax2::{
6 SyntaxNodeRef, AstNode, 8 SyntaxNodeRef, AstNode,
diff --git a/libeditor/src/line_index.rs b/libeditor/src/line_index.rs
new file mode 100644
index 000000000..feb482b32
--- /dev/null
+++ b/libeditor/src/line_index.rs
@@ -0,0 +1,56 @@
1use superslice::Ext;
2use ::{TextUnit};
3
4pub struct LineIndex {
5 newlines: Vec<TextUnit>,
6}
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
9pub struct LineCol {
10 pub line: u32,
11 pub col: TextUnit,
12}
13
14impl LineIndex {
15 pub fn new(text: &str) -> LineIndex {
16 let mut newlines = vec![0.into()];
17 let mut curr = 0.into();
18 for c in text.chars() {
19 curr += TextUnit::of_char(c);
20 if c == '\n' {
21 newlines.push(curr);
22 }
23 }
24 LineIndex { newlines }
25 }
26
27 pub fn translate(&self, offset: TextUnit) -> LineCol {
28 let line = self.newlines.upper_bound(&offset) - 1;
29 let line_start_offset = self.newlines[line];
30 let col = offset - line_start_offset;
31 return LineCol { line: line as u32, col }
32 }
33}
34
35#[test]
36fn test_line_index() {
37 let text = "hello\nworld";
38 let index = LineIndex::new(text);
39 assert_eq!(index.translate(0.into()), LineCol { line: 0, col: 0.into()});
40 assert_eq!(index.translate(1.into()), LineCol { line: 0, col: 1.into()});
41 assert_eq!(index.translate(5.into()), LineCol { line: 0, col: 5.into()});
42 assert_eq!(index.translate(6.into()), LineCol { line: 1, col: 0.into()});
43 assert_eq!(index.translate(7.into()), LineCol { line: 1, col: 1.into()});
44 assert_eq!(index.translate(8.into()), LineCol { line: 1, col: 2.into()});
45 assert_eq!(index.translate(10.into()), LineCol { line: 1, col: 4.into()});
46 assert_eq!(index.translate(11.into()), LineCol { line: 1, col: 5.into()});
47 assert_eq!(index.translate(12.into()), LineCol { line: 1, col: 6.into()});
48
49 let text = "\nhello\nworld";
50 let index = LineIndex::new(text);
51 assert_eq!(index.translate(0.into()), LineCol { line: 0, col: 0.into()});
52 assert_eq!(index.translate(1.into()), LineCol { line: 1, col: 0.into()});
53 assert_eq!(index.translate(2.into()), LineCol { line: 1, col: 1.into()});
54 assert_eq!(index.translate(6.into()), LineCol { line: 1, col: 5.into()});
55 assert_eq!(index.translate(7.into()), LineCol { line: 2, col: 0.into()});
56}