editor.ts

  1import { with_opacity } from "../theme/color"
  2import { Layer, StyleSets } from "../theme/create_theme"
  3import {
  4    background,
  5    border,
  6    border_color,
  7    foreground,
  8    text,
  9} from "./components"
 10import hover_popover from "./hover_popover"
 11
 12import { build_syntax } from "../theme/syntax"
 13import { interactive, toggleable } from "../element"
 14import { useTheme } from "../theme"
 15
 16export default function editor(): any {
 17    const theme = useTheme()
 18
 19    const { is_light } = theme
 20
 21    const layer = theme.highest
 22
 23    const autocomplete_item = {
 24        corner_radius: 6,
 25        padding: {
 26            bottom: 2,
 27            left: 6,
 28            right: 6,
 29            top: 2,
 30        },
 31    }
 32
 33    function diagnostic(layer: Layer, style_set: StyleSets) {
 34        return {
 35            text_scale_factor: 0.857,
 36            header: {
 37                border: border(layer, {
 38                    top: true,
 39                }),
 40            },
 41            message: {
 42                text: text(layer, "sans", style_set, "default", { size: "sm" }),
 43                highlight_text: text(layer, "sans", style_set, "default", {
 44                    size: "sm",
 45                    weight: "bold",
 46                }),
 47            },
 48        }
 49    }
 50
 51    const syntax = build_syntax()
 52
 53    return {
 54        text_color: syntax.primary.color,
 55        background: background(layer),
 56        active_line_background: with_opacity(background(layer, "on"), 0.75),
 57        highlighted_line_background: background(layer, "on"),
 58        // Inline autocomplete suggestions, Co-pilot suggestions, etc.
 59        hint: syntax.hint,
 60        suggestion: syntax.predictive,
 61        code_actions: {
 62            indicator: toggleable({
 63                base: interactive({
 64                    base: {
 65                        color: foreground(layer, "variant"),
 66                    },
 67                    state: {
 68                        hovered: {
 69                            color: foreground(layer, "variant", "hovered"),
 70                        },
 71                        clicked: {
 72                            color: foreground(layer, "variant", "pressed"),
 73                        },
 74                    },
 75                }),
 76                state: {
 77                    active: {
 78                        default: {
 79                            color: foreground(layer, "accent"),
 80                        },
 81                        hovered: {
 82                            color: foreground(layer, "accent", "hovered"),
 83                        },
 84                        clicked: {
 85                            color: foreground(layer, "accent", "pressed"),
 86                        },
 87                    },
 88                },
 89            }),
 90
 91            vertical_scale: 0.55,
 92        },
 93        folds: {
 94            icon_margin_scale: 4,
 95            folded_icon: "icons/chevron_right.svg",
 96            foldable_icon: "icons/chevron_down.svg",
 97            indicator: toggleable({
 98                base: interactive({
 99                    base: {
100                        color: foreground(layer, "variant"),
101                    },
102                    state: {
103                        hovered: {
104                            color: foreground(layer, "on"),
105                        },
106                        clicked: {
107                            color: foreground(layer, "base"),
108                        },
109                    },
110                }),
111                state: {
112                    active: {
113                        default: {
114                            color: foreground(layer, "default"),
115                        },
116                        hovered: {
117                            color: foreground(layer, "on"),
118                        },
119                    },
120                },
121            }),
122            ellipses: {
123                text_color: theme.ramps.neutral(0.71).hex(),
124                corner_radius_factor: 0.15,
125                background: {
126                    // Copied from hover_popover highlight
127                    default: {
128                        color: theme.ramps.neutral(0.5).alpha(0.0).hex(),
129                    },
130
131                    hovered: {
132                        color: theme.ramps.neutral(0.5).alpha(0.5).hex(),
133                    },
134
135                    clicked: {
136                        color: theme.ramps.neutral(0.5).alpha(0.7).hex(),
137                    },
138                },
139            },
140            fold_background: foreground(layer, "variant"),
141        },
142        diff: {
143            deleted: is_light
144                ? theme.ramps.red(0.5).hex()
145                : theme.ramps.red(0.4).hex(),
146            modified: is_light
147                ? theme.ramps.yellow(0.5).hex()
148                : theme.ramps.yellow(0.5).hex(),
149            inserted: is_light
150                ? theme.ramps.green(0.4).hex()
151                : theme.ramps.green(0.5).hex(),
152            removed_width_em: 0.275,
153            width_em: 0.15,
154            corner_radius: 0.05,
155        },
156        /** Highlights matching occurrences of what is under the cursor
157         * as well as matched brackets
158         */
159        document_highlight_read_background: with_opacity(
160            foreground(layer, "accent"),
161            0.1
162        ),
163        document_highlight_write_background: theme.ramps
164            .neutral(0.5)
165            .alpha(0.4)
166            .hex(), // TODO: This was blend * 2
167        error_color: background(layer, "negative"),
168        gutter_background: background(layer),
169        gutter_padding_factor: 3.5,
170        line_number: with_opacity(foreground(layer), 0.35),
171        line_number_active: foreground(layer),
172        rename_fade: 0.6,
173        wrap_guide: with_opacity(foreground(layer), 0.05),
174        active_wrap_guide: with_opacity(foreground(layer), 0.1),
175        unnecessary_code_fade: 0.5,
176        selection: theme.players[0],
177        whitespace: theme.ramps.neutral(0.5).hex(),
178        guest_selections: [
179            theme.players[1],
180            theme.players[2],
181            theme.players[3],
182            theme.players[4],
183            theme.players[5],
184            theme.players[6],
185            theme.players[7],
186        ],
187        absent_selection: theme.players[7],
188        autocomplete: {
189            background: background(theme.middle),
190            corner_radius: 8,
191            padding: 4,
192            margin: {
193                left: -14,
194            },
195            border: border(theme.middle),
196            shadow: theme.popover_shadow,
197            match_highlight: foreground(theme.middle, "accent"),
198            item: autocomplete_item,
199            hovered_item: {
200                ...autocomplete_item,
201                match_highlight: foreground(theme.middle, "accent", "hovered"),
202                background: background(theme.middle, "hovered"),
203            },
204            selected_item: {
205                ...autocomplete_item,
206                match_highlight: foreground(theme.middle, "accent", "active"),
207                background: background(theme.middle, "active"),
208            },
209            completion_min_width: 300,
210            completion_max_width: 700,
211            inline_docs_container: { padding: { left: 40 } },
212            inline_docs_color: text(theme.middle, "sans", "disabled", {}).color,
213            inline_docs_size_percent: 0.75,
214            alongside_docs_max_width: 700,
215            alongside_docs_container: { padding: autocomplete_item.padding }
216        },
217        diagnostic_header: {
218            background: background(theme.middle),
219            icon_width_factor: 1.5,
220            text_scale_factor: 0.857,
221            border: border(theme.middle, {
222                bottom: true,
223                top: true,
224            }),
225            code: {
226                ...text(theme.middle, "mono", { size: "sm" }),
227                margin: {
228                    left: 10,
229                },
230            },
231            source: {
232                text: text(theme.middle, "sans", {
233                    size: "sm",
234                    weight: "bold",
235                }),
236            },
237            message: {
238                highlight_text: text(theme.middle, "sans", {
239                    size: "sm",
240                    weight: "bold",
241                }),
242                text: text(theme.middle, "sans", { size: "sm" }),
243            },
244        },
245        diagnostic_path_header: {
246            background: background(theme.middle),
247            text_scale_factor: 0.857,
248            filename: text(theme.middle, "mono", { size: "sm" }),
249            path: {
250                ...text(theme.middle, "mono", { size: "sm" }),
251                margin: {
252                    left: 12,
253                },
254            },
255        },
256        error_diagnostic: diagnostic(theme.middle, "negative"),
257        warning_diagnostic: diagnostic(theme.middle, "warning"),
258        information_diagnostic: diagnostic(theme.middle, "accent"),
259        hint_diagnostic: diagnostic(theme.middle, "warning"),
260        invalid_error_diagnostic: diagnostic(theme.middle, "base"),
261        invalid_hint_diagnostic: diagnostic(theme.middle, "base"),
262        invalid_information_diagnostic: diagnostic(theme.middle, "base"),
263        invalid_warning_diagnostic: diagnostic(theme.middle, "base"),
264        hover_popover: hover_popover(),
265        link_definition: {
266            color: syntax.link_uri.color,
267            underline: syntax.link_uri.underline,
268        },
269        jump_icon: interactive({
270            base: {
271                color: foreground(layer, "on"),
272                icon_width: 20,
273                button_width: 20,
274                corner_radius: 6,
275                padding: {
276                    top: 6,
277                    bottom: 6,
278                    left: 6,
279                    right: 6,
280                },
281            },
282            state: {
283                hovered: {
284                    background: background(layer, "on", "hovered"),
285                },
286            },
287        }),
288
289        scrollbar: {
290            width: 12,
291            min_height_factor: 1.0,
292            track: {
293                border: border(layer, "variant", { left: true }),
294            },
295            thumb: {
296                background: with_opacity(background(layer, "inverted"), 0.3),
297                border: {
298                    width: 1,
299                    color: border_color(layer, "variant"),
300                    top: false,
301                    right: true,
302                    left: true,
303                    bottom: false,
304                },
305            },
306            git: {
307                deleted: is_light
308                    ? with_opacity(theme.ramps.red(0.5).hex(), 0.8)
309                    : with_opacity(theme.ramps.red(0.4).hex(), 0.8),
310                modified: is_light
311                    ? with_opacity(theme.ramps.yellow(0.5).hex(), 0.8)
312                    : with_opacity(theme.ramps.yellow(0.4).hex(), 0.8),
313                inserted: is_light
314                    ? with_opacity(theme.ramps.green(0.5).hex(), 0.8)
315                    : with_opacity(theme.ramps.green(0.4).hex(), 0.8),
316            },
317            selections: foreground(layer, "accent"),
318        },
319        composition_mark: {
320            underline: {
321                thickness: 1.0,
322                color: border_color(layer),
323            },
324        },
325        syntax,
326    }
327}