1import { withOpacity } from "../utils/color"
2import { ColorScheme, Layer, StyleSets } from "../themes/common/colorScheme"
3import { background, border, borderColor, foreground, text } from "./components"
4import hoverPopover from "./hoverPopover"
5
6import { buildSyntax } from "../themes/common/syntax"
7
8export default function editor(colorScheme: ColorScheme) {
9 const { isLight } = colorScheme
10 let layer = colorScheme.highest
11
12 const autocompleteItem = {
13 cornerRadius: 6,
14 padding: {
15 bottom: 2,
16 left: 6,
17 right: 6,
18 top: 2,
19 },
20 }
21
22 function diagnostic(layer: Layer, styleSet: StyleSets) {
23 return {
24 textScaleFactor: 0.857,
25 header: {
26 border: border(layer, {
27 top: true,
28 }),
29 },
30 message: {
31 text: text(layer, "sans", styleSet, "default", { size: "sm" }),
32 highlightText: text(layer, "sans", styleSet, "default", {
33 size: "sm",
34 weight: "bold",
35 }),
36 },
37 }
38 }
39
40 const syntax = buildSyntax(colorScheme)
41
42 return {
43 textColor: syntax.primary.color,
44 background: background(layer),
45 activeLineBackground: withOpacity(background(layer, "on"), 0.75),
46 highlightedLineBackground: background(layer, "on"),
47 // Inline autocomplete suggestions, Co-pilot suggestions, etc.
48 suggestion: syntax.predictive,
49 codeActions: {
50 indicator: {
51 color: foreground(layer, "variant"),
52
53 clicked: {
54 color: foreground(layer, "base"),
55 },
56 hover: {
57 color: foreground(layer, "on"),
58 },
59 active: {
60 color: foreground(layer, "on"),
61 },
62 },
63 verticalScale: 0.55,
64 },
65 folds: {
66 iconMarginScale: 2.5,
67 foldedIcon: "icons/chevron_right_8.svg",
68 foldableIcon: "icons/chevron_down_8.svg",
69 indicator: {
70 color: foreground(layer, "variant"),
71
72 clicked: {
73 color: foreground(layer, "base"),
74 },
75 hover: {
76 color: foreground(layer, "on"),
77 },
78 active: {
79 color: foreground(layer, "on"),
80 },
81 },
82 ellipses: {
83 textColor: colorScheme.ramps.neutral(0.71).hex(),
84 cornerRadiusFactor: 0.15,
85 background: {
86 // Copied from hover_popover highlight
87 color: colorScheme.ramps.neutral(0.5).alpha(0.0).hex(),
88
89 hover: {
90 color: colorScheme.ramps.neutral(0.5).alpha(0.5).hex(),
91 },
92
93 clicked: {
94 color: colorScheme.ramps.neutral(0.5).alpha(0.7).hex(),
95 },
96 },
97 },
98 foldBackground: foreground(layer, "variant"),
99 },
100 diff: {
101 deleted: isLight
102 ? colorScheme.ramps.red(0.5).hex()
103 : colorScheme.ramps.red(0.4).hex(),
104 modified: isLight
105 ? colorScheme.ramps.yellow(0.3).hex()
106 : colorScheme.ramps.yellow(0.5).hex(),
107 inserted: isLight
108 ? colorScheme.ramps.green(0.4).hex()
109 : colorScheme.ramps.green(0.5).hex(),
110 removedWidthEm: 0.275,
111 widthEm: 0.15,
112 cornerRadius: 0.05,
113 },
114 /** Highlights matching occurences of what is under the cursor
115 * as well as matched brackets
116 */
117 documentHighlightReadBackground: withOpacity(
118 foreground(layer, "accent"),
119 0.1
120 ),
121 documentHighlightWriteBackground: colorScheme.ramps
122 .neutral(0.5)
123 .alpha(0.4)
124 .hex(), // TODO: This was blend * 2
125 errorColor: background(layer, "negative"),
126 gutterBackground: background(layer),
127 gutterPaddingFactor: 3.5,
128 lineNumber: withOpacity(foreground(layer), 0.35),
129 lineNumberActive: foreground(layer),
130 renameFade: 0.6,
131 unnecessaryCodeFade: 0.5,
132 selection: colorScheme.players[0],
133 whitespace: colorScheme.ramps.neutral(0.5).hex(),
134 guestSelections: [
135 colorScheme.players[1],
136 colorScheme.players[2],
137 colorScheme.players[3],
138 colorScheme.players[4],
139 colorScheme.players[5],
140 colorScheme.players[6],
141 colorScheme.players[7],
142 ],
143 autocomplete: {
144 background: background(colorScheme.middle),
145 cornerRadius: 8,
146 padding: 4,
147 margin: {
148 left: -14,
149 },
150 border: border(colorScheme.middle),
151 shadow: colorScheme.popoverShadow,
152 matchHighlight: foreground(colorScheme.middle, "accent"),
153 item: autocompleteItem,
154 hoveredItem: {
155 ...autocompleteItem,
156 matchHighlight: foreground(
157 colorScheme.middle,
158 "accent",
159 "hovered"
160 ),
161 background: background(colorScheme.middle, "hovered"),
162 },
163 selectedItem: {
164 ...autocompleteItem,
165 matchHighlight: foreground(
166 colorScheme.middle,
167 "accent",
168 "active"
169 ),
170 background: background(colorScheme.middle, "active"),
171 },
172 },
173 diagnosticHeader: {
174 background: background(colorScheme.middle),
175 iconWidthFactor: 1.5,
176 textScaleFactor: 0.857,
177 border: border(colorScheme.middle, {
178 bottom: true,
179 top: true,
180 }),
181 code: {
182 ...text(colorScheme.middle, "mono", { size: "sm" }),
183 margin: {
184 left: 10,
185 },
186 },
187 source: {
188 text: text(colorScheme.middle, "sans", { size: "sm", weight: "bold", }),
189 },
190 message: {
191 highlightText: text(colorScheme.middle, "sans", {
192 size: "sm",
193 weight: "bold",
194 }),
195 text: text(colorScheme.middle, "sans", { size: "sm" }),
196 },
197 },
198 diagnosticPathHeader: {
199 background: background(colorScheme.middle),
200 textScaleFactor: 0.857,
201 filename: text(colorScheme.middle, "mono", { size: "sm" }),
202 path: {
203 ...text(colorScheme.middle, "mono", { size: "sm" }),
204 margin: {
205 left: 12,
206 },
207 },
208 },
209 errorDiagnostic: diagnostic(colorScheme.middle, "negative"),
210 warningDiagnostic: diagnostic(colorScheme.middle, "warning"),
211 informationDiagnostic: diagnostic(colorScheme.middle, "accent"),
212 hintDiagnostic: diagnostic(colorScheme.middle, "warning"),
213 invalidErrorDiagnostic: diagnostic(colorScheme.middle, "base"),
214 invalidHintDiagnostic: diagnostic(colorScheme.middle, "base"),
215 invalidInformationDiagnostic: diagnostic(colorScheme.middle, "base"),
216 invalidWarningDiagnostic: diagnostic(colorScheme.middle, "base"),
217 hoverPopover: hoverPopover(colorScheme),
218 linkDefinition: {
219 color: syntax.linkUri.color,
220 underline: syntax.linkUri.underline,
221 },
222 jumpIcon: {
223 color: foreground(layer, "on"),
224 iconWidth: 20,
225 buttonWidth: 20,
226 cornerRadius: 6,
227 padding: {
228 top: 6,
229 bottom: 6,
230 left: 6,
231 right: 6,
232 },
233 hover: {
234 background: background(layer, "on", "hovered"),
235 },
236 },
237 scrollbar: {
238 width: 12,
239 minHeightFactor: 1.0,
240 track: {
241 border: border(layer, "variant", { left: true }),
242 },
243 thumb: {
244 background: withOpacity(background(layer, "inverted"), 0.3),
245 border: {
246 width: 1,
247 color: borderColor(layer, "variant"),
248 top: false,
249 right: true,
250 left: true,
251 bottom: false,
252 },
253 },
254 git: {
255 deleted: isLight
256 ? withOpacity(colorScheme.ramps.red(0.5).hex(), 0.8)
257 : withOpacity(colorScheme.ramps.red(0.4).hex(), 0.8),
258 modified: isLight
259 ? withOpacity(colorScheme.ramps.yellow(0.5).hex(), 0.8)
260 : withOpacity(colorScheme.ramps.yellow(0.4).hex(), 0.8),
261 inserted: isLight
262 ? withOpacity(colorScheme.ramps.green(0.5).hex(), 0.8)
263 : withOpacity(colorScheme.ramps.green(0.4).hex(), 0.8),
264 }
265 },
266 compositionMark: {
267 underline: {
268 thickness: 1.0,
269 color: borderColor(layer),
270 },
271 },
272 syntax,
273 }
274}