This commit is contained in:
2025-10-15 16:52:39 +02:00
parent 1015e9e18f
commit 1b35c4ccc1
26 changed files with 1078 additions and 433 deletions

View File

@ -0,0 +1,105 @@
import { EditorView } from '@codemirror/view';
import type { Extension } from '@codemirror/state';
import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';
import { tags as t } from '@lezer/highlight';
function getCSSVariable(name: string): string {
if (typeof window === 'undefined') return '';
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
}
export function createCodeMirrorTheme(): Extension {
const editorTheme = EditorView.theme({
'&': {
backgroundColor: getCSSVariable('--color-bg-base'),
color: getCSSVariable('--color-text-primary'),
},
'.cm-content': {
caretColor: getCSSVariable('--color-accent-primary'),
},
'.cm-cursor, .cm-dropCursor': {
borderLeftColor: getCSSVariable('--color-accent-primary'),
},
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {
backgroundColor: getCSSVariable('--color-selected-overlay'),
},
'.cm-panels': {
backgroundColor: getCSSVariable('--color-surface-1'),
color: getCSSVariable('--color-text-primary'),
},
'.cm-panels.cm-panels-top': {
borderBottom: `1px solid ${getCSSVariable('--color-border-default')}`,
},
'.cm-panels.cm-panels-bottom': {
borderTop: `1px solid ${getCSSVariable('--color-border-default')}`,
},
'.cm-searchMatch': {
backgroundColor: getCSSVariable('--color-warning'),
outline: `1px solid ${getCSSVariable('--color-border-accent')}`,
},
'.cm-searchMatch.cm-searchMatch-selected': {
backgroundColor: getCSSVariable('--color-accent-primary-subtle'),
},
'.cm-activeLine': {
backgroundColor: getCSSVariable('--color-hover-overlay'),
},
'.cm-selectionMatch': {
backgroundColor: getCSSVariable('--color-selected-overlay'),
},
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
backgroundColor: getCSSVariable('--color-active-overlay'),
},
'.cm-gutters': {
backgroundColor: getCSSVariable('--color-surface-1'),
color: getCSSVariable('--color-text-tertiary'),
border: 'none',
borderRight: `1px solid ${getCSSVariable('--color-border-subtle')}`,
},
'.cm-activeLineGutter': {
backgroundColor: getCSSVariable('--color-hover-overlay'),
color: getCSSVariable('--color-text-secondary'),
},
'.cm-foldPlaceholder': {
backgroundColor: getCSSVariable('--color-surface-2'),
border: `1px solid ${getCSSVariable('--color-border-default')}`,
color: getCSSVariable('--color-text-secondary'),
},
'.cm-tooltip': {
border: `1px solid ${getCSSVariable('--color-border-default')}`,
backgroundColor: getCSSVariable('--color-tooltip-bg'),
},
'.cm-tooltip .cm-tooltip-arrow:before': {
borderTopColor: getCSSVariable('--color-border-default'),
},
'.cm-tooltip .cm-tooltip-arrow:after': {
borderTopColor: getCSSVariable('--color-tooltip-bg'),
},
'.cm-tooltip-autocomplete': {
'& > ul > li[aria-selected]': {
backgroundColor: getCSSVariable('--color-selected-overlay'),
color: getCSSVariable('--color-text-primary'),
},
},
}, { dark: getCSSVariable('--color-bg-base').startsWith('#1') || getCSSVariable('--color-bg-base').startsWith('#2') });
const highlightStyle = HighlightStyle.define([
{ tag: t.keyword, color: getCSSVariable('--color-accent-primary') },
{ tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName], color: getCSSVariable('--color-text-primary') },
{ tag: [t.function(t.variableName), t.labelName], color: getCSSVariable('--color-info') },
{ tag: [t.color, t.constant(t.name), t.standard(t.name)], color: getCSSVariable('--color-warning') },
{ tag: [t.definition(t.name), t.separator], color: getCSSVariable('--color-text-primary') },
{ tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: getCSSVariable('--color-warning') },
{ tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)], color: getCSSVariable('--color-accent-primary-hover') },
{ tag: [t.meta, t.comment], color: getCSSVariable('--color-text-tertiary'), fontStyle: 'italic' },
{ tag: t.strong, fontWeight: 'bold' },
{ tag: t.emphasis, fontStyle: 'italic' },
{ tag: t.strikethrough, textDecoration: 'line-through' },
{ tag: t.link, color: getCSSVariable('--color-info'), textDecoration: 'underline' },
{ tag: t.heading, fontWeight: 'bold', color: getCSSVariable('--color-accent-primary') },
{ tag: [t.atom, t.bool, t.special(t.variableName)], color: getCSSVariable('--color-warning') },
{ tag: [t.processingInstruction, t.string, t.inserted], color: getCSSVariable('--color-success') },
{ tag: t.invalid, color: getCSSVariable('--color-error') },
]);
return [editorTheme, syntaxHighlighting(highlightStyle)];
}