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