diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-02-27 08:32:44 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-02-27 08:32:44 +0000 |
commit | 2180591593b4285b1765eb105c285c82727b2a6f (patch) | |
tree | ea276adbcf0c3fac4b457a2af49a2a7782585b87 /crates/ra_ide/src/syntax_highlighting/highlight.rs | |
parent | ac52a4109f6ada3241d84fd89ad28420bdfad335 (diff) | |
parent | a8e68ff814801a72ecac6cd918a3e7fbb25d11c0 (diff) |
Merge #3335
3335: Refactor highlighting a bit r=matklad a=matklad
bors r+
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_ide/src/syntax_highlighting/highlight.rs')
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting/highlight.rs | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting/highlight.rs b/crates/ra_ide/src/syntax_highlighting/highlight.rs new file mode 100644 index 000000000..383c74c98 --- /dev/null +++ b/crates/ra_ide/src/syntax_highlighting/highlight.rs | |||
@@ -0,0 +1,163 @@ | |||
1 | //! Defines token tags we use for syntax highlighting. | ||
2 | //! A tag is not unlike a CSS class. | ||
3 | |||
4 | use std::{fmt, ops}; | ||
5 | |||
6 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
7 | pub struct Highlight { | ||
8 | pub tag: HighlightTag, | ||
9 | pub modifiers: HighlightModifiers, | ||
10 | } | ||
11 | |||
12 | #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
13 | pub struct HighlightModifiers(u32); | ||
14 | |||
15 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
16 | pub enum HighlightTag { | ||
17 | Field, | ||
18 | Function, | ||
19 | Module, | ||
20 | Constant, | ||
21 | Macro, | ||
22 | Variable, | ||
23 | |||
24 | Type, | ||
25 | TypeSelf, | ||
26 | TypeParam, | ||
27 | TypeLifetime, | ||
28 | |||
29 | LiteralByte, | ||
30 | LiteralNumeric, | ||
31 | LiteralChar, | ||
32 | |||
33 | Comment, | ||
34 | LiteralString, | ||
35 | Attribute, | ||
36 | |||
37 | Keyword, | ||
38 | } | ||
39 | |||
40 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
41 | #[repr(u8)] | ||
42 | pub enum HighlightModifier { | ||
43 | Mutable = 0, | ||
44 | Unsafe, | ||
45 | /// Used with keywords like `if` and `break`. | ||
46 | Control, | ||
47 | Builtin, | ||
48 | } | ||
49 | |||
50 | impl HighlightTag { | ||
51 | fn as_str(self) -> &'static str { | ||
52 | match self { | ||
53 | HighlightTag::Field => "field", | ||
54 | HighlightTag::Function => "function", | ||
55 | HighlightTag::Module => "module", | ||
56 | HighlightTag::Constant => "constant", | ||
57 | HighlightTag::Macro => "macro", | ||
58 | HighlightTag::Variable => "variable", | ||
59 | HighlightTag::Type => "type", | ||
60 | HighlightTag::TypeSelf => "type.self", | ||
61 | HighlightTag::TypeParam => "type.param", | ||
62 | HighlightTag::TypeLifetime => "type.lifetime", | ||
63 | HighlightTag::LiteralByte => "literal.byte", | ||
64 | HighlightTag::LiteralNumeric => "literal.numeric", | ||
65 | HighlightTag::LiteralChar => "literal.char", | ||
66 | HighlightTag::Comment => "comment", | ||
67 | HighlightTag::LiteralString => "string", | ||
68 | HighlightTag::Attribute => "attribute", | ||
69 | HighlightTag::Keyword => "keyword", | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | impl fmt::Display for HighlightTag { | ||
75 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
76 | fmt::Display::fmt(self.as_str(), f) | ||
77 | } | ||
78 | } | ||
79 | |||
80 | impl HighlightModifier { | ||
81 | const ALL: &'static [HighlightModifier] = &[ | ||
82 | HighlightModifier::Mutable, | ||
83 | HighlightModifier::Unsafe, | ||
84 | HighlightModifier::Control, | ||
85 | HighlightModifier::Builtin, | ||
86 | ]; | ||
87 | |||
88 | fn as_str(self) -> &'static str { | ||
89 | match self { | ||
90 | HighlightModifier::Mutable => "mutable", | ||
91 | HighlightModifier::Unsafe => "unsafe", | ||
92 | HighlightModifier::Control => "control", | ||
93 | HighlightModifier::Builtin => "builtin", | ||
94 | } | ||
95 | } | ||
96 | |||
97 | fn mask(self) -> u32 { | ||
98 | 1 << (self as u32) | ||
99 | } | ||
100 | } | ||
101 | |||
102 | impl fmt::Display for HighlightModifier { | ||
103 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
104 | fmt::Display::fmt(self.as_str(), f) | ||
105 | } | ||
106 | } | ||
107 | |||
108 | impl fmt::Display for Highlight { | ||
109 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
110 | write!(f, "{}", self.tag)?; | ||
111 | for modifier in self.modifiers.iter() { | ||
112 | write!(f, ".{}", modifier)? | ||
113 | } | ||
114 | Ok(()) | ||
115 | } | ||
116 | } | ||
117 | |||
118 | impl From<HighlightTag> for Highlight { | ||
119 | fn from(tag: HighlightTag) -> Highlight { | ||
120 | Highlight::new(tag) | ||
121 | } | ||
122 | } | ||
123 | |||
124 | impl Highlight { | ||
125 | pub(crate) fn new(tag: HighlightTag) -> Highlight { | ||
126 | Highlight { tag, modifiers: HighlightModifiers::default() } | ||
127 | } | ||
128 | } | ||
129 | |||
130 | impl ops::BitOr<HighlightModifier> for HighlightTag { | ||
131 | type Output = Highlight; | ||
132 | |||
133 | fn bitor(self, rhs: HighlightModifier) -> Highlight { | ||
134 | Highlight::new(self) | rhs | ||
135 | } | ||
136 | } | ||
137 | |||
138 | impl ops::BitOrAssign<HighlightModifier> for HighlightModifiers { | ||
139 | fn bitor_assign(&mut self, rhs: HighlightModifier) { | ||
140 | self.0 |= rhs.mask(); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | impl ops::BitOrAssign<HighlightModifier> for Highlight { | ||
145 | fn bitor_assign(&mut self, rhs: HighlightModifier) { | ||
146 | self.modifiers |= rhs; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | impl ops::BitOr<HighlightModifier> for Highlight { | ||
151 | type Output = Highlight; | ||
152 | |||
153 | fn bitor(mut self, rhs: HighlightModifier) -> Highlight { | ||
154 | self |= rhs; | ||
155 | self | ||
156 | } | ||
157 | } | ||
158 | |||
159 | impl HighlightModifiers { | ||
160 | pub fn iter(self) -> impl Iterator<Item = HighlightModifier> { | ||
161 | HighlightModifier::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask()) | ||
162 | } | ||
163 | } | ||