236 lines
9.8 KiB
TypeScript
236 lines
9.8 KiB
TypeScript
import {EditorView} from '@codemirror/view';
|
|
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language';
|
|
import {tags} from '@lezer/highlight';
|
|
import {Extension} from '@codemirror/state';
|
|
import type {ThemeColors} from './types';
|
|
|
|
const MONO_FONT_FALLBACK = 'var(--voidraft-font-mono, SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace)';
|
|
|
|
/**
|
|
* 创建通用主题
|
|
* @param colors 主题颜色配置
|
|
* @returns CodeMirror Extension数组
|
|
*/
|
|
export function createBaseTheme(colors: ThemeColors): Extension {
|
|
// 编辑器主题样式
|
|
const theme = EditorView.theme({
|
|
|
|
'&': {
|
|
backgroundColor: colors.background,
|
|
},
|
|
|
|
'.cm-editor': {
|
|
backgroundColor: colors.background,
|
|
},
|
|
|
|
// 光标
|
|
'.cm-cursor, .cm-dropCursor': {
|
|
borderLeftColor: colors.cursor,
|
|
borderLeftWidth: '2px',
|
|
paddingTop: '4px',
|
|
marginTop: '-2px',
|
|
},
|
|
|
|
// 选择背景
|
|
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
|
|
backgroundColor: colors.selection,
|
|
},
|
|
|
|
|
|
// 当前行高亮
|
|
'.cm-activeLine': {
|
|
backgroundColor: colors.activeLine
|
|
},
|
|
|
|
// 行号区域
|
|
'.cm-gutters': {
|
|
backgroundColor: colors.dark ? 'rgba(0,0,0, 0.1)' : 'rgba(0,0,0, 0.04)',
|
|
color: colors.lineNumber,
|
|
border: 'none',
|
|
padding: '0 2px 0 4px',
|
|
userSelect: 'none',
|
|
},
|
|
'.cm-activeLineGutter': {
|
|
backgroundColor: 'transparent',
|
|
color: colors.activeLineNumber,
|
|
},
|
|
|
|
|
|
|
|
// 括号匹配
|
|
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
|
outline: `0.5px solid ${colors.matchingBracket}`,
|
|
},
|
|
|
|
// 代码块层(自定义)
|
|
'.code-blocks-layer': {
|
|
width: '100%',
|
|
},
|
|
'.code-blocks-layer .block-even, .code-blocks-layer .block-odd': {
|
|
width: '100%',
|
|
boxSizing: 'content-box',
|
|
},
|
|
'.code-blocks-layer .block-even': {
|
|
background: colors.background,
|
|
borderTop: `1px solid ${colors.borderColor}`,
|
|
},
|
|
'.code-blocks-layer .block-even:first-child': {
|
|
borderTop: 'none',
|
|
},
|
|
'.code-blocks-layer .block-odd': {
|
|
background: colors.backgroundSecondary,
|
|
borderTop: `1px solid ${colors.borderColor}`,
|
|
},
|
|
'.code-block-empty-selected': {
|
|
backgroundColor: colors.selection,
|
|
},
|
|
// 代码块开始标记
|
|
'.code-block-start': {
|
|
height: '12px',
|
|
position: 'relative',
|
|
},
|
|
'.code-block-start.first': {
|
|
height: '0px',
|
|
},
|
|
|
|
// 数学计算结果
|
|
'.code-blocks-math-result': {
|
|
paddingLeft: "12px",
|
|
position: "relative",
|
|
},
|
|
".code-blocks-math-result .inner": {
|
|
background: colors.dark ? '#0e1217' : '#48b57e',
|
|
color: colors.dark ? '#a0e7c7' : '#fff',
|
|
padding: '0px 4px',
|
|
borderRadius: '2px',
|
|
boxShadow: colors.dark ? '0 0 3px rgba(0,0,0, 0.3)' : '0 0 3px rgba(0,0,0, 0.1)',
|
|
cursor: 'pointer',
|
|
whiteSpace: "nowrap",
|
|
},
|
|
'.code-blocks-math-result-copied': {
|
|
position: "absolute",
|
|
top: "0px",
|
|
left: "0px",
|
|
marginLeft: "calc(100% + 10px)",
|
|
width: "60px",
|
|
transition: "opacity 500ms",
|
|
transitionDelay: "1000ms",
|
|
color: colors.dark ? 'rgba(220,240,230, 1.0)' : 'rgba(0,0,0, 0.8)',
|
|
},
|
|
'.code-blocks-math-result-copied.fade-out': {
|
|
opacity: 0,
|
|
},
|
|
}, {dark: colors.dark});
|
|
|
|
const highlightStyle = HighlightStyle.define([
|
|
{tag: tags.comment, color: colors.comment, fontStyle: 'italic'},
|
|
{tag: tags.lineComment, color: colors.lineComment, fontStyle: 'italic'},
|
|
{tag: tags.blockComment, color: colors.blockComment, fontStyle: 'italic'},
|
|
{tag: tags.docComment, color: colors.docComment, fontStyle: 'italic'},
|
|
|
|
{tag: tags.name, color: colors.name},
|
|
{tag: tags.variableName, color: colors.variableName},
|
|
{tag: tags.typeName, color: colors.typeName},
|
|
{tag: tags.tagName, color: colors.tagName},
|
|
{tag: tags.propertyName, color: colors.propertyName},
|
|
{tag: tags.attributeName, color: colors.attributeName},
|
|
{tag: tags.className, color: colors.className},
|
|
{tag: tags.labelName, color: colors.labelName},
|
|
{tag: tags.namespace, color: colors.namespace},
|
|
{tag: tags.macroName, color: colors.macroName},
|
|
|
|
{tag: tags.literal, color: colors.literal},
|
|
{tag: tags.string, color: colors.string},
|
|
{tag: tags.docString, color: colors.docString},
|
|
{tag: tags.character, color: colors.character},
|
|
{tag: tags.attributeValue, color: colors.attributeValue},
|
|
{tag: tags.number, color: colors.number},
|
|
{tag: tags.integer, color: colors.integer},
|
|
{tag: tags.float, color: colors.float},
|
|
{tag: tags.bool, color: colors.bool},
|
|
{tag: tags.regexp, color: colors.regexp},
|
|
{tag: tags.escape, color: colors.escape},
|
|
{tag: tags.color, color: colors.color},
|
|
{tag: tags.url, color: colors.url},
|
|
|
|
{tag: tags.keyword, color: colors.keyword},
|
|
{tag: tags.self, color: colors.self},
|
|
{tag: tags.null, color: colors.null},
|
|
{tag: tags.atom, color: colors.atom},
|
|
{tag: tags.unit, color: colors.unit},
|
|
{tag: tags.modifier, color: colors.modifier},
|
|
{tag: tags.operatorKeyword, color: colors.operatorKeyword},
|
|
{tag: tags.controlKeyword, color: colors.controlKeyword},
|
|
{tag: tags.definitionKeyword, color: colors.definitionKeyword},
|
|
{tag: tags.moduleKeyword, color: colors.moduleKeyword},
|
|
|
|
{tag: tags.operator, color: colors.operator},
|
|
{tag: tags.derefOperator, color: colors.derefOperator},
|
|
{tag: tags.arithmeticOperator, color: colors.arithmeticOperator},
|
|
{tag: tags.logicOperator, color: colors.logicOperator},
|
|
{tag: tags.bitwiseOperator, color: colors.bitwiseOperator},
|
|
{tag: tags.compareOperator, color: colors.compareOperator},
|
|
{tag: tags.updateOperator, color: colors.updateOperator},
|
|
{tag: tags.definitionOperator, color: colors.definitionOperator},
|
|
{tag: tags.typeOperator, color: colors.typeOperator},
|
|
{tag: tags.controlOperator, color: colors.controlOperator},
|
|
|
|
{tag: tags.punctuation, color: colors.punctuation},
|
|
{tag: tags.separator, color: colors.separator},
|
|
{tag: tags.bracket, color: colors.bracket},
|
|
{tag: tags.angleBracket, color: colors.angleBracket},
|
|
{tag: tags.squareBracket, color: colors.squareBracket},
|
|
{tag: tags.paren, color: colors.paren},
|
|
{tag: tags.brace, color: colors.brace},
|
|
|
|
{tag: tags.content, color: colors.content},
|
|
{tag: tags.heading, color: colors.heading, fontWeight: 'bold'},
|
|
{tag: tags.heading1, color: colors.heading1, fontWeight: 'bold', fontSize: '1.4em'},
|
|
{tag: tags.heading2, color: colors.heading2, fontWeight: 'bold', fontSize: '1.3em'},
|
|
{tag: tags.heading3, color: colors.heading3, fontWeight: 'bold', fontSize: '1.2em'},
|
|
{tag: tags.heading4, color: colors.heading4, fontWeight: 'bold', fontSize: '1.1em'},
|
|
{tag: tags.heading5, color: colors.heading5, fontWeight: 'bold'},
|
|
{tag: tags.heading6, color: colors.heading6, fontWeight: 'bold'},
|
|
{tag: tags.contentSeparator, color: colors.contentSeparator},
|
|
{tag: tags.list, color: colors.list},
|
|
{tag: tags.quote, color: colors.quote, fontStyle: 'italic'},
|
|
{tag: tags.emphasis, color: colors.emphasis, fontStyle: 'italic'},
|
|
{tag: tags.strong, color: colors.strong, fontWeight: 'bold'},
|
|
{tag: tags.link, color: colors.link, textDecoration: 'underline'},
|
|
{tag: tags.monospace, color: colors.monospace, fontFamily: MONO_FONT_FALLBACK},
|
|
{tag: tags.strikethrough, color: colors.strikethrough, textDecoration: 'line-through'},
|
|
|
|
{tag: tags.inserted, color: colors.inserted},
|
|
{tag: tags.deleted, color: colors.deleted},
|
|
{tag: tags.changed, color: colors.changed},
|
|
|
|
{tag: tags.meta, color: colors.meta, fontStyle: 'italic'},
|
|
{tag: tags.documentMeta, color: colors.documentMeta},
|
|
{tag: tags.annotation, color: colors.annotation},
|
|
{tag: tags.processingInstruction, color: colors.processingInstruction},
|
|
|
|
{tag: tags.definition(tags.variableName), color: colors.definition},
|
|
{tag: tags.definition(tags.propertyName), color: colors.definition},
|
|
{tag: tags.definition(tags.name), color: colors.definition},
|
|
{tag: tags.constant(tags.variableName), color: colors.constant},
|
|
{tag: tags.constant(tags.propertyName), color: colors.constant},
|
|
{tag: tags.constant(tags.name), color: colors.constant},
|
|
{tag: tags.function(tags.variableName), color: colors.function},
|
|
{tag: tags.function(tags.propertyName), color: colors.function},
|
|
{tag: tags.function(tags.name), color: colors.function},
|
|
{tag: tags.standard(tags.variableName), color: colors.standard},
|
|
{tag: tags.standard(tags.name), color: colors.standard},
|
|
{tag: tags.local(tags.variableName), color: colors.local},
|
|
{tag: tags.local(tags.name), color: colors.local},
|
|
{tag: tags.special(tags.variableName), color: colors.special},
|
|
{tag: tags.special(tags.name), color: colors.special},
|
|
{tag: tags.special(tags.string), color: colors.special},
|
|
|
|
{tag: tags.invalid, color: colors.invalid},
|
|
]);
|
|
return [
|
|
theme,
|
|
syntaxHighlighting(highlightStyle),
|
|
];
|
|
}
|