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