diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_ide/src/syntax_highlighting.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_ide/src/syntax_highlighting.rs')
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 129 |
1 files changed, 85 insertions, 44 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 9a3e4c82f..0228ee7e9 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | 4 | ||
5 | use hir::{Name, Source}; | 5 | use hir::{InFile, Name}; |
6 | use ra_db::SourceDatabase; | 6 | use ra_db::SourceDatabase; |
7 | use ra_prof::profile; | 7 | use ra_prof::profile; |
8 | use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T}; | 8 | use ra_syntax::{ast, AstNode, Direction, SyntaxElement, SyntaxKind, SyntaxKind::*, TextRange, T}; |
@@ -16,6 +16,34 @@ use crate::{ | |||
16 | FileId, | 16 | FileId, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | pub mod tags { | ||
20 | pub(crate) const FIELD: &str = "field"; | ||
21 | pub(crate) const FUNCTION: &str = "function"; | ||
22 | pub(crate) const MODULE: &str = "module"; | ||
23 | pub(crate) const TYPE: &str = "type"; | ||
24 | pub(crate) const CONSTANT: &str = "constant"; | ||
25 | pub(crate) const MACRO: &str = "macro"; | ||
26 | pub(crate) const VARIABLE: &str = "variable"; | ||
27 | pub(crate) const VARIABLE_MUT: &str = "variable.mut"; | ||
28 | pub(crate) const TEXT: &str = "text"; | ||
29 | |||
30 | pub(crate) const TYPE_BUILTIN: &str = "type.builtin"; | ||
31 | pub(crate) const TYPE_SELF: &str = "type.self"; | ||
32 | pub(crate) const TYPE_PARAM: &str = "type.param"; | ||
33 | pub(crate) const TYPE_LIFETIME: &str = "type.lifetime"; | ||
34 | |||
35 | pub(crate) const LITERAL_BYTE: &str = "literal.byte"; | ||
36 | pub(crate) const LITERAL_NUMERIC: &str = "literal.numeric"; | ||
37 | pub(crate) const LITERAL_CHAR: &str = "literal.char"; | ||
38 | pub(crate) const LITERAL_COMMENT: &str = "comment"; | ||
39 | pub(crate) const LITERAL_STRING: &str = "string"; | ||
40 | pub(crate) const LITERAL_ATTRIBUTE: &str = "attribute"; | ||
41 | |||
42 | pub(crate) const KEYWORD_UNSAFE: &str = "keyword.unsafe"; | ||
43 | pub(crate) const KEYWORD_CONTROL: &str = "keyword.control"; | ||
44 | pub(crate) const KEYWORD: &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,17 +99,16 @@ 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, |
105 | // Special-case field init shorthand | ||
106 | NAME_REF if node.parent().and_then(ast::RecordField::cast).is_some() => tags::FIELD, | ||
107 | NAME_REF if node.ancestors().any(|it| it.kind() == ATTR) => continue, | ||
77 | NAME_REF => { | 108 | NAME_REF => { |
78 | if node.ancestors().any(|it| it.kind() == ATTR) { | ||
79 | continue; | ||
80 | } | ||
81 | |||
82 | let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); | 109 | let name_ref = node.as_node().cloned().and_then(ast::NameRef::cast).unwrap(); |
83 | let name_kind = | 110 | let name_kind = |
84 | classify_name_ref(db, Source::new(file_id.into(), &name_ref)).map(|d| d.kind); | 111 | classify_name_ref(db, InFile::new(file_id.into(), &name_ref)).map(|d| d.kind); |
85 | 112 | ||
86 | if let Some(Local(local)) = &name_kind { | 113 | if let Some(Local(local)) = &name_kind { |
87 | if let Some(name) = local.name(db) { | 114 | if let Some(name) = local.name(db) { |
@@ -90,12 +117,12 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
90 | } | 117 | } |
91 | }; | 118 | }; |
92 | 119 | ||
93 | name_kind.map_or("text", |it| highlight_name(db, it)) | 120 | name_kind.map_or(tags::TEXT, |it| highlight_name(db, it)) |
94 | } | 121 | } |
95 | NAME => { | 122 | NAME => { |
96 | let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap(); | 123 | let name = node.as_node().cloned().and_then(ast::Name::cast).unwrap(); |
97 | let name_kind = | 124 | let name_kind = |
98 | classify_name(db, Source::new(file_id.into(), &name)).map(|d| d.kind); | 125 | classify_name(db, InFile::new(file_id.into(), &name)).map(|d| d.kind); |
99 | 126 | ||
100 | if let Some(Local(local)) = &name_kind { | 127 | if let Some(Local(local)) = &name_kind { |
101 | if let Some(name) = local.name(db) { | 128 | if let Some(name) = local.name(db) { |
@@ -107,18 +134,21 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
107 | 134 | ||
108 | match name_kind { | 135 | match name_kind { |
109 | Some(name_kind) => highlight_name(db, name_kind), | 136 | Some(name_kind) => highlight_name(db, name_kind), |
110 | None => name.syntax().parent().map_or("function", |x| match x.kind() { | 137 | 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", | 138 | STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_ALIAS_DEF => tags::TYPE, |
112 | RECORD_FIELD_DEF => "field", | 139 | TYPE_PARAM => tags::TYPE_PARAM, |
113 | _ => "function", | 140 | RECORD_FIELD_DEF => tags::FIELD, |
141 | _ => tags::FUNCTION, | ||
114 | }), | 142 | }), |
115 | } | 143 | } |
116 | } | 144 | } |
117 | INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE => "literal", | 145 | INT_NUMBER | FLOAT_NUMBER => tags::LITERAL_NUMERIC, |
118 | LIFETIME => "parameter", | 146 | BYTE => tags::LITERAL_BYTE, |
119 | T![unsafe] => "keyword.unsafe", | 147 | CHAR => tags::LITERAL_CHAR, |
120 | k if is_control_keyword(k) => "keyword.control", | 148 | LIFETIME => tags::TYPE_LIFETIME, |
121 | k if k.is_keyword() => "keyword", | 149 | T![unsafe] => tags::KEYWORD_UNSAFE, |
150 | k if is_control_keyword(k) => tags::KEYWORD_CONTROL, | ||
151 | k if k.is_keyword() => tags::KEYWORD, | ||
122 | _ => { | 152 | _ => { |
123 | if let Some(macro_call) = node.as_node().cloned().and_then(ast::MacroCall::cast) { | 153 | if let Some(macro_call) = node.as_node().cloned().and_then(ast::MacroCall::cast) { |
124 | if let Some(path) = macro_call.path() { | 154 | if let Some(path) = macro_call.path() { |
@@ -135,7 +165,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa | |||
135 | } | 165 | } |
136 | res.push(HighlightedRange { | 166 | res.push(HighlightedRange { |
137 | range: TextRange::from_to(range_start, range_end), | 167 | range: TextRange::from_to(range_start, range_end), |
138 | tag: "macro", | 168 | tag: tags::MACRO, |
139 | binding_hash: None, | 169 | binding_hash: None, |
140 | }) | 170 | }) |
141 | } | 171 | } |
@@ -211,29 +241,27 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo | |||
211 | 241 | ||
212 | fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str { | 242 | fn highlight_name(db: &RootDatabase, name_kind: NameKind) -> &'static str { |
213 | match name_kind { | 243 | match name_kind { |
214 | Macro(_) => "macro", | 244 | Macro(_) => tags::MACRO, |
215 | Field(_) => "field", | 245 | Field(_) => tags::FIELD, |
216 | AssocItem(hir::AssocItem::Function(_)) => "function", | 246 | AssocItem(hir::AssocItem::Function(_)) => tags::FUNCTION, |
217 | AssocItem(hir::AssocItem::Const(_)) => "constant", | 247 | AssocItem(hir::AssocItem::Const(_)) => tags::CONSTANT, |
218 | AssocItem(hir::AssocItem::TypeAlias(_)) => "type", | 248 | AssocItem(hir::AssocItem::TypeAlias(_)) => tags::TYPE, |
219 | Def(hir::ModuleDef::Module(_)) => "module", | 249 | Def(hir::ModuleDef::Module(_)) => tags::MODULE, |
220 | Def(hir::ModuleDef::Function(_)) => "function", | 250 | Def(hir::ModuleDef::Function(_)) => tags::FUNCTION, |
221 | Def(hir::ModuleDef::Adt(_)) => "type", | 251 | Def(hir::ModuleDef::Adt(_)) => tags::TYPE, |
222 | Def(hir::ModuleDef::EnumVariant(_)) => "constant", | 252 | Def(hir::ModuleDef::EnumVariant(_)) => tags::CONSTANT, |
223 | Def(hir::ModuleDef::Const(_)) => "constant", | 253 | Def(hir::ModuleDef::Const(_)) => tags::CONSTANT, |
224 | Def(hir::ModuleDef::Static(_)) => "constant", | 254 | Def(hir::ModuleDef::Static(_)) => tags::CONSTANT, |
225 | Def(hir::ModuleDef::Trait(_)) => "type", | 255 | Def(hir::ModuleDef::Trait(_)) => tags::TYPE, |
226 | Def(hir::ModuleDef::TypeAlias(_)) => "type", | 256 | Def(hir::ModuleDef::TypeAlias(_)) => tags::TYPE, |
227 | Def(hir::ModuleDef::BuiltinType(_)) => "type", | 257 | Def(hir::ModuleDef::BuiltinType(_)) => tags::TYPE_BUILTIN, |
228 | SelfType(_) => "type", | 258 | SelfType(_) => tags::TYPE_SELF, |
229 | GenericParam(_) => "type", | 259 | TypeParam(_) => tags::TYPE_PARAM, |
230 | Local(local) => { | 260 | Local(local) => { |
231 | if local.is_mut(db) { | 261 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { |
232 | "variable.mut" | 262 | tags::VARIABLE_MUT |
233 | } else if local.ty(db).is_mutable_reference() { | ||
234 | "variable.mut" | ||
235 | } else { | 263 | } else { |
236 | "variable" | 264 | tags::VARIABLE |
237 | } | 265 | } |
238 | } | 266 | } |
239 | } | 267 | } |
@@ -251,12 +279,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
251 | 279 | ||
252 | .comment { color: #7F9F7F; } | 280 | .comment { color: #7F9F7F; } |
253 | .string { color: #CC9393; } | 281 | .string { color: #CC9393; } |
282 | .field { color: #94BFF3; } | ||
254 | .function { color: #93E0E3; } | 283 | .function { color: #93E0E3; } |
255 | .parameter { color: #94BFF3; } | 284 | .parameter { color: #94BFF3; } |
256 | .builtin { color: #DD6718; } | ||
257 | .text { color: #DCDCCC; } | 285 | .text { color: #DCDCCC; } |
286 | .type { color: #7CB8BB; } | ||
287 | .type\\.builtin { color: #8CD0D3; } | ||
288 | .type\\.param { color: #20999D; } | ||
258 | .attribute { color: #94BFF3; } | 289 | .attribute { color: #94BFF3; } |
259 | .literal { color: #BFEBBF; } | 290 | .literal { color: #BFEBBF; } |
291 | .literal\\.numeric { color: #6A8759; } | ||
260 | .macro { color: #94BFF3; } | 292 | .macro { color: #94BFF3; } |
261 | .variable { color: #DCDCCC; } | 293 | .variable { color: #DCDCCC; } |
262 | .variable\\.mut { color: #DCDCCC; text-decoration: underline; } | 294 | .variable\\.mut { color: #DCDCCC; text-decoration: underline; } |
@@ -293,7 +325,8 @@ fn main() { | |||
293 | 325 | ||
294 | let mut vec = Vec::new(); | 326 | let mut vec = Vec::new(); |
295 | if true { | 327 | if true { |
296 | vec.push(Foo { x: 0, y: 1 }); | 328 | let x = 92; |
329 | vec.push(Foo { x, y: 1 }); | ||
297 | } | 330 | } |
298 | unsafe { vec.set_len(0); } | 331 | unsafe { vec.set_len(0); } |
299 | 332 | ||
@@ -303,6 +336,14 @@ fn main() { | |||
303 | 336 | ||
304 | y; | 337 | y; |
305 | } | 338 | } |
339 | |||
340 | enum E<X> { | ||
341 | V(X) | ||
342 | } | ||
343 | |||
344 | impl<X> E<X> { | ||
345 | fn new<T>() -> E<T> {} | ||
346 | } | ||
306 | "# | 347 | "# |
307 | .trim(), | 348 | .trim(), |
308 | ); | 349 | ); |