editor.ts

  1import { fontWeights } from "../common";
  2import { withOpacity } from "../utils/color";
  3import { ColorScheme, Layer, StyleSets } from "../themes/common/colorScheme";
  4import {
  5  background,
  6  border,
  7  borderColor,
  8  foreground,
  9  text,
 10} from "./components";
 11import hoverPopover from "./hoverPopover";
 12
 13export default function editor(colorScheme: ColorScheme) {
 14  let layer = colorScheme.highest;
 15
 16  const autocompleteItem = {
 17    cornerRadius: 6,
 18    padding: {
 19      bottom: 2,
 20      left: 6,
 21      right: 6,
 22      top: 2,
 23    },
 24  };
 25
 26  function diagnostic(layer: Layer, styleSet: StyleSets) {
 27    return {
 28      textScaleFactor: 0.857,
 29      header: {
 30        border: border(layer, {
 31          top: true,
 32        }),
 33      },
 34      message: {
 35        text: text(layer, "sans", styleSet, "default", { size: "sm" }),
 36        highlightText: text(layer, "sans", styleSet, "default", {
 37          size: "sm",
 38          weight: "bold",
 39        }),
 40      },
 41    };
 42  }
 43
 44  const syntax = {
 45    primary: {
 46      color: colorScheme.ramps.neutral(1).hex(),
 47      weight: fontWeights.normal,
 48    },
 49    "variable.special": {
 50      // Highlights for self, this, etc
 51      color: colorScheme.ramps.blue(0.7).hex(),
 52      weight: fontWeights.normal,
 53    },
 54    comment: {
 55      color: colorScheme.ramps.neutral(0.71).hex(),
 56      weight: fontWeights.normal,
 57    },
 58    punctuation: {
 59      color: colorScheme.ramps.neutral(0.86).hex(),
 60      weight: fontWeights.normal,
 61    },
 62    constant: {
 63      color: colorScheme.ramps.green(0.5).hex(),
 64      weight: fontWeights.normal,
 65    },
 66    keyword: {
 67      color: colorScheme.ramps.blue(0.5).hex(),
 68      weight: fontWeights.normal,
 69    },
 70    function: {
 71      color: colorScheme.ramps.yellow(0.5).hex(),
 72      weight: fontWeights.normal,
 73    },
 74    type: {
 75      color: colorScheme.ramps.cyan(0.5).hex(),
 76      weight: fontWeights.normal,
 77    },
 78    constructor: {
 79      color: colorScheme.ramps.blue(0.5).hex(),
 80      weight: fontWeights.normal,
 81    },
 82    variant: {
 83      color: colorScheme.ramps.blue(0.5).hex(),
 84      weight: fontWeights.normal,
 85    },
 86    property: {
 87      color: colorScheme.ramps.blue(0.5).hex(),
 88      weight: fontWeights.normal,
 89    },
 90    enum: {
 91      color: colorScheme.ramps.orange(0.5).hex(),
 92      weight: fontWeights.normal,
 93    },
 94    operator: {
 95      color: colorScheme.ramps.orange(0.5).hex(),
 96      weight: fontWeights.normal,
 97    },
 98    string: {
 99      color: colorScheme.ramps.orange(0.5).hex(),
100      weight: fontWeights.normal,
101    },
102    number: {
103      color: colorScheme.ramps.green(0.5).hex(),
104      weight: fontWeights.normal,
105    },
106    boolean: {
107      color: colorScheme.ramps.green(0.5).hex(),
108      weight: fontWeights.normal,
109    },
110    predictive: {
111      color: colorScheme.ramps.neutral(0.57).hex(),
112      weight: fontWeights.normal,
113    },
114    title: {
115      color: colorScheme.ramps.yellow(0.5).hex(),
116      weight: fontWeights.bold,
117    },
118    emphasis: {
119      color: colorScheme.ramps.blue(0.5).hex(),
120      weight: fontWeights.normal,
121    },
122    "emphasis.strong": {
123      color: colorScheme.ramps.blue(0.5).hex(),
124      weight: fontWeights.bold,
125    },
126    linkUri: {
127      color: colorScheme.ramps.green(0.5).hex(),
128      weight: fontWeights.normal,
129      underline: true,
130    },
131    linkText: {
132      color: colorScheme.ramps.orange(0.5).hex(),
133      weight: fontWeights.normal,
134      italic: true,
135    },
136  };
137
138  return {
139    textColor: syntax.primary.color,
140    background: background(layer),
141    activeLineBackground: withOpacity(background(layer, "on"), 0.75),
142    highlightedLineBackground: background(layer, "on"),
143    codeActions: {
144      indicator: foreground(layer, "variant"),
145      verticalScale: 0.55,
146    },
147    diff: {
148      deleted: foreground(layer, "negative"),
149      modified: foreground(layer, "warning"),
150      inserted: foreground(layer, "positive"),
151      removedWidthEm: 0.275,
152      widthEm: 0.16,
153      cornerRadius: 0.05,
154    },
155    /** Highlights matching occurences of what is under the cursor
156     * as well as matched brackets
157     */
158    documentHighlightReadBackground: withOpacity(foreground(layer, "accent"), 0.1),
159    documentHighlightWriteBackground: colorScheme.ramps
160      .neutral(0.5)
161      .alpha(0.4)
162      .hex(), // TODO: This was blend * 2
163    errorColor: background(layer, "negative"),
164    gutterBackground: background(layer),
165    gutterPaddingFactor: 3.5,
166    lineNumber: withOpacity(foreground(layer), 0.35),
167    lineNumberActive: foreground(layer),
168    renameFade: 0.6,
169    unnecessaryCodeFade: 0.5,
170    selection: colorScheme.players[0],
171    guestSelections: [
172      colorScheme.players[1],
173      colorScheme.players[2],
174      colorScheme.players[3],
175      colorScheme.players[4],
176      colorScheme.players[5],
177      colorScheme.players[6],
178      colorScheme.players[7],
179    ],
180    autocomplete: {
181      background: background(colorScheme.middle),
182      cornerRadius: 8,
183      padding: 4,
184      margin: {
185        left: -14,
186      },
187      border: border(colorScheme.middle),
188      shadow: colorScheme.popoverShadow,
189      matchHighlight: foreground(colorScheme.middle, "accent"),
190      item: autocompleteItem,
191      hoveredItem: {
192        ...autocompleteItem,
193        matchHighlight: foreground(colorScheme.middle, "accent", "hovered"),
194        background: background(colorScheme.middle, "hovered"),
195      },
196      selectedItem: {
197        ...autocompleteItem,
198        matchHighlight: foreground(colorScheme.middle, "accent", "active"),
199        background: background(colorScheme.middle, "active"),
200      },
201    },
202    diagnosticHeader: {
203      background: background(colorScheme.middle),
204      iconWidthFactor: 1.5,
205      textScaleFactor: 0.857,
206      border: border(colorScheme.middle, {
207        bottom: true,
208        top: true,
209      }),
210      code: {
211        ...text(colorScheme.middle, "mono", { size: "sm" }),
212        margin: {
213          left: 10,
214        },
215      },
216      message: {
217        highlightText: text(colorScheme.middle, "sans", {
218          size: "sm",
219          weight: "bold",
220        }),
221        text: text(colorScheme.middle, "sans", { size: "sm" }),
222      },
223    },
224    diagnosticPathHeader: {
225      background: background(colorScheme.middle),
226      textScaleFactor: 0.857,
227      filename: text(colorScheme.middle, "mono", { size: "sm" }),
228      path: {
229        ...text(colorScheme.middle, "mono", { size: "sm" }),
230        margin: {
231          left: 12,
232        },
233      },
234    },
235    errorDiagnostic: diagnostic(colorScheme.middle, "negative"),
236    warningDiagnostic: diagnostic(colorScheme.middle, "warning"),
237    informationDiagnostic: diagnostic(colorScheme.middle, "accent"),
238    hintDiagnostic: diagnostic(colorScheme.middle, "warning"),
239    invalidErrorDiagnostic: diagnostic(colorScheme.middle, "base"),
240    invalidHintDiagnostic: diagnostic(colorScheme.middle, "base"),
241    invalidInformationDiagnostic: diagnostic(colorScheme.middle, "base"),
242    invalidWarningDiagnostic: diagnostic(colorScheme.middle, "base"),
243    hoverPopover: hoverPopover(colorScheme),
244    linkDefinition: {
245      color: syntax.linkUri.color,
246      underline: syntax.linkUri.underline,
247    },
248    jumpIcon: {
249      color: foreground(layer, "on"),
250      iconWidth: 20,
251      buttonWidth: 20,
252      cornerRadius: 6,
253      padding: {
254        top: 6,
255        bottom: 6,
256        left: 6,
257        right: 6,
258      },
259      hover: {
260        color: foreground(layer, "on", "hovered"),
261        background: background(layer, "on", "hovered"),
262      },
263    },
264    scrollbar: {
265      width: 12,
266      minHeightFactor: 1.0,
267      track: {
268        border: border(layer, "variant", { left: true }),
269      },
270      thumb: {
271        background: withOpacity(background(layer, "inverted"), 0.4),
272        border: {
273          width: 1,
274          color: borderColor(layer, "variant"),
275        },
276      },
277    },
278    compositionMark: {
279      underline: {
280        thickness: 1.0,
281        color: borderColor(layer),
282      },
283    },
284    syntax,
285  };
286}