editor.ts

  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                },
249            },
250            git: {
251                deleted: isLight
252                    ? withOpacity(colorScheme.ramps.red(0.5).hex(), 0.8)
253                    : withOpacity(colorScheme.ramps.red(0.4).hex(), 0.8),
254                modified: isLight
255                    ? withOpacity(colorScheme.ramps.yellow(0.5).hex(), 0.8)
256                    : withOpacity(colorScheme.ramps.yellow(0.4).hex(), 0.8),
257                inserted: isLight
258                    ? withOpacity(colorScheme.ramps.green(0.5).hex(), 0.8)
259                    : withOpacity(colorScheme.ramps.green(0.4).hex(), 0.8),
260            }
261        },
262        compositionMark: {
263            underline: {
264                thickness: 1.0,
265                color: borderColor(layer),
266            },
267        },
268        syntax,
269    }
270}