diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/completion/completion_context.rs | 7 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 46 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_type_definition.rs | 43 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 23 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/highlighting.html | 26 | ||||
-rw-r--r-- | crates/ra_ide/src/snapshots/rainbow_highlighting.html | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 98 |
7 files changed, 191 insertions, 54 deletions
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index ca0a483d4..981da2b79 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs | |||
@@ -188,10 +188,9 @@ impl<'a> CompletionContext<'a> { | |||
188 | self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some(); | 188 | self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some(); |
189 | self.has_type_args = segment.type_arg_list().is_some(); | 189 | self.has_type_args = segment.type_arg_list().is_some(); |
190 | 190 | ||
191 | if let Some(mut path) = hir::Path::from_ast(path.clone()) { | 191 | if let Some(path) = hir::Path::from_ast(path.clone()) { |
192 | if !path.is_ident() { | 192 | if let Some(path_prefix) = path.qualifier() { |
193 | path.segments.pop().unwrap(); | 193 | self.path_prefix = Some(path_prefix); |
194 | self.path_prefix = Some(path); | ||
195 | return; | 194 | return; |
196 | } | 195 | } |
197 | } | 196 | } |
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index 2c634990d..bee8e9df2 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -3,7 +3,9 @@ | |||
3 | use hir::{db::AstDatabase, InFile}; | 3 | use hir::{db::AstDatabase, InFile}; |
4 | use ra_syntax::{ | 4 | use ra_syntax::{ |
5 | ast::{self, DocCommentsOwner}, | 5 | ast::{self, DocCommentsOwner}, |
6 | match_ast, AstNode, SyntaxNode, | 6 | match_ast, AstNode, |
7 | SyntaxKind::*, | ||
8 | SyntaxNode, SyntaxToken, TokenAtOffset, | ||
7 | }; | 9 | }; |
8 | 10 | ||
9 | use crate::{ | 11 | use crate::{ |
@@ -19,8 +21,7 @@ pub(crate) fn goto_definition( | |||
19 | position: FilePosition, | 21 | position: FilePosition, |
20 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { | 22 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { |
21 | let file = db.parse_or_expand(position.file_id.into())?; | 23 | let file = db.parse_or_expand(position.file_id.into())?; |
22 | let original_token = | 24 | let original_token = pick_best(file.token_at_offset(position.offset))?; |
23 | file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?; | ||
24 | let token = descend_into_macros(db, position.file_id, original_token.clone()); | 25 | let token = descend_into_macros(db, position.file_id, original_token.clone()); |
25 | 26 | ||
26 | let nav_targets = match_ast! { | 27 | let nav_targets = match_ast! { |
@@ -38,6 +39,17 @@ pub(crate) fn goto_definition( | |||
38 | Some(RangeInfo::new(original_token.text_range(), nav_targets)) | 39 | Some(RangeInfo::new(original_token.text_range(), nav_targets)) |
39 | } | 40 | } |
40 | 41 | ||
42 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | ||
43 | return tokens.max_by_key(priority); | ||
44 | fn priority(n: &SyntaxToken) -> usize { | ||
45 | match n.kind() { | ||
46 | IDENT | INT_NUMBER => 2, | ||
47 | kind if kind.is_trivia() => 0, | ||
48 | _ => 1, | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | |||
41 | #[derive(Debug)] | 53 | #[derive(Debug)] |
42 | pub(crate) enum ReferenceResult { | 54 | pub(crate) enum ReferenceResult { |
43 | Exact(NavigationTarget), | 55 | Exact(NavigationTarget), |
@@ -253,6 +265,18 @@ mod tests { | |||
253 | } | 265 | } |
254 | 266 | ||
255 | #[test] | 267 | #[test] |
268 | fn goto_definition_works_at_start_of_item() { | ||
269 | check_goto( | ||
270 | " | ||
271 | //- /lib.rs | ||
272 | struct Foo; | ||
273 | enum E { X(<|>Foo) } | ||
274 | ", | ||
275 | "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", | ||
276 | ); | ||
277 | } | ||
278 | |||
279 | #[test] | ||
256 | fn goto_definition_resolves_correct_name() { | 280 | fn goto_definition_resolves_correct_name() { |
257 | check_goto( | 281 | check_goto( |
258 | " | 282 | " |
@@ -453,6 +477,22 @@ mod tests { | |||
453 | } | 477 | } |
454 | 478 | ||
455 | #[test] | 479 | #[test] |
480 | fn goto_for_tuple_fields() { | ||
481 | check_goto( | ||
482 | " | ||
483 | //- /lib.rs | ||
484 | struct Foo(u32); | ||
485 | |||
486 | fn bar() { | ||
487 | let foo = Foo(0); | ||
488 | foo.<|>0; | ||
489 | } | ||
490 | ", | ||
491 | "TUPLE_FIELD_DEF FileId(1) [11; 14)", | ||
492 | ); | ||
493 | } | ||
494 | |||
495 | #[test] | ||
456 | fn goto_definition_works_for_ufcs_inherent_methods() { | 496 | fn goto_definition_works_for_ufcs_inherent_methods() { |
457 | check_goto( | 497 | check_goto( |
458 | " | 498 | " |
diff --git a/crates/ra_ide/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs index 992a08809..ce8b6c72a 100644 --- a/crates/ra_ide/src/goto_type_definition.rs +++ b/crates/ra_ide/src/goto_type_definition.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::db::AstDatabase; | 3 | use hir::db::AstDatabase; |
4 | use ra_syntax::{ast, AstNode}; | 4 | use ra_syntax::{ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | db::RootDatabase, display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget, | 7 | db::RootDatabase, display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget, |
@@ -13,7 +13,7 @@ pub(crate) fn goto_type_definition( | |||
13 | position: FilePosition, | 13 | position: FilePosition, |
14 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { | 14 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { |
15 | let file = db.parse_or_expand(position.file_id.into())?; | 15 | let file = db.parse_or_expand(position.file_id.into())?; |
16 | let token = file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?; | 16 | let token = pick_best(file.token_at_offset(position.offset))?; |
17 | let token = descend_into_macros(db, position.file_id, token); | 17 | let token = descend_into_macros(db, position.file_id, token); |
18 | 18 | ||
19 | let node = token.value.ancestors().find_map(|token| { | 19 | let node = token.value.ancestors().find_map(|token| { |
@@ -41,6 +41,17 @@ pub(crate) fn goto_type_definition( | |||
41 | Some(RangeInfo::new(node.text_range(), vec![nav])) | 41 | Some(RangeInfo::new(node.text_range(), vec![nav])) |
42 | } | 42 | } |
43 | 43 | ||
44 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | ||
45 | return tokens.max_by_key(priority); | ||
46 | fn priority(n: &SyntaxToken) -> usize { | ||
47 | match n.kind() { | ||
48 | IDENT | INT_NUMBER => 2, | ||
49 | kind if kind.is_trivia() => 0, | ||
50 | _ => 1, | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | |||
44 | #[cfg(test)] | 55 | #[cfg(test)] |
45 | mod tests { | 56 | mod tests { |
46 | use crate::mock_analysis::analysis_and_position; | 57 | use crate::mock_analysis::analysis_and_position; |
@@ -102,4 +113,32 @@ mod tests { | |||
102 | "Foo STRUCT_DEF FileId(1) [52; 65) [59; 62)", | 113 | "Foo STRUCT_DEF FileId(1) [52; 65) [59; 62)", |
103 | ); | 114 | ); |
104 | } | 115 | } |
116 | |||
117 | #[test] | ||
118 | fn goto_type_definition_for_param() { | ||
119 | check_goto( | ||
120 | " | ||
121 | //- /lib.rs | ||
122 | struct Foo; | ||
123 | fn foo(<|>f: Foo) {} | ||
124 | ", | ||
125 | "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", | ||
126 | ); | ||
127 | } | ||
128 | |||
129 | #[test] | ||
130 | fn goto_type_definition_for_tuple_field() { | ||
131 | check_goto( | ||
132 | " | ||
133 | //- /lib.rs | ||
134 | struct Foo; | ||
135 | struct Bar(Foo); | ||
136 | fn foo() { | ||
137 | let bar = Bar(Foo); | ||
138 | bar.<|>0; | ||
139 | } | ||
140 | ", | ||
141 | "Foo STRUCT_DEF FileId(1) [0; 11) [7; 10)", | ||
142 | ); | ||
143 | } | ||
105 | } | 144 | } |
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index d372ca758..51e320128 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -6,6 +6,8 @@ use ra_syntax::{ | |||
6 | algo::find_covering_element, | 6 | algo::find_covering_element, |
7 | ast::{self, DocCommentsOwner}, | 7 | ast::{self, DocCommentsOwner}, |
8 | match_ast, AstNode, | 8 | match_ast, AstNode, |
9 | SyntaxKind::*, | ||
10 | SyntaxToken, TokenAtOffset, | ||
9 | }; | 11 | }; |
10 | 12 | ||
11 | use crate::{ | 13 | use crate::{ |
@@ -156,7 +158,7 @@ fn hover_text_from_name_kind( | |||
156 | 158 | ||
157 | pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> { | 159 | pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> { |
158 | let file = db.parse_or_expand(position.file_id.into())?; | 160 | let file = db.parse_or_expand(position.file_id.into())?; |
159 | let token = file.token_at_offset(position.offset).filter(|it| !it.kind().is_trivia()).next()?; | 161 | let token = pick_best(file.token_at_offset(position.offset))?; |
160 | let token = descend_into_macros(db, position.file_id, token); | 162 | let token = descend_into_macros(db, position.file_id, token); |
161 | 163 | ||
162 | let mut res = HoverResult::new(); | 164 | let mut res = HoverResult::new(); |
@@ -218,6 +220,18 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
218 | Some(RangeInfo::new(range, res)) | 220 | Some(RangeInfo::new(range, res)) |
219 | } | 221 | } |
220 | 222 | ||
223 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | ||
224 | return tokens.max_by_key(priority); | ||
225 | fn priority(n: &SyntaxToken) -> usize { | ||
226 | match n.kind() { | ||
227 | IDENT | INT_NUMBER => 3, | ||
228 | L_PAREN | R_PAREN => 2, | ||
229 | kind if kind.is_trivia() => 0, | ||
230 | _ => 1, | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | |||
221 | pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { | 235 | pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { |
222 | let parse = db.parse(frange.file_id); | 236 | let parse = db.parse(frange.file_id); |
223 | let leaf_node = find_covering_element(parse.tree().syntax(), frange.range); | 237 | let leaf_node = find_covering_element(parse.tree().syntax(), frange.range); |
@@ -505,6 +519,13 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
505 | } | 519 | } |
506 | 520 | ||
507 | #[test] | 521 | #[test] |
522 | fn hover_for_param_edge() { | ||
523 | let (analysis, position) = single_file_with_position("fn func(<|>foo: i32) {}"); | ||
524 | let hover = analysis.hover(position).unwrap().unwrap(); | ||
525 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); | ||
526 | } | ||
527 | |||
528 | #[test] | ||
508 | fn test_type_of_for_function() { | 529 | fn test_type_of_for_function() { |
509 | let (analysis, range) = single_file_with_range( | 530 | let (analysis, range) = single_file_with_range( |
510 | " | 531 | " |
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html index 4166a8f90..40605d9ef 100644 --- a/crates/ra_ide/src/snapshots/highlighting.html +++ b/crates/ra_ide/src/snapshots/highlighting.html | |||
@@ -10,8 +10,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
10 | .builtin { color: #DD6718; } | 10 | .builtin { color: #DD6718; } |
11 | .text { color: #DCDCCC; } | 11 | .text { color: #DCDCCC; } |
12 | .type { color: #7CB8BB; } | 12 | .type { color: #7CB8BB; } |
13 | .type\.param { color: #20999D; } | ||
13 | .attribute { color: #94BFF3; } | 14 | .attribute { color: #94BFF3; } |
14 | .literal { color: #BFEBBF; } | 15 | .literal { color: #BFEBBF; } |
16 | .literal\.numeric { color: #6A8759; } | ||
15 | .macro { color: #94BFF3; } | 17 | .macro { color: #94BFF3; } |
16 | .variable { color: #DCDCCC; } | 18 | .variable { color: #DCDCCC; } |
17 | .variable\.mut { color: #DCDCCC; text-decoration: underline; } | 19 | .variable\.mut { color: #DCDCCC; text-decoration: underline; } |
@@ -22,36 +24,36 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
22 | </style> | 24 | </style> |
23 | <pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span> | 25 | <pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span> |
24 | <span class="keyword">struct</span> <span class="type">Foo</span> { | 26 | <span class="keyword">struct</span> <span class="type">Foo</span> { |
25 | <span class="keyword">pub</span> <span class="field">x</span>: <span class="type">i32</span>, | 27 | <span class="keyword">pub</span> <span class="field">x</span>: <span class="type.builtin">i32</span>, |
26 | <span class="keyword">pub</span> <span class="field">y</span>: <span class="type">i32</span>, | 28 | <span class="keyword">pub</span> <span class="field">y</span>: <span class="type.builtin">i32</span>, |
27 | } | 29 | } |
28 | 30 | ||
29 | <span class="keyword">fn</span> <span class="function">foo</span><<span class="type">T</span>>() -> <span class="type">T</span> { | 31 | <span class="keyword">fn</span> <span class="function">foo</span><<span class="type.param">T</span>>() -> <span class="type.param">T</span> { |
30 | <span class="macro">unimplemented</span><span class="macro">!</span>(); | 32 | <span class="macro">unimplemented</span><span class="macro">!</span>(); |
31 | <span class="function">foo</span>::<<span class="type">i32</span>>(); | 33 | <span class="function">foo</span>::<<span class="type.builtin">i32</span>>(); |
32 | } | 34 | } |
33 | 35 | ||
34 | <span class="comment">// comment</span> | 36 | <span class="comment">// comment</span> |
35 | <span class="keyword">fn</span> <span class="function">main</span>() { | 37 | <span class="keyword">fn</span> <span class="function">main</span>() { |
36 | <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal">92</span>); | 38 | <span class="macro">println</span><span class="macro">!</span>(<span class="string">"Hello, {}!"</span>, <span class="literal.numeric">92</span>); |
37 | 39 | ||
38 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">vec</span> = <span class="text">Vec</span>::<span class="text">new</span>(); | 40 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">vec</span> = <span class="text">Vec</span>::<span class="text">new</span>(); |
39 | <span class="keyword.control">if</span> <span class="keyword">true</span> { | 41 | <span class="keyword.control">if</span> <span class="keyword">true</span> { |
40 | <span class="variable.mut">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>: <span class="literal">0</span>, <span class="field">y</span>: <span class="literal">1</span> }); | 42 | <span class="variable.mut">vec</span>.<span class="text">push</span>(<span class="type">Foo</span> { <span class="field">x</span>: <span class="literal.numeric">0</span>, <span class="field">y</span>: <span class="literal.numeric">1</span> }); |
41 | } | 43 | } |
42 | <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal">0</span>); } | 44 | <span class="keyword.unsafe">unsafe</span> { <span class="variable.mut">vec</span>.<span class="text">set_len</span>(<span class="literal.numeric">0</span>); } |
43 | 45 | ||
44 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">x</span> = <span class="literal">42</span>; | 46 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable.mut">x</span> = <span class="literal.numeric">42</span>; |
45 | <span class="keyword">let</span> <span class="variable.mut">y</span> = &<span class="keyword">mut</span> <span class="variable.mut">x</span>; | 47 | <span class="keyword">let</span> <span class="variable.mut">y</span> = &<span class="keyword">mut</span> <span class="variable.mut">x</span>; |
46 | <span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable.mut">y</span>; | 48 | <span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable.mut">y</span>; |
47 | 49 | ||
48 | <span class="variable.mut">y</span>; | 50 | <span class="variable.mut">y</span>; |
49 | } | 51 | } |
50 | 52 | ||
51 | <span class="keyword">enum</span> <span class="type">E</span><<span class="type">X</span>> { | 53 | <span class="keyword">enum</span> <span class="type">E</span><<span class="type.param">X</span>> { |
52 | <span class="constant">V</span>(<span class="type">X</span>) | 54 | <span class="constant">V</span>(<span class="type.param">X</span>) |
53 | } | 55 | } |
54 | 56 | ||
55 | <span class="keyword">impl</span><<span class="type">X</span>> <span class="type">E</span><<span class="type">X</span>> { | 57 | <span class="keyword">impl</span><<span class="type.param">X</span>> <span class="type">E</span><<span class="type.param">X</span>> { |
56 | <span class="keyword">fn</span> <span class="function">new</span><<span class="type">T</span>>() -> <span class="type">E</span><<span class="type">T</span>> {} | 58 | <span class="keyword">fn</span> <span class="function">new</span><<span class="type.param">T</span>>() -> <span class="type">E</span><<span class="type.param">T</span>> {} |
57 | }</code></pre> \ No newline at end of file | 59 | }</code></pre> \ No newline at end of file |
diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html index 9dfbc8047..ecf26c708 100644 --- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html +++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html | |||
@@ -10,8 +10,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
10 | .builtin { color: #DD6718; } | 10 | .builtin { color: #DD6718; } |
11 | .text { color: #DCDCCC; } | 11 | .text { color: #DCDCCC; } |
12 | .type { color: #7CB8BB; } | 12 | .type { color: #7CB8BB; } |
13 | .type\.param { color: #20999D; } | ||
13 | .attribute { color: #94BFF3; } | 14 | .attribute { color: #94BFF3; } |
14 | .literal { color: #BFEBBF; } | 15 | .literal { color: #BFEBBF; } |
16 | .literal\.numeric { color: #6A8759; } | ||
15 | .macro { color: #94BFF3; } | 17 | .macro { color: #94BFF3; } |
16 | .variable { color: #DCDCCC; } | 18 | .variable { color: #DCDCCC; } |
17 | .variable\.mut { color: #DCDCCC; text-decoration: underline; } | 19 | .variable\.mut { color: #DCDCCC; text-decoration: underline; } |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 7ecb1a027..eb3dd1779 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -16,6 +16,34 @@ use crate::{ | |||
16 | FileId, | 16 | FileId, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | pub mod tags { | ||
20 | pub(crate) const FIELD: &'static str = "field"; | ||
21 | pub(crate) const FUNCTION: &'static str = "function"; | ||
22 | pub(crate) const MODULE: &'static str = "module"; | ||
23 | pub(crate) const TYPE: &'static str = "type"; | ||
24 | pub(crate) const CONSTANT: &'static str = "constant"; | ||
25 | pub(crate) const MACRO: &'static str = "macro"; | ||
26 | pub(crate) const VARIABLE: &'static str = "variable"; | ||
27 | pub(crate) const VARIABLE_MUT: &'static str = "variable.mut"; | ||
28 | pub(crate) const TEXT: &'static str = "text"; | ||
29 | |||
30 | pub(crate) const TYPE_BUILTIN: &'static str = "type.builtin"; | ||
31 | pub(crate) const TYPE_SELF: &'static str = "type.self"; | ||
32 | pub(crate) const TYPE_PARAM: &'static str = "type.param"; | ||
33 | pub(crate) const TYPE_LIFETIME: &'static str = "type.lifetime"; | ||
34 | |||
35 | pub(crate) const LITERAL_BYTE: &'static str = "literal.byte"; | ||
36 | pub(crate) const LITERAL_NUMERIC: &'static str = "literal.numeric"; | ||
37 | pub(crate) const LITERAL_CHAR: &'static str = "literal.char"; | ||
38 | pub(crate) const LITERAL_COMMENT: &'static str = "comment"; | ||
39 | pub(crate) const LITERAL_STRING: &'static str = "string"; | ||
40 | pub(crate) const LITERAL_ATTRIBUTE: &'static str = "attribute"; | ||
41 | |||
42 | pub(crate) const KEYWORD_UNSAFE: &'static str = "keyword.unsafe"; | ||
43 | pub(crate) const KEYWORD_CONTROL: &'static str = "keyword.control"; | ||
44 | pub(crate) const KEYWORD: &'static str = "keyword"; | ||
45 | } | ||
46 | |||
19 | #[derive(Debug)] | 47 | #[derive(Debug)] |
20 | pub struct HighlightedRange { | 48 | pub struct HighlightedRange { |
21 | pub range: TextRange, | 49 | pub range: TextRange, |
@@ -71,9 +99,9 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
71 | bindings_shadow_count.clear(); | 99 | bindings_shadow_count.clear(); |
72 | continue; | 100 | continue; |
73 | } | 101 | } |
74 | COMMENT => "comment", | 102 | COMMENT => tags::LITERAL_COMMENT, |
75 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => "string", | 103 | STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => tags::LITERAL_STRING, |
76 | ATTR => "attribute", | 104 | ATTR => tags::LITERAL_ATTRIBUTE, |
77 | NAME_REF => { | 105 | NAME_REF => { |
78 | if node.ancestors().any(|it| it.kind() == ATTR) { | 106 | if node.ancestors().any(|it| it.kind() == ATTR) { |
79 | continue; | 107 | continue; |
@@ -90,7 +118,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
90 | } | 118 | } |
91 | }; | 119 | }; |
92 | 120 | ||
93 | name_kind.map_or("text", |it| highlight_name(db, it)) | 121 | name_kind.map_or(tags::TEXT, |it| highlight_name(db, it)) |
94 | } | 122 | } |
95 | NAME => { | 123 | NAME => { |
96 | let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap(); | 124 | let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap(); |
@@ -107,18 +135,21 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
107 | 135 | ||
108 | match name_kind { | 136 | match name_kind { |
109 | Some(name_kind) => highlight_name(db, name_kind), | 137 | Some(name_kind) => highlight_name(db, name_kind), |
110 | None => name.syntax().parent().map_or("function", |x| match x.kind() { | 138 | None => name.syntax().parent().map_or(tags::FUNCTION, |x| match x.kind() { |
111 | TYPE_PARAM | STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_ALIAS_DEF => "type", | 139 | STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_ALIAS_DEF => tags::TYPE, |
112 | RECORD_FIELD_DEF => "field", | 140 | TYPE_PARAM => tags::TYPE_PARAM, |
113 | _ => "function", | 141 | RECORD_FIELD_DEF => tags::FIELD, |
142 | _ => tags::FUNCTION, | ||
114 | }), | 143 | }), |
115 | } | 144 | } |
116 | } | 145 | } |
117 | INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", | 146 | INT_NUMBER | FLOAT_NUMBER => tags::LITERAL_NUMERIC, |
118 | LIFETIME => "parameter", | 147 | BYTE => tags::LITERAL_BYTE, |
119 | T![unsafe] => "keyword.unsafe", | 148 | CHAR => tags::LITERAL_CHAR, |
120 | k if is_control_keyword(k) => "keyword.control", | 149 | LIFETIME => tags::TYPE_LIFETIME, |
121 | k if k.is_keyword() => "keyword", | 150 | T![unsafe] => tags::KEYWORD_UNSAFE, |
151 | k if is_control_keyword(k) => tags::KEYWORD_CONTROL, | ||
152 | k if k.is_keyword() => tags::KEYWORD, | ||
122 | _ => { | 153 | _ => { |
123 | if let Some(macro_call) = node.as_node().cloned().and_then(ast::MacroCall::cast) { | 154 | if let Some(macro_call) = node.as_node().cloned().and_then(ast::MacroCall::cast) { |
124 | if let Some(path) = macro_call.path() { | 155 | if let Some(path) = macro_call.path() { |
@@ -135,7 +166,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
135 | } | 166 | } |
136 | res.push(HighlightedRange { | 167 | res.push(HighlightedRange { |
137 | range: TextRange::from_to(range_start, range_end), | 168 | range: TextRange::from_to(range_start, range_end), |
138 | tag: "macro", | 169 | tag: tags::MACRO, |
139 | binding_hash: None, | 170 | binding_hash: None, |
140 | }) | 171 | }) |
141 | } | 172 | } |
@@ -211,28 +242,29 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo | |||
211 | 242 | ||
212 | fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str { | 243 | fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str { |
213 | match name_kind { | 244 | match name_kind { |
214 | Macro(_) => "macro", | 245 | Macro(_) => tags::MACRO, |
215 | Field(_) => "field", | 246 | Field(_) => tags::FIELD, |
216 | AssocItem(hir::AssocItem::Function(_)) => "function", | 247 | AssocItem(hir::AssocItem::Function(_)) => tags::FUNCTION, |
217 | AssocItem(hir::AssocItem::Const(_)) => "constant", | 248 | AssocItem(hir::AssocItem::Const(_)) => tags::CONSTANT, |
218 | AssocItem(hir::AssocItem::TypeAlias(_)) => "type", | 249 | AssocItem(hir::AssocItem::TypeAlias(_)) => tags::TYPE, |
219 | Def(hir::ModuleDef::Module(_)) => "module", | 250 | Def(hir::ModuleDef::Module(_)) => tags::MODULE, |
220 | Def(hir::ModuleDef::Function(_)) => "function", | 251 | Def(hir::ModuleDef::Function(_)) => tags::FUNCTION, |
221 | Def(hir::ModuleDef::Adt(_)) => "type", | 252 | Def(hir::ModuleDef::Adt(_)) => tags::TYPE, |
222 | Def(hir::ModuleDef::EnumVariant(_)) => "constant", | 253 | Def(hir::ModuleDef::EnumVariant(_)) => tags::CONSTANT, |
223 | Def(hir::ModuleDef::Const(_)) => "constant", | 254 | Def(hir::ModuleDef::Const(_)) => tags::CONSTANT, |
224 | Def(hir::ModuleDef::Static(_)) => "constant", | 255 | Def(hir::ModuleDef::Static(_)) => tags::CONSTANT, |
225 | Def(hir::ModuleDef::Trait(_)) => "type", | 256 | Def(hir::ModuleDef::Trait(_)) => tags::TYPE, |
226 | Def(hir::ModuleDef::TypeAlias(_)) => "type", | 257 | Def(hir::ModuleDef::TypeAlias(_)) => tags::TYPE, |
227 | Def(hir::ModuleDef::BuiltinType(_)) => "type", | 258 | Def(hir::ModuleDef::BuiltinType(_)) => tags::TYPE_BUILTIN, |
228 | SelfType(_) | TypeParam(_) => "type", | 259 | SelfType(_) => tags::TYPE_SELF, |
260 | TypeParam(_) => tags::TYPE_PARAM, | ||
229 | Local(local) => { | 261 | Local(local) => { |
230 | if local.is_mut(db) { | 262 | if local.is_mut(db) { |
231 | "variable.mut" | 263 | tags::VARIABLE_MUT |
232 | } else if local.ty(db).is_mutable_reference() { | 264 | } else if local.ty(db).is_mutable_reference() { |
233 | "variable.mut" | 265 | tags::VARIABLE_MUT |
234 | } else { | 266 | } else { |
235 | "variable" | 267 | tags::VARIABLE |
236 | } | 268 | } |
237 | } | 269 | } |
238 | } | 270 | } |
@@ -255,8 +287,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
255 | .builtin { color: #DD6718; } | 287 | .builtin { color: #DD6718; } |
256 | .text { color: #DCDCCC; } | 288 | .text { color: #DCDCCC; } |
257 | .type { color: #7CB8BB; } | 289 | .type { color: #7CB8BB; } |
290 | .type\\.param { color: #20999D; } | ||
258 | .attribute { color: #94BFF3; } | 291 | .attribute { color: #94BFF3; } |
259 | .literal { color: #BFEBBF; } | 292 | .literal { color: #BFEBBF; } |
293 | .literal\\.numeric { color: #6A8759; } | ||
260 | .macro { color: #94BFF3; } | 294 | .macro { color: #94BFF3; } |
261 | .variable { color: #DCDCCC; } | 295 | .variable { color: #DCDCCC; } |
262 | .variable\\.mut { color: #DCDCCC; text-decoration: underline; } | 296 | .variable\\.mut { color: #DCDCCC; text-decoration: underline; } |