diff options
Diffstat (limited to 'crates/ra_editor')
-rw-r--r-- | crates/ra_editor/src/extend_selection.rs | 27 | ||||
-rw-r--r-- | crates/ra_editor/src/symbols.rs | 55 |
2 files changed, 78 insertions, 4 deletions
diff --git a/crates/ra_editor/src/extend_selection.rs b/crates/ra_editor/src/extend_selection.rs index 8f11d5364..a2aa02149 100644 --- a/crates/ra_editor/src/extend_selection.rs +++ b/crates/ra_editor/src/extend_selection.rs | |||
@@ -48,13 +48,18 @@ fn extend_single_word_in_comment(leaf: SyntaxNodeRef, offset: TextUnit) -> Optio | |||
48 | let cursor_position: u32 = (offset - leaf.range().start()).into(); | 48 | let cursor_position: u32 = (offset - leaf.range().start()).into(); |
49 | 49 | ||
50 | let (before, after) = text.split_at(cursor_position as usize); | 50 | let (before, after) = text.split_at(cursor_position as usize); |
51 | let start_idx = before.rfind(char::is_whitespace)? as u32; | 51 | let start_idx = before.rfind(char::is_whitespace).unwrap_or(0) as u32; |
52 | let end_idx = after.find(char::is_whitespace)? as u32; | 52 | let end_idx = after.find(char::is_whitespace).unwrap_or(after.len()) as u32; |
53 | 53 | ||
54 | let from: TextUnit = (start_idx + 1).into(); | 54 | let from: TextUnit = (start_idx + 1).into(); |
55 | let to: TextUnit = (cursor_position + end_idx).into(); | 55 | let to: TextUnit = (cursor_position + end_idx).into(); |
56 | 56 | ||
57 | Some(TextRange::from_to(from, to) + leaf.range().start()) | 57 | let range = TextRange::from_to(from, to); |
58 | if range.is_empty() { | ||
59 | None | ||
60 | } else { | ||
61 | Some(range + leaf.range().start()) | ||
62 | } | ||
58 | } | 63 | } |
59 | 64 | ||
60 | fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { | 65 | fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { |
@@ -179,7 +184,21 @@ fn bar(){} | |||
179 | 184 | ||
180 | // fn foo(){} | 185 | // fn foo(){} |
181 | "#, | 186 | "#, |
182 | &["// 1 + 1", "// fn foo() {\n// 1 + 1\n// }"], | 187 | &["1", "// 1 + 1", "// fn foo() {\n// 1 + 1\n// }"], |
188 | ); | ||
189 | |||
190 | do_check( | ||
191 | r#" | ||
192 | // #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
193 | // pub enum Direction { | ||
194 | // <|> Next, | ||
195 | // Prev | ||
196 | // } | ||
197 | "#, | ||
198 | &[ | ||
199 | "// Next,", | ||
200 | "// #[derive(Debug, Clone, Copy, PartialEq, Eq)]\n// pub enum Direction {\n// Next,\n// Prev\n// }", | ||
201 | ], | ||
183 | ); | 202 | ); |
184 | } | 203 | } |
185 | 204 | ||
diff --git a/crates/ra_editor/src/symbols.rs b/crates/ra_editor/src/symbols.rs index 6d3b0514a..9e25decfb 100644 --- a/crates/ra_editor/src/symbols.rs +++ b/crates/ra_editor/src/symbols.rs | |||
@@ -50,6 +50,61 @@ impl FileSymbol { | |||
50 | }) | 50 | }) |
51 | .nth(0) | 51 | .nth(0) |
52 | } | 52 | } |
53 | /// Get a description of this node. | ||
54 | /// | ||
55 | /// e.g. `struct Name`, `enum Name`, `fn Name` | ||
56 | pub fn description(&self, file: &SourceFileNode) -> Option<String> { | ||
57 | // TODO: After type inference is done, add type information to improve the output | ||
58 | file.syntax() | ||
59 | .descendants() | ||
60 | .filter(|node| node.kind() == self.kind && node.range() == self.node_range) | ||
61 | .filter_map(|node: SyntaxNodeRef| { | ||
62 | // TODO: Refactor to be have less repetition | ||
63 | visitor() | ||
64 | .visit(|node: ast::FnDef| { | ||
65 | let mut string = "fn ".to_string(); | ||
66 | node.name()?.syntax().text().push_to(&mut string); | ||
67 | Some(string) | ||
68 | }) | ||
69 | .visit(|node: ast::StructDef| { | ||
70 | let mut string = "struct ".to_string(); | ||
71 | node.name()?.syntax().text().push_to(&mut string); | ||
72 | Some(string) | ||
73 | }) | ||
74 | .visit(|node: ast::EnumDef| { | ||
75 | let mut string = "enum ".to_string(); | ||
76 | node.name()?.syntax().text().push_to(&mut string); | ||
77 | Some(string) | ||
78 | }) | ||
79 | .visit(|node: ast::TraitDef| { | ||
80 | let mut string = "trait ".to_string(); | ||
81 | node.name()?.syntax().text().push_to(&mut string); | ||
82 | Some(string) | ||
83 | }) | ||
84 | .visit(|node: ast::Module| { | ||
85 | let mut string = "mod ".to_string(); | ||
86 | node.name()?.syntax().text().push_to(&mut string); | ||
87 | Some(string) | ||
88 | }) | ||
89 | .visit(|node: ast::TypeDef| { | ||
90 | let mut string = "type ".to_string(); | ||
91 | node.name()?.syntax().text().push_to(&mut string); | ||
92 | Some(string) | ||
93 | }) | ||
94 | .visit(|node: ast::ConstDef| { | ||
95 | let mut string = "const ".to_string(); | ||
96 | node.name()?.syntax().text().push_to(&mut string); | ||
97 | Some(string) | ||
98 | }) | ||
99 | .visit(|node: ast::StaticDef| { | ||
100 | let mut string = "static ".to_string(); | ||
101 | node.name()?.syntax().text().push_to(&mut string); | ||
102 | Some(string) | ||
103 | }) | ||
104 | .accept(node)? | ||
105 | }) | ||
106 | .nth(0) | ||
107 | } | ||
53 | } | 108 | } |
54 | 109 | ||
55 | pub fn file_symbols(file: &SourceFileNode) -> Vec<FileSymbol> { | 110 | pub fn file_symbols(file: &SourceFileNode) -> Vec<FileSymbol> { |