diff options
Diffstat (limited to 'crates/ra_ide_api/src/extend_selection.rs')
-rw-r--r-- | crates/ra_ide_api/src/extend_selection.rs | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs index 292f61f4a..140820df6 100644 --- a/crates/ra_ide_api/src/extend_selection.rs +++ b/crates/ra_ide_api/src/extend_selection.rs | |||
@@ -42,19 +42,20 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange | |||
42 | TokenAtOffset::None => return None, | 42 | TokenAtOffset::None => return None, |
43 | TokenAtOffset::Single(l) => { | 43 | TokenAtOffset::Single(l) => { |
44 | if string_kinds.contains(&l.kind()) { | 44 | if string_kinds.contains(&l.kind()) { |
45 | extend_single_word_in_comment_or_string(&l, offset).unwrap_or_else(|| l.range()) | 45 | extend_single_word_in_comment_or_string(&l, offset) |
46 | .unwrap_or_else(|| l.text_range()) | ||
46 | } else { | 47 | } else { |
47 | l.range() | 48 | l.text_range() |
48 | } | 49 | } |
49 | } | 50 | } |
50 | TokenAtOffset::Between(l, r) => pick_best(l, r).range(), | 51 | TokenAtOffset::Between(l, r) => pick_best(l, r).text_range(), |
51 | }; | 52 | }; |
52 | return Some(leaf_range); | 53 | return Some(leaf_range); |
53 | }; | 54 | }; |
54 | let node = match find_covering_element(root, range) { | 55 | let node = match find_covering_element(root, range) { |
55 | SyntaxElement::Token(token) => { | 56 | SyntaxElement::Token(token) => { |
56 | if token.range() != range { | 57 | if token.text_range() != range { |
57 | return Some(token.range()); | 58 | return Some(token.text_range()); |
58 | } | 59 | } |
59 | if let Some(comment) = ast::Comment::cast(token.clone()) { | 60 | if let Some(comment) = ast::Comment::cast(token.clone()) { |
60 | if let Some(range) = extend_comments(comment) { | 61 | if let Some(range) = extend_comments(comment) { |
@@ -65,12 +66,12 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange | |||
65 | } | 66 | } |
66 | SyntaxElement::Node(node) => node, | 67 | SyntaxElement::Node(node) => node, |
67 | }; | 68 | }; |
68 | if node.range() != range { | 69 | if node.text_range() != range { |
69 | return Some(node.range()); | 70 | return Some(node.text_range()); |
70 | } | 71 | } |
71 | 72 | ||
72 | // Using shallowest node with same range allows us to traverse siblings. | 73 | // Using shallowest node with same range allows us to traverse siblings. |
73 | let node = node.ancestors().take_while(|n| n.range() == node.range()).last().unwrap(); | 74 | let node = node.ancestors().take_while(|n| n.text_range() == node.text_range()).last().unwrap(); |
74 | 75 | ||
75 | if node.parent().map(|n| list_kinds.contains(&n.kind())) == Some(true) { | 76 | if node.parent().map(|n| list_kinds.contains(&n.kind())) == Some(true) { |
76 | if let Some(range) = extend_list_item(&node) { | 77 | if let Some(range) = extend_list_item(&node) { |
@@ -78,7 +79,7 @@ fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange | |||
78 | } | 79 | } |
79 | } | 80 | } |
80 | 81 | ||
81 | node.parent().map(|it| it.range()) | 82 | node.parent().map(|it| it.text_range()) |
82 | } | 83 | } |
83 | 84 | ||
84 | fn extend_single_word_in_comment_or_string( | 85 | fn extend_single_word_in_comment_or_string( |
@@ -86,7 +87,7 @@ fn extend_single_word_in_comment_or_string( | |||
86 | offset: TextUnit, | 87 | offset: TextUnit, |
87 | ) -> Option<TextRange> { | 88 | ) -> Option<TextRange> { |
88 | let text: &str = leaf.text(); | 89 | let text: &str = leaf.text(); |
89 | let cursor_position: u32 = (offset - leaf.range().start()).into(); | 90 | let cursor_position: u32 = (offset - leaf.text_range().start()).into(); |
90 | 91 | ||
91 | let (before, after) = text.split_at(cursor_position as usize); | 92 | let (before, after) = text.split_at(cursor_position as usize); |
92 | 93 | ||
@@ -104,31 +105,31 @@ fn extend_single_word_in_comment_or_string( | |||
104 | if range.is_empty() { | 105 | if range.is_empty() { |
105 | None | 106 | None |
106 | } else { | 107 | } else { |
107 | Some(range + leaf.range().start()) | 108 | Some(range + leaf.text_range().start()) |
108 | } | 109 | } |
109 | } | 110 | } |
110 | 111 | ||
111 | fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextUnit) -> TextRange { | 112 | fn extend_ws(root: &SyntaxNode, ws: SyntaxToken, offset: TextUnit) -> TextRange { |
112 | let ws_text = ws.text(); | 113 | let ws_text = ws.text(); |
113 | let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); | 114 | let suffix = TextRange::from_to(offset, ws.text_range().end()) - ws.text_range().start(); |
114 | let prefix = TextRange::from_to(ws.range().start(), offset) - ws.range().start(); | 115 | let prefix = TextRange::from_to(ws.text_range().start(), offset) - ws.text_range().start(); |
115 | let ws_suffix = &ws_text.as_str()[suffix]; | 116 | let ws_suffix = &ws_text.as_str()[suffix]; |
116 | let ws_prefix = &ws_text.as_str()[prefix]; | 117 | let ws_prefix = &ws_text.as_str()[prefix]; |
117 | if ws_text.contains('\n') && !ws_suffix.contains('\n') { | 118 | if ws_text.contains('\n') && !ws_suffix.contains('\n') { |
118 | if let Some(node) = ws.next_sibling_or_token() { | 119 | if let Some(node) = ws.next_sibling_or_token() { |
119 | let start = match ws_prefix.rfind('\n') { | 120 | let start = match ws_prefix.rfind('\n') { |
120 | Some(idx) => ws.range().start() + TextUnit::from((idx + 1) as u32), | 121 | Some(idx) => ws.text_range().start() + TextUnit::from((idx + 1) as u32), |
121 | None => node.range().start(), | 122 | None => node.text_range().start(), |
122 | }; | 123 | }; |
123 | let end = if root.text().char_at(node.range().end()) == Some('\n') { | 124 | let end = if root.text().char_at(node.text_range().end()) == Some('\n') { |
124 | node.range().end() + TextUnit::of_char('\n') | 125 | node.text_range().end() + TextUnit::of_char('\n') |
125 | } else { | 126 | } else { |
126 | node.range().end() | 127 | node.text_range().end() |
127 | }; | 128 | }; |
128 | return TextRange::from_to(start, end); | 129 | return TextRange::from_to(start, end); |
129 | } | 130 | } |
130 | } | 131 | } |
131 | ws.range() | 132 | ws.text_range() |
132 | } | 133 | } |
133 | 134 | ||
134 | fn pick_best<'a>(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken { | 135 | fn pick_best<'a>(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken { |
@@ -161,7 +162,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> { | |||
161 | } | 162 | } |
162 | 163 | ||
163 | if let Some(comma_node) = nearby_comma(node, Direction::Prev) { | 164 | if let Some(comma_node) = nearby_comma(node, Direction::Prev) { |
164 | return Some(TextRange::from_to(comma_node.range().start(), node.range().end())); | 165 | return Some(TextRange::from_to(comma_node.text_range().start(), node.text_range().end())); |
165 | } | 166 | } |
166 | if let Some(comma_node) = nearby_comma(node, Direction::Next) { | 167 | if let Some(comma_node) = nearby_comma(node, Direction::Next) { |
167 | // Include any following whitespace when comma if after list item. | 168 | // Include any following whitespace when comma if after list item. |
@@ -171,7 +172,7 @@ fn extend_list_item(node: &SyntaxNode) -> Option<TextRange> { | |||
171 | .filter(|node| is_single_line_ws(node)) | 172 | .filter(|node| is_single_line_ws(node)) |
172 | .unwrap_or(comma_node); | 173 | .unwrap_or(comma_node); |
173 | 174 | ||
174 | return Some(TextRange::from_to(node.range().start(), final_node.range().end())); | 175 | return Some(TextRange::from_to(node.text_range().start(), final_node.text_range().end())); |
175 | } | 176 | } |
176 | 177 | ||
177 | None | 178 | None |
@@ -181,7 +182,10 @@ fn extend_comments(comment: ast::Comment) -> Option<TextRange> { | |||
181 | let prev = adj_comments(&comment, Direction::Prev); | 182 | let prev = adj_comments(&comment, Direction::Prev); |
182 | let next = adj_comments(&comment, Direction::Next); | 183 | let next = adj_comments(&comment, Direction::Next); |
183 | if prev != next { | 184 | if prev != next { |
184 | Some(TextRange::from_to(prev.syntax().range().start(), next.syntax().range().end())) | 185 | Some(TextRange::from_to( |
186 | prev.syntax().text_range().start(), | ||
187 | next.syntax().text_range().end(), | ||
188 | )) | ||
185 | } else { | 189 | } else { |
186 | None | 190 | None |
187 | } | 191 | } |