diff options
Diffstat (limited to 'crates/ra_editor/src/lib.rs')
-rw-r--r-- | crates/ra_editor/src/lib.rs | 103 |
1 files changed, 53 insertions, 50 deletions
diff --git a/crates/ra_editor/src/lib.rs b/crates/ra_editor/src/lib.rs index bd61fd191..417080d90 100644 --- a/crates/ra_editor/src/lib.rs +++ b/crates/ra_editor/src/lib.rs | |||
@@ -1,44 +1,41 @@ | |||
1 | extern crate ra_syntax; | ||
2 | extern crate superslice; | ||
3 | extern crate itertools; | 1 | extern crate itertools; |
4 | extern crate join_to_string; | 2 | extern crate join_to_string; |
3 | extern crate ra_syntax; | ||
5 | extern crate rustc_hash; | 4 | extern crate rustc_hash; |
5 | extern crate superslice; | ||
6 | #[cfg(test)] | 6 | #[cfg(test)] |
7 | #[macro_use] | 7 | #[macro_use] |
8 | extern crate test_utils as _test_utils; | 8 | extern crate test_utils as _test_utils; |
9 | 9 | ||
10 | mod extend_selection; | ||
11 | mod symbols; | ||
12 | mod line_index; | ||
13 | mod edit; | ||
14 | mod folding_ranges; | ||
15 | mod code_actions; | 10 | mod code_actions; |
16 | mod typing; | ||
17 | mod completion; | 11 | mod completion; |
12 | mod edit; | ||
13 | mod extend_selection; | ||
14 | mod folding_ranges; | ||
15 | mod line_index; | ||
18 | mod scope; | 16 | mod scope; |
17 | mod symbols; | ||
19 | #[cfg(test)] | 18 | #[cfg(test)] |
20 | mod test_utils; | 19 | mod test_utils; |
20 | mod typing; | ||
21 | 21 | ||
22 | pub use self::{ | ||
23 | code_actions::{add_derive, add_impl, flip_comma, introduce_variable, LocalEdit}, | ||
24 | completion::{scope_completion, CompletionItem}, | ||
25 | edit::{Edit, EditBuilder}, | ||
26 | extend_selection::extend_selection, | ||
27 | folding_ranges::{folding_ranges, Fold, FoldKind}, | ||
28 | line_index::{LineCol, LineIndex}, | ||
29 | symbols::{file_structure, file_symbols, FileSymbol, StructureNode}, | ||
30 | typing::{join_lines, on_enter, on_eq_typed}, | ||
31 | }; | ||
32 | pub use ra_syntax::AtomEdit; | ||
22 | use ra_syntax::{ | 33 | use ra_syntax::{ |
23 | File, TextUnit, TextRange, SmolStr, SyntaxNodeRef, | ||
24 | ast::{self, AstNode, NameOwner}, | ||
25 | algo::find_leaf_at_offset, | 34 | algo::find_leaf_at_offset, |
35 | ast::{self, AstNode, NameOwner}, | ||
36 | File, SmolStr, | ||
26 | SyntaxKind::{self, *}, | 37 | SyntaxKind::{self, *}, |
27 | }; | 38 | SyntaxNodeRef, TextRange, TextUnit, |
28 | pub use ra_syntax::AtomEdit; | ||
29 | pub use self::{ | ||
30 | line_index::{LineIndex, LineCol}, | ||
31 | extend_selection::extend_selection, | ||
32 | symbols::{StructureNode, file_structure, FileSymbol, file_symbols}, | ||
33 | edit::{EditBuilder, Edit}, | ||
34 | code_actions::{ | ||
35 | LocalEdit, | ||
36 | flip_comma, add_derive, add_impl, | ||
37 | introduce_variable, | ||
38 | }, | ||
39 | typing::{join_lines, on_eq_typed, on_enter}, | ||
40 | completion::{scope_completion, CompletionItem}, | ||
41 | folding_ranges::{Fold, FoldKind, folding_ranges} | ||
42 | }; | 39 | }; |
43 | 40 | ||
44 | #[derive(Debug)] | 41 | #[derive(Debug)] |
@@ -67,10 +64,7 @@ pub enum RunnableKind { | |||
67 | 64 | ||
68 | pub fn matching_brace(file: &File, offset: TextUnit) -> Option<TextUnit> { | 65 | pub fn matching_brace(file: &File, offset: TextUnit) -> Option<TextUnit> { |
69 | const BRACES: &[SyntaxKind] = &[ | 66 | const BRACES: &[SyntaxKind] = &[ |
70 | L_CURLY, R_CURLY, | 67 | L_CURLY, R_CURLY, L_BRACK, R_BRACK, L_PAREN, R_PAREN, L_ANGLE, R_ANGLE, |
71 | L_BRACK, R_BRACK, | ||
72 | L_PAREN, R_PAREN, | ||
73 | L_ANGLE, R_ANGLE, | ||
74 | ]; | 68 | ]; |
75 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset) | 69 | let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax(), offset) |
76 | .filter_map(|node| { | 70 | .filter_map(|node| { |
@@ -80,7 +74,8 @@ pub fn matching_brace(file: &File, offset: TextUnit) -> Option<TextUnit> { | |||
80 | .next()?; | 74 | .next()?; |
81 | let parent = brace_node.parent()?; | 75 | let parent = brace_node.parent()?; |
82 | let matching_kind = BRACES[brace_idx ^ 1]; | 76 | let matching_kind = BRACES[brace_idx ^ 1]; |
83 | let matching_node = parent.children() | 77 | let matching_node = parent |
78 | .children() | ||
84 | .find(|node| node.kind() == matching_kind)?; | 79 | .find(|node| node.kind() == matching_kind)?; |
85 | Some(matching_node.range().start()) | 80 | Some(matching_node.range().start()) |
86 | } | 81 | } |
@@ -108,10 +103,13 @@ pub fn highlight(file: &File) -> Vec<HighlightedRange> { | |||
108 | } | 103 | } |
109 | 104 | ||
110 | pub fn diagnostics(file: &File) -> Vec<Diagnostic> { | 105 | pub fn diagnostics(file: &File) -> Vec<Diagnostic> { |
111 | file.errors().into_iter().map(|err| Diagnostic { | 106 | file.errors() |
112 | range: TextRange::offset_len(err.offset, 1.into()), | 107 | .into_iter() |
113 | msg: "Syntax Error: ".to_string() + &err.msg, | 108 | .map(|err| Diagnostic { |
114 | }).collect() | 109 | range: TextRange::offset_len(err.offset, 1.into()), |
110 | msg: "Syntax Error: ".to_string() + &err.msg, | ||
111 | }) | ||
112 | .collect() | ||
115 | } | 113 | } |
116 | 114 | ||
117 | pub fn syntax_tree(file: &File) -> String { | 115 | pub fn syntax_tree(file: &File) -> String { |
@@ -119,7 +117,8 @@ pub fn syntax_tree(file: &File) -> String { | |||
119 | } | 117 | } |
120 | 118 | ||
121 | pub fn runnables(file: &File) -> Vec<Runnable> { | 119 | pub fn runnables(file: &File) -> Vec<Runnable> { |
122 | file.syntax().descendants() | 120 | file.syntax() |
121 | .descendants() | ||
123 | .filter_map(ast::FnDef::cast) | 122 | .filter_map(ast::FnDef::cast) |
124 | .filter_map(|f| { | 123 | .filter_map(|f| { |
125 | let name = f.name()?.text(); | 124 | let name = f.name()?.text(); |
@@ -127,7 +126,7 @@ pub fn runnables(file: &File) -> Vec<Runnable> { | |||
127 | RunnableKind::Bin | 126 | RunnableKind::Bin |
128 | } else if f.has_atom_attr("test") { | 127 | } else if f.has_atom_attr("test") { |
129 | RunnableKind::Test { | 128 | RunnableKind::Test { |
130 | name: name.to_string() | 129 | name: name.to_string(), |
131 | } | 130 | } |
132 | } else { | 131 | } else { |
133 | return None; | 132 | return None; |
@@ -145,15 +144,18 @@ pub fn find_node_at_offset<'a, N: AstNode<'a>>( | |||
145 | offset: TextUnit, | 144 | offset: TextUnit, |
146 | ) -> Option<N> { | 145 | ) -> Option<N> { |
147 | let leaves = find_leaf_at_offset(syntax, offset); | 146 | let leaves = find_leaf_at_offset(syntax, offset); |
148 | let leaf = leaves.clone() | 147 | let leaf = leaves |
148 | .clone() | ||
149 | .find(|leaf| !leaf.kind().is_trivia()) | 149 | .find(|leaf| !leaf.kind().is_trivia()) |
150 | .or_else(|| leaves.right_biased())?; | 150 | .or_else(|| leaves.right_biased())?; |
151 | leaf.ancestors() | 151 | leaf.ancestors().filter_map(N::cast).next() |
152 | .filter_map(N::cast) | ||
153 | .next() | ||
154 | } | 152 | } |
155 | 153 | ||
156 | pub fn resolve_local_name(file: &File, offset: TextUnit, name_ref: ast::NameRef) -> Option<(SmolStr, TextRange)> { | 154 | pub fn resolve_local_name( |
155 | file: &File, | ||
156 | offset: TextUnit, | ||
157 | name_ref: ast::NameRef, | ||
158 | ) -> Option<(SmolStr, TextRange)> { | ||
157 | let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), offset)?; | 159 | let fn_def = find_node_at_offset::<ast::FnDef>(file.syntax(), offset)?; |
158 | let scopes = scope::FnScopes::new(fn_def); | 160 | let scopes = scope::FnScopes::new(fn_def); |
159 | let scope_entry = scope::resolve_local_name(name_ref, &scopes)?; | 161 | let scope_entry = scope::resolve_local_name(name_ref, &scopes)?; |
@@ -164,15 +166,17 @@ pub fn resolve_local_name(file: &File, offset: TextUnit, name_ref: ast::NameRef) | |||
164 | #[cfg(test)] | 166 | #[cfg(test)] |
165 | mod tests { | 167 | mod tests { |
166 | use super::*; | 168 | use super::*; |
167 | use crate::test_utils::{assert_eq_dbg, extract_offset, add_cursor}; | 169 | use crate::test_utils::{add_cursor, assert_eq_dbg, extract_offset}; |
168 | 170 | ||
169 | #[test] | 171 | #[test] |
170 | fn test_highlighting() { | 172 | fn test_highlighting() { |
171 | let file = File::parse(r#" | 173 | let file = File::parse( |
174 | r#" | ||
172 | // comment | 175 | // comment |
173 | fn main() {} | 176 | fn main() {} |
174 | println!("Hello, {}!", 92); | 177 | println!("Hello, {}!", 92); |
175 | "#); | 178 | "#, |
179 | ); | ||
176 | let hls = highlight(&file); | 180 | let hls = highlight(&file); |
177 | assert_eq_dbg( | 181 | assert_eq_dbg( |
178 | r#"[HighlightedRange { range: [1; 11), tag: "comment" }, | 182 | r#"[HighlightedRange { range: [1; 11), tag: "comment" }, |
@@ -187,7 +191,8 @@ fn main() {} | |||
187 | 191 | ||
188 | #[test] | 192 | #[test] |
189 | fn test_runnables() { | 193 | fn test_runnables() { |
190 | let file = File::parse(r#" | 194 | let file = File::parse( |
195 | r#" | ||
191 | fn main() {} | 196 | fn main() {} |
192 | 197 | ||
193 | #[test] | 198 | #[test] |
@@ -196,7 +201,8 @@ fn test_foo() {} | |||
196 | #[test] | 201 | #[test] |
197 | #[ignore] | 202 | #[ignore] |
198 | fn test_foo() {} | 203 | fn test_foo() {} |
199 | "#); | 204 | "#, |
205 | ); | ||
200 | let runnables = runnables(&file); | 206 | let runnables = runnables(&file); |
201 | assert_eq_dbg( | 207 | assert_eq_dbg( |
202 | r#"[Runnable { range: [1; 13), kind: Bin }, | 208 | r#"[Runnable { range: [1; 13), kind: Bin }, |
@@ -219,9 +225,6 @@ fn test_foo() {} | |||
219 | assert_eq_text!(after, &actual); | 225 | assert_eq_text!(after, &actual); |
220 | } | 226 | } |
221 | 227 | ||
222 | do_check( | 228 | do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }"); |
223 | "struct Foo { a: i32, }<|>", | ||
224 | "struct Foo <|>{ a: i32, }", | ||
225 | ); | ||
226 | } | 229 | } |
227 | } | 230 | } |