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    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        guestSelections: [
127            colorScheme.players[1],
128            colorScheme.players[2],
129            colorScheme.players[3],
130            colorScheme.players[4],
131            colorScheme.players[5],
132            colorScheme.players[6],
133            colorScheme.players[7],
134        ],
135        autocomplete: {
136            background: background(colorScheme.middle),
137            cornerRadius: 8,
138            padding: 4,
139            margin: {
140                left: -14,
141            },
142            border: border(colorScheme.middle),
143            shadow: colorScheme.popoverShadow,
144            matchHighlight: foreground(colorScheme.middle, "accent"),
145            item: autocompleteItem,
146            hoveredItem: {
147                ...autocompleteItem,
148                matchHighlight: foreground(
149                    colorScheme.middle,
150                    "accent",
151                    "hovered"
152                ),
153                background: background(colorScheme.middle, "hovered"),
154            },
155            selectedItem: {
156                ...autocompleteItem,
157                matchHighlight: foreground(
158                    colorScheme.middle,
159                    "accent",
160                    "active"
161                ),
162                background: background(colorScheme.middle, "active"),
163            },
164        },
165        diagnosticHeader: {
166            background: background(colorScheme.middle),
167            iconWidthFactor: 1.5,
168            textScaleFactor: 0.857,
169            border: border(colorScheme.middle, {
170                bottom: true,
171                top: true,
172            }),
173            code: {
174                ...text(colorScheme.middle, "mono", { size: "sm" }),
175                margin: {
176                    left: 10,
177                },
178            },
179            source: {
180                text: text(colorScheme.middle, "sans", { size: "sm", weight: "bold", }),
181            },
182            message: {
183                highlightText: text(colorScheme.middle, "sans", {
184                    size: "sm",
185                    weight: "bold",
186                }),
187                text: text(colorScheme.middle, "sans", { size: "sm" }),
188            },
189        },
190        diagnosticPathHeader: {
191            background: background(colorScheme.middle),
192            textScaleFactor: 0.857,
193            filename: text(colorScheme.middle, "mono", { size: "sm" }),
194            path: {
195                ...text(colorScheme.middle, "mono", { size: "sm" }),
196                margin: {
197                    left: 12,
198                },
199            },
200        },
201        errorDiagnostic: diagnostic(colorScheme.middle, "negative"),
202        warningDiagnostic: diagnostic(colorScheme.middle, "warning"),
203        informationDiagnostic: diagnostic(colorScheme.middle, "accent"),
204        hintDiagnostic: diagnostic(colorScheme.middle, "warning"),
205        invalidErrorDiagnostic: diagnostic(colorScheme.middle, "base"),
206        invalidHintDiagnostic: diagnostic(colorScheme.middle, "base"),
207        invalidInformationDiagnostic: diagnostic(colorScheme.middle, "base"),
208        invalidWarningDiagnostic: diagnostic(colorScheme.middle, "base"),
209        hoverPopover: hoverPopover(colorScheme),
210        linkDefinition: {
211            color: syntax.linkUri.color,
212            underline: syntax.linkUri.underline,
213        },
214        jumpIcon: {
215            color: foreground(layer, "on"),
216            iconWidth: 20,
217            buttonWidth: 20,
218            cornerRadius: 6,
219            padding: {
220                top: 6,
221                bottom: 6,
222                left: 6,
223                right: 6,
224            },
225            hover: {
226                background: background(layer, "on", "hovered"),
227            },
228        },
229        scrollbar: {
230            width: 12,
231            minHeightFactor: 1.0,
232            track: {
233                border: border(layer, "variant", { left: true }),
234            },
235            thumb: {
236                background: withOpacity(background(layer, "inverted"), 0.4),
237                border: {
238                    width: 1,
239                    color: borderColor(layer, "variant"),
240                },
241            },
242        },
243        compositionMark: {
244            underline: {
245                thickness: 1.0,
246                color: borderColor(layer),
247            },
248        },
249        syntax,
250    }
251}