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: {
 48            color: syntax.predictive.color,
 49        },
 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: foreground(layer, "negative"),
103            modified: foreground(layer, "warning"),
104            inserted: foreground(layer, "positive"),
105            removedWidthEm: 0.275,
106            widthEm: 0.22,
107            cornerRadius: 0.2,
108        },
109        /** Highlights matching occurences of what is under the cursor
110         * as well as matched brackets
111         */
112        documentHighlightReadBackground: withOpacity(
113            foreground(layer, "accent"),
114            0.1
115        ),
116        documentHighlightWriteBackground: colorScheme.ramps
117            .neutral(0.5)
118            .alpha(0.4)
119            .hex(), // TODO: This was blend * 2
120        errorColor: background(layer, "negative"),
121        gutterBackground: background(layer),
122        gutterPaddingFactor: 3.5,
123        lineNumber: withOpacity(foreground(layer), 0.35),
124        lineNumberActive: foreground(layer),
125        renameFade: 0.6,
126        unnecessaryCodeFade: 0.5,
127        selection: colorScheme.players[0],
128        guestSelections: [
129            colorScheme.players[1],
130            colorScheme.players[2],
131            colorScheme.players[3],
132            colorScheme.players[4],
133            colorScheme.players[5],
134            colorScheme.players[6],
135            colorScheme.players[7],
136        ],
137        autocomplete: {
138            background: background(colorScheme.middle),
139            cornerRadius: 8,
140            padding: 4,
141            margin: {
142                left: -14,
143            },
144            border: border(colorScheme.middle),
145            shadow: colorScheme.popoverShadow,
146            matchHighlight: foreground(colorScheme.middle, "accent"),
147            item: autocompleteItem,
148            hoveredItem: {
149                ...autocompleteItem,
150                matchHighlight: foreground(
151                    colorScheme.middle,
152                    "accent",
153                    "hovered"
154                ),
155                background: background(colorScheme.middle, "hovered"),
156            },
157            selectedItem: {
158                ...autocompleteItem,
159                matchHighlight: foreground(
160                    colorScheme.middle,
161                    "accent",
162                    "active"
163                ),
164                background: background(colorScheme.middle, "active"),
165            },
166        },
167        diagnosticHeader: {
168            background: background(colorScheme.middle),
169            iconWidthFactor: 1.5,
170            textScaleFactor: 0.857,
171            border: border(colorScheme.middle, {
172                bottom: true,
173                top: true,
174            }),
175            code: {
176                ...text(colorScheme.middle, "mono", { size: "sm" }),
177                margin: {
178                    left: 10,
179                },
180            },
181            message: {
182                highlightText: text(colorScheme.middle, "sans", {
183                    size: "sm",
184                    weight: "bold",
185                }),
186                text: text(colorScheme.middle, "sans", { size: "sm" }),
187            },
188        },
189        diagnosticPathHeader: {
190            background: background(colorScheme.middle),
191            textScaleFactor: 0.857,
192            filename: text(colorScheme.middle, "mono", { size: "sm" }),
193            path: {
194                ...text(colorScheme.middle, "mono", { size: "sm" }),
195                margin: {
196                    left: 12,
197                },
198            },
199        },
200        errorDiagnostic: diagnostic(colorScheme.middle, "negative"),
201        warningDiagnostic: diagnostic(colorScheme.middle, "warning"),
202        informationDiagnostic: diagnostic(colorScheme.middle, "accent"),
203        hintDiagnostic: diagnostic(colorScheme.middle, "warning"),
204        invalidErrorDiagnostic: diagnostic(colorScheme.middle, "base"),
205        invalidHintDiagnostic: diagnostic(colorScheme.middle, "base"),
206        invalidInformationDiagnostic: diagnostic(colorScheme.middle, "base"),
207        invalidWarningDiagnostic: diagnostic(colorScheme.middle, "base"),
208        hoverPopover: hoverPopover(colorScheme),
209        linkDefinition: {
210            color: syntax.linkUri.color,
211            underline: syntax.linkUri.underline,
212        },
213        jumpIcon: {
214            color: foreground(layer, "on"),
215            iconWidth: 20,
216            buttonWidth: 20,
217            cornerRadius: 6,
218            padding: {
219                top: 6,
220                bottom: 6,
221                left: 6,
222                right: 6,
223            },
224            hover: {
225                background: background(layer, "on", "hovered"),
226            },
227        },
228        scrollbar: {
229            width: 12,
230            minHeightFactor: 1.0,
231            track: {
232                border: border(layer, "variant", { left: true }),
233            },
234            thumb: {
235                background: withOpacity(background(layer, "inverted"), 0.4),
236                border: {
237                    width: 1,
238                    color: borderColor(layer, "variant"),
239                },
240            },
241        },
242        compositionMark: {
243            underline: {
244                thickness: 1.0,
245                color: borderColor(layer),
246            },
247        },
248        syntax,
249    }
250}