✨ Added preset theme
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { Extension, Compartment } from '@codemirror/state';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
import { SystemThemeType } from '@/../bindings/voidraft/internal/models/models';
|
||||
import { createDarkTheme } from '@/views/editor/theme/dark';
|
||||
import { createLightTheme } from '@/views/editor/theme/light';
|
||||
import { createThemeByColors } from '@/views/editor/theme/registry';
|
||||
import { useThemeStore } from '@/stores/themeStore';
|
||||
|
||||
// 主题区间 - 用于动态切换主题
|
||||
@@ -11,23 +10,25 @@ export const themeCompartment = new Compartment();
|
||||
/**
|
||||
* 根据主题类型获取主题扩展
|
||||
*/
|
||||
const getThemeExtension = (themeType: SystemThemeType): Extension => {
|
||||
const getThemeExtension = (themeType: SystemThemeType): Extension | null => {
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
// 处理 auto 主题类型
|
||||
let actualTheme: SystemThemeType = themeType;
|
||||
let isDark = themeType === SystemThemeType.SystemThemeDark;
|
||||
if (themeType === SystemThemeType.SystemThemeAuto) {
|
||||
actualTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
? SystemThemeType.SystemThemeDark
|
||||
: SystemThemeType.SystemThemeLight;
|
||||
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
|
||||
// 根据主题类型创建主题
|
||||
if (actualTheme === SystemThemeType.SystemThemeLight) {
|
||||
return createLightTheme(themeStore.themeColors.lightTheme);
|
||||
} else {
|
||||
return createDarkTheme(themeStore.themeColors.darkTheme);
|
||||
// 根据主题类型获取对应的颜色配置
|
||||
const colors = isDark ? themeStore.currentColors.dark : themeStore.currentColors.light;
|
||||
|
||||
if (!colors) {
|
||||
console.warn('Theme colors not loaded yet');
|
||||
return null;
|
||||
}
|
||||
|
||||
// 使用颜色配置创建主题
|
||||
return createThemeByColors(colors);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -35,6 +36,12 @@ const getThemeExtension = (themeType: SystemThemeType): Extension => {
|
||||
*/
|
||||
export const createThemeExtension = (themeType: SystemThemeType = SystemThemeType.SystemThemeDark): Extension => {
|
||||
const extension = getThemeExtension(themeType);
|
||||
|
||||
// 如果主题未加载,返回空扩展
|
||||
if (!extension) {
|
||||
return themeCompartment.of([]);
|
||||
}
|
||||
|
||||
return themeCompartment.of(extension);
|
||||
};
|
||||
|
||||
@@ -48,6 +55,13 @@ export const updateEditorTheme = (view: EditorView, themeType: SystemThemeType):
|
||||
|
||||
try {
|
||||
const extension = getThemeExtension(themeType);
|
||||
|
||||
// 如果主题未加载,不更新
|
||||
if (!extension) {
|
||||
console.warn('Cannot update theme: theme not loaded');
|
||||
return;
|
||||
}
|
||||
|
||||
view.dispatch({
|
||||
effects: themeCompartment.reconfigure(extension)
|
||||
});
|
||||
|
||||
@@ -1,48 +1,17 @@
|
||||
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';
|
||||
|
||||
// 默认深色主题颜色
|
||||
export const defaultDarkColors = {
|
||||
// 基础色调
|
||||
background: '#252B37', // 主背景色
|
||||
backgroundSecondary: '#213644', // 次要背景色
|
||||
surface: '#474747', // 面板背景
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#9BB586', // 主文本色
|
||||
foregroundSecondary: '#9c9c9c', // 次要文本色
|
||||
comment: '#6272a4', // 注释色
|
||||
|
||||
// 语法高亮色
|
||||
keyword: '#ff79c6', // 关键字
|
||||
string: '#f1fa8c', // 字符串
|
||||
function: '#50fa7b', // 函数名
|
||||
number: '#bd93f9', // 数字
|
||||
operator: '#ff79c6', // 操作符
|
||||
variable: '#8fbcbb', // 变量
|
||||
type: '#8be9fd', // 类型
|
||||
|
||||
// 界面元素
|
||||
cursor: '#ffffff', // 光标
|
||||
selection: '#0865a9', // 选中背景
|
||||
selectionBlur: '#225377', // 失焦选中背景
|
||||
activeLine: '#ffffff0a', // 当前行高亮
|
||||
lineNumber: '#ffffff26', // 行号
|
||||
activeLineNumber: '#ffffff99', // 活动行号
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#1e222a', // 边框色
|
||||
borderLight: '#ffffff19', // 浅色边框
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#8fbcbb', // 搜索匹配
|
||||
matchingBracket: '#ffffff19', // 匹配括号
|
||||
};
|
||||
|
||||
// 创建深色主题
|
||||
export function createDarkTheme(colors = defaultDarkColors) {
|
||||
const darkTheme = EditorView.theme({
|
||||
/**
|
||||
* 创建通用主题
|
||||
* @param colors 主题颜色配置
|
||||
* @returns CodeMirror Extension数组
|
||||
*/
|
||||
export function createBaseTheme(colors: ThemeColors): Extension {
|
||||
// 编辑器主题样式
|
||||
const theme = EditorView.theme({
|
||||
'&': {
|
||||
color: colors.foreground,
|
||||
backgroundColor: colors.background,
|
||||
@@ -79,6 +48,9 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
|
||||
backgroundColor: colors.selection,
|
||||
},
|
||||
'.cm-content ::selection': {
|
||||
backgroundColor: colors.selection,
|
||||
},
|
||||
'.cm-activeLine.code-empty-block-selected': {
|
||||
backgroundColor: colors.selection,
|
||||
},
|
||||
@@ -90,9 +62,10 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
|
||||
// 行号区域
|
||||
'.cm-gutters': {
|
||||
backgroundColor: 'rgba(0,0,0, 0.1)',
|
||||
backgroundColor: colors.dark ? 'rgba(0,0,0, 0.1)' : 'rgba(0,0,0, 0.04)',
|
||||
color: colors.lineNumber,
|
||||
border: 'none',
|
||||
borderRight: colors.dark ? 'none' : `1px solid ${colors.borderLight}`,
|
||||
padding: '0 2px 0 4px',
|
||||
userSelect: 'none',
|
||||
},
|
||||
@@ -115,9 +88,20 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: '#ddd',
|
||||
color: colors.comment,
|
||||
},
|
||||
|
||||
// 面板
|
||||
'.cm-panels': {
|
||||
backgroundColor: colors.dropdownBackground,
|
||||
color: colors.foreground
|
||||
},
|
||||
'.cm-panels.cm-panels-top': {
|
||||
borderBottom: '2px solid black'
|
||||
},
|
||||
'.cm-panels.cm-panels-bottom': {
|
||||
borderTop: '2px solid black'
|
||||
},
|
||||
|
||||
// 搜索匹配
|
||||
'.cm-searchMatch': {
|
||||
@@ -125,11 +109,11 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
outline: `1px solid ${colors.searchMatch}`,
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: colors.foreground,
|
||||
backgroundColor: colors.searchMatch,
|
||||
color: colors.background,
|
||||
},
|
||||
'.cm-selectionMatch': {
|
||||
backgroundColor: '#50606D',
|
||||
backgroundColor: colors.dark ? '#50606D' : '#e6f3ff',
|
||||
},
|
||||
|
||||
// 括号匹配
|
||||
@@ -141,7 +125,7 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
color: 'inherit',
|
||||
},
|
||||
'&.cm-focused .cm-nonmatchingBracket': {
|
||||
outline: '0.5px solid #bc8f8f',
|
||||
outline: colors.dark ? '0.5px solid #bc8f8f' : '0.5px solid #d73a49',
|
||||
},
|
||||
|
||||
// 编辑器焦点
|
||||
@@ -151,8 +135,10 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
|
||||
// 工具提示
|
||||
'.cm-tooltip': {
|
||||
border: 'none',
|
||||
border: colors.dark ? 'none' : `1px solid ${colors.dropdownBorder}`,
|
||||
backgroundColor: colors.surface,
|
||||
color: colors.foreground,
|
||||
boxShadow: colors.dark ? 'none' : '0 2px 8px rgba(0,0,0,0.1)',
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
@@ -169,7 +155,7 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
},
|
||||
},
|
||||
|
||||
// 代码块层
|
||||
// 代码块层(自定义)
|
||||
'.code-blocks-layer': {
|
||||
width: '100%',
|
||||
},
|
||||
@@ -188,34 +174,36 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
background: colors.backgroundSecondary,
|
||||
borderTop: `1px solid ${colors.borderColor}`,
|
||||
},
|
||||
'.code-blocks-math-result': {
|
||||
paddingLeft: "12px",
|
||||
position: "relative",
|
||||
},
|
||||
".code-blocks-math-result .inner": {
|
||||
background: "#0e1217",
|
||||
color: "#a0e7c7",
|
||||
padding: '0px 4px',
|
||||
borderRadius: '2px',
|
||||
boxShadow: '0 0 3px rgba(0,0,0, 0.3)',
|
||||
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: "rgba(220,240,230, 1.0)",
|
||||
},
|
||||
'.code-blocks-math-result-copied.fade-out': {
|
||||
opacity: 0,
|
||||
},
|
||||
|
||||
// 代码块开始标记
|
||||
// 数学计算结果(自定义)
|
||||
'.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,
|
||||
},
|
||||
|
||||
// 代码块开始标记(自定义)
|
||||
'.code-block-start': {
|
||||
height: '12px',
|
||||
position: 'relative',
|
||||
@@ -223,47 +211,79 @@ export function createDarkTheme(colors = defaultDarkColors) {
|
||||
'.code-block-start.first': {
|
||||
height: '0px',
|
||||
},
|
||||
}, {dark: true});
|
||||
}, {dark: colors.dark});
|
||||
|
||||
// 语法高亮样式
|
||||
const darkHighlightStyle = HighlightStyle.define([
|
||||
const highlightStyle = HighlightStyle.define([
|
||||
// 关键字
|
||||
{tag: tags.keyword, color: colors.keyword},
|
||||
{tag: [tags.name, tags.deleted, tags.character, tags.propertyName, tags.macroName], color: colors.variable},
|
||||
{tag: [tags.variableName], color: colors.variable},
|
||||
{tag: [tags.function(tags.variableName)], color: colors.function},
|
||||
{tag: [tags.labelName], color: colors.operator},
|
||||
{tag: [tags.color, tags.constant(tags.name), tags.standard(tags.name)], color: colors.keyword},
|
||||
{tag: [tags.definition(tags.name), tags.separator], color: colors.function},
|
||||
{tag: [tags.brace], color: colors.variable},
|
||||
{tag: [tags.annotation], color: '#d30102'},
|
||||
{tag: [tags.number, tags.changed, tags.annotation, tags.modifier, tags.self, tags.namespace], color: colors.number},
|
||||
{tag: [tags.typeName, tags.className], color: colors.type},
|
||||
|
||||
// 操作符
|
||||
{tag: [tags.operator, tags.operatorKeyword], color: colors.operator},
|
||||
{tag: [tags.tagName], color: colors.number},
|
||||
{tag: [tags.squareBracket], color: '#bf616a'},
|
||||
{tag: [tags.angleBracket], color: '#d08770'},
|
||||
{tag: [tags.attributeName], color: colors.variable},
|
||||
{tag: [tags.regexp], color: colors.string},
|
||||
|
||||
// 名称、变量
|
||||
{tag: [tags.name, tags.deleted, tags.character, tags.macroName], color: colors.variable},
|
||||
{tag: [tags.variableName], color: colors.variable},
|
||||
{tag: [tags.labelName], color: colors.operator},
|
||||
{tag: [tags.atom, tags.bool, tags.special(tags.variableName)], color: colors.variable},
|
||||
|
||||
// 函数
|
||||
{tag: [tags.function(tags.variableName)], color: colors.function},
|
||||
{tag: [tags.propertyName], color: colors.function},
|
||||
|
||||
// 类型、类
|
||||
{tag: [tags.typeName], color: colors.type},
|
||||
{tag: [tags.className], color: colors.class},
|
||||
|
||||
// 常量
|
||||
{tag: [tags.color, tags.constant(tags.name), tags.standard(tags.name)], color: colors.constant},
|
||||
|
||||
// 字符串
|
||||
{tag: [tags.processingInstruction, tags.string, tags.inserted], color: colors.string},
|
||||
{tag: [tags.special(tags.string)], color: colors.string},
|
||||
{tag: [tags.quote], color: colors.comment},
|
||||
{tag: [tags.string], color: colors.string},
|
||||
{tag: tags.link, color: colors.variable, textDecoration: 'underline'},
|
||||
{tag: [tags.url, tags.escape, tags.special(tags.string)], color: colors.string},
|
||||
{tag: [tags.meta], color: colors.comment},
|
||||
{tag: [tags.comment], color: colors.comment, fontStyle: 'italic'},
|
||||
|
||||
// 数字
|
||||
{tag: [tags.number, tags.changed, tags.annotation, tags.modifier, tags.self, tags.namespace], color: colors.number},
|
||||
|
||||
// 正则表达式
|
||||
{tag: [tags.url, tags.escape, tags.regexp, tags.link], color: colors.regexp},
|
||||
|
||||
// 注释
|
||||
{tag: [tags.meta, tags.comment], color: colors.comment, fontStyle: 'italic'},
|
||||
|
||||
// 分隔符、括号
|
||||
{tag: [tags.definition(tags.name), tags.separator], color: colors.variable},
|
||||
{tag: [tags.brace], color: colors.variable},
|
||||
{tag: [tags.squareBracket], color: colors.dark ? '#bf616a' : colors.keyword},
|
||||
{tag: [tags.angleBracket], color: colors.dark ? '#d08770' : colors.operator},
|
||||
{tag: [tags.attributeName], color: colors.variable},
|
||||
|
||||
// 标签
|
||||
{tag: [tags.tagName], color: colors.number},
|
||||
|
||||
// 注解
|
||||
{tag: [tags.annotation], color: colors.invalid},
|
||||
|
||||
// 特殊样式
|
||||
{tag: tags.strong, fontWeight: 'bold'},
|
||||
{tag: tags.emphasis, fontStyle: 'italic'},
|
||||
{tag: tags.strikethrough, textDecoration: 'line-through'},
|
||||
{tag: tags.heading, fontWeight: 'bold', color: colors.keyword},
|
||||
{tag: tags.link, color: colors.variable, textDecoration: 'underline'},
|
||||
|
||||
// 标题
|
||||
{tag: tags.heading, fontWeight: 'bold', color: colors.heading},
|
||||
{tag: [tags.heading1, tags.heading2], fontSize: '1.4em'},
|
||||
{tag: [tags.heading3, tags.heading4], fontSize: '1.2em'},
|
||||
{tag: [tags.heading5, tags.heading6], fontSize: '1.1em'},
|
||||
|
||||
// 无效内容
|
||||
{tag: tags.invalid, color: colors.invalid},
|
||||
]);
|
||||
|
||||
return [
|
||||
darkTheme,
|
||||
syntaxHighlighting(darkHighlightStyle),
|
||||
theme,
|
||||
syntaxHighlighting(highlightStyle),
|
||||
];
|
||||
}
|
||||
|
||||
// 默认深色主题
|
||||
export const dark = createDarkTheme(defaultDarkColors);
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
export const config: ThemeColors = {
|
||||
name: 'aura',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: '#21202e',
|
||||
foreground: '#edecee',
|
||||
selection: '#3d375e7f',
|
||||
cursor: '#a277ff',
|
||||
backgroundSecondary: '#21202e',
|
||||
surface: '#21202e',
|
||||
dropdownBackground: '#21202e',
|
||||
dropdownBorder: '#3b334b',
|
||||
activeLine: '#4d4b6622',
|
||||
lineNumber: '#a394f033',
|
||||
activeLineNumber: '#cdccce',
|
||||
matchingBracket: '#a394f033',
|
||||
keyword: '#a277ff',
|
||||
storage: '#a277ff',
|
||||
variable: '#edecee',
|
||||
parameter: '#edecee',
|
||||
function: '#ffca85',
|
||||
string: '#61ffca',
|
||||
constant: '#61ffca',
|
||||
type: '#82e2ff',
|
||||
class: '#82e2ff',
|
||||
number: '#61ffca',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#edecee',
|
||||
foregroundSecondary: '#edecee',
|
||||
comment: '#6d6d6d',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#a277ff',
|
||||
string: '#61ffca',
|
||||
function: '#ffca85',
|
||||
number: '#61ffca',
|
||||
operator: '#a277ff',
|
||||
variable: '#edecee',
|
||||
type: '#82e2ff',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#61ffca',
|
||||
storage: '#a277ff',
|
||||
parameter: '#edecee',
|
||||
class: '#82e2ff',
|
||||
heading: '#a277ff',
|
||||
invalid: '#ff6767',
|
||||
regexp: '#61ffca',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#a277ff',
|
||||
selection: '#3d375e7f',
|
||||
selectionBlur: '#3d375e7f',
|
||||
activeLine: '#4d4b6622',
|
||||
lineNumber: '#a394f033',
|
||||
activeLineNumber: '#cdccce',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#3b334b',
|
||||
borderLight: '#edecee19',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#61ffca',
|
||||
matchingBracket: '#a394f033',
|
||||
}
|
||||
|
||||
export const auraTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const auraHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const aura: Extension = [
|
||||
auraTheme,
|
||||
syntaxHighlighting(auraHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Aura 主题
|
||||
export const aura: Extension = createBaseTheme(config)
|
||||
|
||||
63
frontend/src/views/editor/theme/dark/default-dark.ts
Normal file
63
frontend/src/views/editor/theme/dark/default-dark.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import {createBaseTheme} from '../base';
|
||||
import type {ThemeColors} from '../types';
|
||||
|
||||
// 默认深色主题颜色
|
||||
export const defaultDarkColors: ThemeColors = {
|
||||
// 主题信息
|
||||
name: 'default-dark',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: '#252B37', // 主背景色
|
||||
backgroundSecondary: '#213644', // 次要背景色
|
||||
surface: '#474747', // 面板背景
|
||||
dropdownBackground: '#252B37', // 下拉菜单背景
|
||||
dropdownBorder: '#ffffff19', // 下拉菜单边框
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#9BB586', // 主文本色
|
||||
foregroundSecondary: '#9c9c9c', // 次要文本色
|
||||
comment: '#6272a4', // 注释色
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#ff79c6', // 关键字
|
||||
string: '#f1fa8c', // 字符串
|
||||
function: '#50fa7b', // 函数名
|
||||
number: '#bd93f9', // 数字
|
||||
operator: '#ff79c6', // 操作符
|
||||
variable: '#8fbcbb', // 变量
|
||||
type: '#8be9fd', // 类型
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#bd93f9', // 常量
|
||||
storage: '#ff79c6', // 存储类型
|
||||
parameter: '#8fbcbb', // 参数
|
||||
class: '#8be9fd', // 类名
|
||||
heading: '#ff79c6', // 标题
|
||||
invalid: '#d30102', // 无效内容
|
||||
regexp: '#f1fa8c', // 正则表达式
|
||||
|
||||
// 界面元素
|
||||
cursor: '#ffffff', // 光标
|
||||
selection: '#0865a9', // 选中背景
|
||||
selectionBlur: '#225377', // 失焦选中背景
|
||||
activeLine: '#ffffff0a', // 当前行高亮
|
||||
lineNumber: '#ffffff26', // 行号
|
||||
activeLineNumber: '#ffffff99', // 活动行号
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#1e222a', // 边框色
|
||||
borderLight: '#ffffff19', // 浅色边框
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#8fbcbb', // 搜索匹配
|
||||
matchingBracket: '#ffffff19', // 匹配括号
|
||||
};
|
||||
|
||||
// 创建深色主题
|
||||
export function createDarkTheme(colors: ThemeColors = defaultDarkColors) {
|
||||
return createBaseTheme({...colors, dark: true});
|
||||
}
|
||||
|
||||
// 默认深色主题
|
||||
export const defaultDark = createDarkTheme(defaultDarkColors);
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
export const config: ThemeColors = {
|
||||
name: 'dracula',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: '#282A36',
|
||||
foreground: '#F8F8F2',
|
||||
selection: '#44475A',
|
||||
cursor: '#F8F8F2',
|
||||
backgroundSecondary: '#282A36',
|
||||
surface: '#282A36',
|
||||
dropdownBackground: '#282A36',
|
||||
dropdownBorder: '#191A21',
|
||||
activeLine: '#53576c22',
|
||||
lineNumber: '#6272A4',
|
||||
activeLineNumber: '#F8F8F2',
|
||||
matchingBracket: '#44475A',
|
||||
keyword: '#FF79C6',
|
||||
storage: '#FF79C6',
|
||||
variable: '#F8F8F2',
|
||||
parameter: '#F8F8F2',
|
||||
function: '#50FA7B',
|
||||
string: '#F1FA8C',
|
||||
constant: '#BD93F9',
|
||||
type: '#8BE9FD',
|
||||
class: '#8BE9FD',
|
||||
number: '#BD93F9',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#F8F8F2',
|
||||
foregroundSecondary: '#F8F8F2',
|
||||
comment: '#6272A4',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#FF79C6',
|
||||
string: '#F1FA8C',
|
||||
function: '#50FA7B',
|
||||
number: '#BD93F9',
|
||||
operator: '#FF79C6',
|
||||
variable: '#F8F8F2',
|
||||
type: '#8BE9FD',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#BD93F9',
|
||||
storage: '#FF79C6',
|
||||
parameter: '#F8F8F2',
|
||||
class: '#8BE9FD',
|
||||
heading: '#BD93F9',
|
||||
invalid: '#FF5555',
|
||||
regexp: '#F1FA8C',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#F8F8F2',
|
||||
selection: '#44475A',
|
||||
selectionBlur: '#44475A',
|
||||
activeLine: '#53576c22',
|
||||
lineNumber: '#6272A4',
|
||||
activeLineNumber: '#F8F8F2',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#191A21',
|
||||
borderLight: '#F8F8F219',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#50FA7B',
|
||||
matchingBracket: '#44475A',
|
||||
}
|
||||
|
||||
export const draculaTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const draculaHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const dracula: Extension = [
|
||||
draculaTheme,
|
||||
syntaxHighlighting(draculaHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Dracula 主题
|
||||
export const dracula: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView, lineNumbers} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'githubDark',
|
||||
export const config: ThemeColors = {
|
||||
name: 'github-dark',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: '#24292e',
|
||||
foreground: '#d1d5da',
|
||||
selection: '#3392FF44',
|
||||
cursor: '#c8e1ff',
|
||||
backgroundSecondary: '#24292e',
|
||||
surface: '#24292e',
|
||||
dropdownBackground: '#24292e',
|
||||
dropdownBorder: '#1b1f23',
|
||||
activeLine: '#4d566022',
|
||||
lineNumber: '#444d56',
|
||||
activeLineNumber: '#e1e4e8',
|
||||
matchingBracket: '#17E5E650',
|
||||
keyword: '#f97583',
|
||||
storage: '#f97583',
|
||||
variable: '#ffab70',
|
||||
parameter: '#e1e4e8',
|
||||
function: '#79b8ff',
|
||||
string: '#9ecbff',
|
||||
constant: '#79b8ff',
|
||||
type: '#79b8ff',
|
||||
class: '#b392f0',
|
||||
number: '#79b8ff',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#d1d5da',
|
||||
foregroundSecondary: '#d1d5da',
|
||||
comment: '#6a737d',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#f97583',
|
||||
string: '#9ecbff',
|
||||
function: '#79b8ff',
|
||||
number: '#79b8ff',
|
||||
operator: '#f97583',
|
||||
variable: '#ffab70',
|
||||
type: '#79b8ff',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#79b8ff',
|
||||
storage: '#f97583',
|
||||
parameter: '#e1e4e8',
|
||||
class: '#b392f0',
|
||||
heading: '#79b8ff',
|
||||
invalid: '#f97583',
|
||||
regexp: '#9ecbff',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#c8e1ff',
|
||||
selection: '#3392FF44',
|
||||
selectionBlur: '#3392FF44',
|
||||
activeLine: '#4d566022',
|
||||
lineNumber: '#444d56',
|
||||
activeLineNumber: '#e1e4e8',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#1b1f23',
|
||||
borderLight: '#d1d5da19',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#79b8ff',
|
||||
matchingBracket: '#17E5E650',
|
||||
}
|
||||
|
||||
export const githubDarkTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const githubDarkHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const githubDark: Extension = [
|
||||
githubDarkTheme,
|
||||
syntaxHighlighting(githubDarkHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 GitHub Dark 主题
|
||||
export const githubDark: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'materialDark',
|
||||
export const config: ThemeColors = {
|
||||
name: 'material-dark',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: '#263238',
|
||||
foreground: '#EEFFFF',
|
||||
selection: '#80CBC420',
|
||||
cursor: '#FFCC00',
|
||||
backgroundSecondary: '#263238',
|
||||
surface: '#263238',
|
||||
dropdownBackground: '#263238',
|
||||
dropdownBorder: '#FFFFFF10',
|
||||
activeLine: '#4c616c22',
|
||||
lineNumber: '#37474F',
|
||||
activeLineNumber: '#607a86',
|
||||
matchingBracket: '#263238',
|
||||
keyword: '#C792EA',
|
||||
storage: '#C792EA',
|
||||
variable: '#EEFFFF',
|
||||
parameter: '#EEFFFF',
|
||||
function: '#82AAFF',
|
||||
string: '#C3E88D',
|
||||
constant: '#F78C6C',
|
||||
type: '#B2CCD6',
|
||||
class: '#FFCB6B',
|
||||
number: '#F78C6C',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#EEFFFF',
|
||||
foregroundSecondary: '#EEFFFF',
|
||||
comment: '#546E7A',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#C792EA',
|
||||
string: '#C3E88D',
|
||||
function: '#82AAFF',
|
||||
number: '#F78C6C',
|
||||
operator: '#C792EA',
|
||||
variable: '#EEFFFF',
|
||||
type: '#B2CCD6',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#F78C6C',
|
||||
storage: '#C792EA',
|
||||
parameter: '#EEFFFF',
|
||||
class: '#FFCB6B',
|
||||
heading: '#C3E88D',
|
||||
invalid: '#FF5370',
|
||||
regexp: '#89DDFF',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#FFCC00',
|
||||
selection: '#80CBC420',
|
||||
selectionBlur: '#80CBC420',
|
||||
activeLine: '#4c616c22',
|
||||
lineNumber: '#37474F',
|
||||
activeLineNumber: '#607a86',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#FFFFFF10',
|
||||
borderLight: '#EEFFFF19',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#82AAFF',
|
||||
matchingBracket: '#263238',
|
||||
}
|
||||
|
||||
export const materialDarkTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const materialDarkHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const materialDark: Extension = [
|
||||
materialDarkTheme,
|
||||
syntaxHighlighting(materialDarkHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Material Dark 主题
|
||||
export const materialDark: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {EditorView} from "@codemirror/view"
|
||||
import {Extension} from "@codemirror/state"
|
||||
import {HighlightStyle, syntaxHighlighting} from "@codemirror/language"
|
||||
import {tags as t} from "@lezer/highlight"
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
// Using https://github.com/one-dark/vscode-one-dark-theme/ as reference for the colors
|
||||
|
||||
@@ -22,133 +21,56 @@ const chalky = "#e5c07b",
|
||||
selection = "#3E4451",
|
||||
cursor = "#528bff"
|
||||
|
||||
/// The colors used in the theme, as CSS color strings.
|
||||
export const color = {
|
||||
chalky,
|
||||
coral,
|
||||
cyan,
|
||||
invalid,
|
||||
ivory,
|
||||
stone,
|
||||
malibu,
|
||||
sage,
|
||||
whiskey,
|
||||
violet,
|
||||
darkBackground,
|
||||
highlightBackground,
|
||||
background,
|
||||
tooltipBackground,
|
||||
selection,
|
||||
cursor
|
||||
export const config: ThemeColors = {
|
||||
name: 'one-dark',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: background,
|
||||
backgroundSecondary: highlightBackground,
|
||||
surface: tooltipBackground,
|
||||
dropdownBackground: darkBackground,
|
||||
dropdownBorder: stone,
|
||||
|
||||
// 文本颜色
|
||||
foreground: ivory,
|
||||
foregroundSecondary: stone,
|
||||
comment: stone,
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: violet,
|
||||
string: sage,
|
||||
function: malibu,
|
||||
number: chalky,
|
||||
operator: cyan,
|
||||
variable: coral,
|
||||
type: chalky,
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: whiskey,
|
||||
storage: violet,
|
||||
parameter: coral,
|
||||
class: chalky,
|
||||
heading: coral,
|
||||
invalid: invalid,
|
||||
regexp: cyan,
|
||||
|
||||
// 界面元素
|
||||
cursor: cursor,
|
||||
selection: selection,
|
||||
selectionBlur: selection,
|
||||
activeLine: '#6699ff0b',
|
||||
lineNumber: stone,
|
||||
activeLineNumber: ivory,
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: darkBackground,
|
||||
borderLight: ivory + '19',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: malibu,
|
||||
matchingBracket: '#bad0f847',
|
||||
}
|
||||
|
||||
/// The editor theme styles for One Dark.
|
||||
export const oneDarkTheme = EditorView.theme({
|
||||
"&": {
|
||||
color: ivory,
|
||||
backgroundColor: background
|
||||
},
|
||||
|
||||
".cm-content": {
|
||||
caretColor: cursor
|
||||
},
|
||||
|
||||
".cm-cursor, .cm-dropCursor": {borderLeftColor: cursor},
|
||||
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": {backgroundColor: selection},
|
||||
|
||||
".cm-panels": {backgroundColor: darkBackground, color: ivory},
|
||||
".cm-panels.cm-panels-top": {borderBottom: "2px solid black"},
|
||||
".cm-panels.cm-panels-bottom": {borderTop: "2px solid black"},
|
||||
|
||||
".cm-searchMatch": {
|
||||
backgroundColor: "#72a1ff59",
|
||||
outline: "1px solid #457dff"
|
||||
},
|
||||
".cm-searchMatch.cm-searchMatch-selected": {
|
||||
backgroundColor: "#6199ff2f"
|
||||
},
|
||||
|
||||
".cm-activeLine": {backgroundColor: "#6699ff0b"},
|
||||
".cm-selectionMatch": {backgroundColor: "#aafe661a"},
|
||||
|
||||
"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket": {
|
||||
backgroundColor: "#bad0f847"
|
||||
},
|
||||
|
||||
".cm-gutters": {
|
||||
backgroundColor: background,
|
||||
color: stone,
|
||||
border: "none"
|
||||
},
|
||||
|
||||
".cm-activeLineGutter": {
|
||||
backgroundColor: highlightBackground
|
||||
},
|
||||
|
||||
".cm-foldPlaceholder": {
|
||||
backgroundColor: "transparent",
|
||||
border: "none",
|
||||
color: "#ddd"
|
||||
},
|
||||
|
||||
".cm-tooltip": {
|
||||
border: "none",
|
||||
backgroundColor: tooltipBackground
|
||||
},
|
||||
".cm-tooltip .cm-tooltip-arrow:before": {
|
||||
borderTopColor: "transparent",
|
||||
borderBottomColor: "transparent"
|
||||
},
|
||||
".cm-tooltip .cm-tooltip-arrow:after": {
|
||||
borderTopColor: tooltipBackground,
|
||||
borderBottomColor: tooltipBackground
|
||||
},
|
||||
".cm-tooltip-autocomplete": {
|
||||
"& > ul > li[aria-selected]": {
|
||||
backgroundColor: highlightBackground,
|
||||
color: ivory
|
||||
}
|
||||
}
|
||||
}, {dark: true})
|
||||
|
||||
/// The highlighting style for code in the One Dark theme.
|
||||
export const oneDarkHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword,
|
||||
color: violet},
|
||||
{tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
|
||||
color: coral},
|
||||
{tag: [t.function(t.variableName), t.labelName],
|
||||
color: malibu},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)],
|
||||
color: whiskey},
|
||||
{tag: [t.definition(t.name), t.separator],
|
||||
color: ivory},
|
||||
{tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace],
|
||||
color: chalky},
|
||||
{tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)],
|
||||
color: cyan},
|
||||
{tag: [t.meta, t.comment],
|
||||
color: stone},
|
||||
{tag: t.strong,
|
||||
fontWeight: "bold"},
|
||||
{tag: t.emphasis,
|
||||
fontStyle: "italic"},
|
||||
{tag: t.strikethrough,
|
||||
textDecoration: "line-through"},
|
||||
{tag: t.link,
|
||||
color: stone,
|
||||
textDecoration: "underline"},
|
||||
{tag: t.heading,
|
||||
fontWeight: "bold",
|
||||
color: coral},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)],
|
||||
color: whiskey },
|
||||
{tag: [t.processingInstruction, t.string, t.inserted],
|
||||
color: sage},
|
||||
{tag: t.invalid,
|
||||
color: invalid},
|
||||
])
|
||||
|
||||
/// Extension to enable the One Dark theme (both the editor theme and
|
||||
/// the highlight style).
|
||||
export const oneDark: Extension = [oneDarkTheme, syntaxHighlighting(oneDarkHighlightStyle)]
|
||||
// 使用通用主题工厂函数创建 One Dark 主题
|
||||
export const oneDark: Extension = createBaseTheme(config)
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'solarizedDark',
|
||||
export const config: ThemeColors = {
|
||||
name: 'solarized-dark',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: '#002B36',
|
||||
foreground: '#93A1A1',
|
||||
selection: '#274642',
|
||||
cursor: '#D30102',
|
||||
backgroundSecondary: '#002B36',
|
||||
surface: '#002B36',
|
||||
dropdownBackground: '#002B36',
|
||||
dropdownBorder: '#2AA19899',
|
||||
activeLine: '#005b7022',
|
||||
lineNumber: '#93A1A1',
|
||||
activeLineNumber: '#949494',
|
||||
matchingBracket: '#073642',
|
||||
keyword: '#859900',
|
||||
storage: '#93A1A1',
|
||||
variable: '#268BD2',
|
||||
parameter: '#268BD2',
|
||||
function: '#268BD2',
|
||||
string: '#2AA198',
|
||||
constant: '#CB4B16',
|
||||
type: '#CB4B16',
|
||||
class: '#CB4B16',
|
||||
number: '#D33682',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#93A1A1',
|
||||
foregroundSecondary: '#93A1A1',
|
||||
comment: '#586E75',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#859900',
|
||||
string: '#2AA198',
|
||||
function: '#268BD2',
|
||||
number: '#D33682',
|
||||
operator: '#859900',
|
||||
variable: '#268BD2',
|
||||
type: '#CB4B16',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#CB4B16',
|
||||
storage: '#93A1A1',
|
||||
parameter: '#268BD2',
|
||||
class: '#CB4B16',
|
||||
heading: '#268BD2',
|
||||
invalid: '#DC322F',
|
||||
regexp: '#DC322F',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#D30102',
|
||||
selection: '#274642',
|
||||
selectionBlur: '#274642',
|
||||
activeLine: '#005b7022',
|
||||
lineNumber: '#93A1A1',
|
||||
activeLineNumber: '#949494',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#073642',
|
||||
borderLight: '#93A1A119',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#2AA198',
|
||||
matchingBracket: '#073642',
|
||||
}
|
||||
|
||||
export const solarizedDarkTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const solarizedDarkHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const solarizedDark: Extension = [
|
||||
solarizedDarkTheme,
|
||||
syntaxHighlighting(solarizedDarkHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Solarized Dark 主题
|
||||
export const solarizedDark: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'tokyoNightStorm',
|
||||
export const config: ThemeColors = {
|
||||
name: 'tokyo-night-storm',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: '#24283b',
|
||||
foreground: '#7982a9',
|
||||
selection: '#6f7bb630',
|
||||
cursor: '#c0caf5',
|
||||
backgroundSecondary: '#24283b',
|
||||
surface: '#24283b',
|
||||
dropdownBackground: '#24283b',
|
||||
dropdownBorder: '#7982a9',
|
||||
activeLine: '#4d547722',
|
||||
lineNumber: '#3b4261',
|
||||
activeLineNumber: '#737aa2',
|
||||
matchingBracket: '#1f2335',
|
||||
keyword: '#bb9af7',
|
||||
storage: '#bb9af7',
|
||||
variable: '#c0caf5',
|
||||
parameter: '#c0caf5',
|
||||
function: '#7aa2f7',
|
||||
string: '#9ece6a',
|
||||
constant: '#bb9af7',
|
||||
type: '#2ac3de',
|
||||
class: '#c0caf5',
|
||||
number: '#ff9e64',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#7982a9',
|
||||
foregroundSecondary: '#7982a9',
|
||||
comment: '#565f89',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#bb9af7',
|
||||
string: '#9ece6a',
|
||||
function: '#7aa2f7',
|
||||
number: '#ff9e64',
|
||||
operator: '#bb9af7',
|
||||
variable: '#c0caf5',
|
||||
type: '#2ac3de',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#bb9af7',
|
||||
storage: '#bb9af7',
|
||||
parameter: '#c0caf5',
|
||||
class: '#c0caf5',
|
||||
heading: '#89ddff',
|
||||
invalid: '#ff5370',
|
||||
regexp: '#b4f9f8',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#c0caf5',
|
||||
selection: '#6f7bb630',
|
||||
selectionBlur: '#6f7bb630',
|
||||
activeLine: '#4d547722',
|
||||
lineNumber: '#3b4261',
|
||||
activeLineNumber: '#737aa2',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#1f2335',
|
||||
borderLight: '#7982a919',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#7aa2f7',
|
||||
matchingBracket: '#1f2335',
|
||||
}
|
||||
|
||||
export const tokyoNightStormTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const tokyoNightStormHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const tokyoNightStorm: Extension = [
|
||||
tokyoNightStormTheme,
|
||||
syntaxHighlighting(tokyoNightStormHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Tokyo Night Storm 主题
|
||||
export const tokyoNightStorm: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'tokyoNight',
|
||||
export const config: ThemeColors = {
|
||||
name: 'tokyo-night',
|
||||
dark: true,
|
||||
|
||||
// 基础色调
|
||||
background: '#1a1b26',
|
||||
foreground: '#787c99',
|
||||
selection: '#515c7e40',
|
||||
cursor: '#c0caf5',
|
||||
backgroundSecondary: '#1a1b26',
|
||||
surface: '#1a1b26',
|
||||
dropdownBackground: '#1a1b26',
|
||||
dropdownBorder: '#787c99',
|
||||
activeLine: '#43455c22',
|
||||
lineNumber: '#363b54',
|
||||
activeLineNumber: '#737aa2',
|
||||
matchingBracket: '#16161e',
|
||||
keyword: '#bb9af7',
|
||||
storage: '#bb9af7',
|
||||
variable: '#c0caf5',
|
||||
parameter: '#c0caf5',
|
||||
function: '#7aa2f7',
|
||||
string: '#9ece6a',
|
||||
constant: '#bb9af7',
|
||||
type: '#0db9d7',
|
||||
class: '#c0caf5',
|
||||
number: '#ff9e64',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#787c99',
|
||||
foregroundSecondary: '#787c99',
|
||||
comment: '#444b6a',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#bb9af7',
|
||||
string: '#9ece6a',
|
||||
function: '#7aa2f7',
|
||||
number: '#ff9e64',
|
||||
operator: '#bb9af7',
|
||||
variable: '#c0caf5',
|
||||
type: '#0db9d7',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#bb9af7',
|
||||
storage: '#bb9af7',
|
||||
parameter: '#c0caf5',
|
||||
class: '#c0caf5',
|
||||
heading: '#89ddff',
|
||||
invalid: '#ff5370',
|
||||
regexp: '#b4f9f8',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#c0caf5',
|
||||
selection: '#515c7e40',
|
||||
selectionBlur: '#515c7e40',
|
||||
activeLine: '#43455c22',
|
||||
lineNumber: '#363b54',
|
||||
activeLineNumber: '#737aa2',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#16161e',
|
||||
borderLight: '#787c9919',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#7aa2f7',
|
||||
matchingBracket: '#16161e',
|
||||
}
|
||||
|
||||
export const tokyoNightTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const tokyoNightHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const tokyoNight: Extension = [
|
||||
tokyoNightTheme,
|
||||
syntaxHighlighting(tokyoNightHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Tokyo Night 主题
|
||||
export const tokyoNight: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
import {EditorView} from '@codemirror/view';
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language';
|
||||
import {tags} from '@lezer/highlight';
|
||||
|
||||
// 默认浅色主题颜色
|
||||
export const defaultLightColors = {
|
||||
// 基础色调
|
||||
background: '#ffffff', // 主背景色
|
||||
backgroundSecondary: '#f1faf1', // 次要背景色
|
||||
surface: '#f5f5f5', // 面板背景
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#444d56', // 主文本色
|
||||
foregroundSecondary: '#6a737d', // 次要文本色
|
||||
comment: '#6a737d', // 注释色
|
||||
|
||||
// 语法高亮色
|
||||
keyword: '#d73a49', // 关键字
|
||||
string: '#032f62', // 字符串
|
||||
function: '#005cc5', // 函数名
|
||||
number: '#005cc5', // 数字
|
||||
operator: '#d73a49', // 操作符
|
||||
variable: '#24292e', // 变量
|
||||
type: '#6f42c1', // 类型
|
||||
|
||||
// 界面元素
|
||||
cursor: '#000000', // 光标
|
||||
selection: '#77baff', // 选中背景
|
||||
selectionBlur: '#b2c2ca', // 失焦选中背景
|
||||
activeLine: '#0000000a', // 当前行高亮
|
||||
lineNumber: '#00000040', // 行号
|
||||
activeLineNumber: '#000000aa', // 活动行号
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#dfdfdf', // 边框色
|
||||
borderLight: '#0000000c', // 浅色边框
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#005cc5', // 搜索匹配
|
||||
matchingBracket: '#00000019', // 匹配括号
|
||||
};
|
||||
|
||||
// 创建浅色主题
|
||||
export function createLightTheme(colors = defaultLightColors) {
|
||||
const lightTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: colors.foreground,
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
|
||||
// 确保编辑器容器背景一致
|
||||
'.cm-editor': {
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
|
||||
// 确保滚动区域背景一致
|
||||
'.cm-scroller': {
|
||||
backgroundColor: colors.background,
|
||||
},
|
||||
|
||||
// 编辑器内容
|
||||
'.cm-content': {
|
||||
caretColor: colors.cursor,
|
||||
paddingTop: '4px',
|
||||
},
|
||||
|
||||
// 光标
|
||||
'.cm-cursor, .cm-dropCursor': {
|
||||
borderLeftColor: colors.cursor,
|
||||
borderLeftWidth: '2px',
|
||||
paddingTop: '4px',
|
||||
marginTop: '-2px',
|
||||
},
|
||||
|
||||
// 选择
|
||||
'.cm-selectionBackground': {
|
||||
backgroundColor: colors.selectionBlur,
|
||||
},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
|
||||
backgroundColor: colors.selection,
|
||||
},
|
||||
'.cm-activeLine.code-empty-block-selected': {
|
||||
backgroundColor: colors.selection,
|
||||
},
|
||||
|
||||
// 当前行高亮
|
||||
'.cm-activeLine': {
|
||||
backgroundColor: colors.activeLine
|
||||
},
|
||||
|
||||
// 行号区域
|
||||
'.cm-gutters': {
|
||||
backgroundColor: 'rgba(0,0,0, 0.04)',
|
||||
color: colors.lineNumber,
|
||||
border: 'none',
|
||||
borderRight: `1px solid ${colors.borderLight}`,
|
||||
padding: '0 2px 0 4px',
|
||||
userSelect: 'none',
|
||||
},
|
||||
'.cm-activeLineGutter': {
|
||||
backgroundColor: 'transparent',
|
||||
color: colors.activeLineNumber,
|
||||
},
|
||||
|
||||
// 折叠功能
|
||||
'.cm-foldGutter': {
|
||||
marginLeft: '0px',
|
||||
},
|
||||
'.cm-foldGutter .cm-gutterElement': {
|
||||
opacity: 0,
|
||||
transition: 'opacity 400ms',
|
||||
},
|
||||
'.cm-gutters:hover .cm-gutterElement': {
|
||||
opacity: 1,
|
||||
},
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: colors.comment,
|
||||
},
|
||||
|
||||
|
||||
// 搜索匹配
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: 'transparent',
|
||||
outline: `1px solid ${colors.searchMatch}`,
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: colors.searchMatch,
|
||||
color: colors.background,
|
||||
},
|
||||
'.cm-selectionMatch': {
|
||||
backgroundColor: '#e6f3ff',
|
||||
},
|
||||
|
||||
// 括号匹配
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
outline: `0.5px solid ${colors.searchMatch}`,
|
||||
},
|
||||
'&.cm-focused .cm-matchingBracket': {
|
||||
backgroundColor: colors.matchingBracket,
|
||||
color: 'inherit',
|
||||
},
|
||||
'&.cm-focused .cm-nonmatchingBracket': {
|
||||
outline: '0.5px solid #d73a49',
|
||||
},
|
||||
|
||||
// 编辑器焦点
|
||||
'&.cm-editor.cm-focused': {
|
||||
outline: 'none',
|
||||
},
|
||||
|
||||
// 工具提示
|
||||
'.cm-tooltip': {
|
||||
border: 'none',
|
||||
backgroundColor: colors.surface,
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent',
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: colors.surface,
|
||||
borderBottomColor: colors.surface,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
backgroundColor: colors.activeLine,
|
||||
color: colors.foreground,
|
||||
},
|
||||
},
|
||||
|
||||
// 代码块层
|
||||
'.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-blocks-math-result': {
|
||||
paddingLeft: "12px",
|
||||
position: "relative",
|
||||
},
|
||||
'.code-blocks-math-result .inner': {
|
||||
background: '#48b57e',
|
||||
color: '#fff',
|
||||
padding: '0px 4px',
|
||||
borderRadius: '2px',
|
||||
boxShadow: '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: "rgba(0,0,0, 0.8)",
|
||||
},
|
||||
'.code-blocks-math-result-copied.fade-out': {
|
||||
opacity: 0,
|
||||
},
|
||||
|
||||
// 代码块开始标记
|
||||
'.code-block-start': {
|
||||
height: '12px',
|
||||
},
|
||||
'.code-block-start.first': {
|
||||
height: '0px',
|
||||
},
|
||||
}, {dark: false});
|
||||
|
||||
// 语法高亮样式
|
||||
const lightHighlightStyle = HighlightStyle.define([
|
||||
{tag: tags.keyword, color: colors.keyword},
|
||||
{tag: [tags.name, tags.deleted, tags.character, tags.propertyName, tags.macroName], color: colors.variable},
|
||||
{tag: [tags.variableName], color: colors.variable},
|
||||
{tag: [tags.function(tags.variableName)], color: colors.function},
|
||||
{tag: [tags.labelName], color: colors.operator},
|
||||
{tag: [tags.color, tags.constant(tags.name), tags.standard(tags.name)], color: colors.keyword},
|
||||
{tag: [tags.definition(tags.name), tags.separator], color: colors.function},
|
||||
{tag: [tags.brace], color: colors.variable},
|
||||
{tag: [tags.annotation], color: '#d73a49'},
|
||||
{
|
||||
tag: [tags.number, tags.changed, tags.annotation, tags.modifier, tags.self, tags.namespace],
|
||||
color: colors.number
|
||||
},
|
||||
{tag: [tags.typeName, tags.className], color: colors.type},
|
||||
{tag: [tags.operator, tags.operatorKeyword], color: colors.operator},
|
||||
{tag: [tags.tagName], color: colors.type},
|
||||
{tag: [tags.squareBracket], color: colors.keyword},
|
||||
{tag: [tags.angleBracket], color: colors.operator},
|
||||
{tag: [tags.attributeName], color: colors.variable},
|
||||
{tag: [tags.regexp], color: colors.string},
|
||||
{tag: [tags.quote], color: colors.comment},
|
||||
{tag: [tags.string], color: colors.string},
|
||||
{tag: tags.link, color: colors.function, textDecoration: 'underline'},
|
||||
{tag: [tags.url, tags.escape, tags.special(tags.string)], color: colors.string},
|
||||
{tag: [tags.meta], color: colors.comment},
|
||||
{tag: [tags.comment], color: colors.comment, fontStyle: 'italic'},
|
||||
{tag: tags.strong, fontWeight: 'bold'},
|
||||
{tag: tags.emphasis, fontStyle: 'italic'},
|
||||
{tag: tags.strikethrough, textDecoration: 'line-through'},
|
||||
{tag: tags.heading, fontWeight: 'bold', color: colors.keyword},
|
||||
{tag: [tags.heading1, tags.heading2], fontSize: '1.4em'},
|
||||
{tag: [tags.heading3, tags.heading4], fontSize: '1.2em'},
|
||||
{tag: [tags.heading5, tags.heading6], fontSize: '1.1em'},
|
||||
]);
|
||||
|
||||
return [
|
||||
lightTheme,
|
||||
syntaxHighlighting(lightHighlightStyle),
|
||||
];
|
||||
}
|
||||
|
||||
// 默认浅色主题
|
||||
export const light = createLightTheme(defaultLightColors);
|
||||
63
frontend/src/views/editor/theme/light/default-light.ts
Normal file
63
frontend/src/views/editor/theme/light/default-light.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import {createBaseTheme} from '../base';
|
||||
import type {ThemeColors} from '../types';
|
||||
|
||||
// 默认浅色主题颜色
|
||||
export const defaultLightColors: ThemeColors = {
|
||||
// 主题信息
|
||||
name: 'default-light',
|
||||
dark: false,
|
||||
|
||||
// 基础色调
|
||||
background: '#ffffff', // 主背景色
|
||||
backgroundSecondary: '#f1faf1', // 次要背景色
|
||||
surface: '#f5f5f5', // 面板背景
|
||||
dropdownBackground: '#ffffff', // 下拉菜单背景
|
||||
dropdownBorder: '#e1e4e8', // 下拉菜单边框
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#444d56', // 主文本色
|
||||
foregroundSecondary: '#6a737d', // 次要文本色
|
||||
comment: '#6a737d', // 注释色
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#d73a49', // 关键字
|
||||
string: '#032f62', // 字符串
|
||||
function: '#005cc5', // 函数名
|
||||
number: '#005cc5', // 数字
|
||||
operator: '#d73a49', // 操作符
|
||||
variable: '#24292e', // 变量
|
||||
type: '#6f42c1', // 类型
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#005cc5', // 常量
|
||||
storage: '#d73a49', // 存储类型
|
||||
parameter: '#24292e', // 参数
|
||||
class: '#6f42c1', // 类名
|
||||
heading: '#d73a49', // 标题
|
||||
invalid: '#cb2431', // 无效内容
|
||||
regexp: '#032f62', // 正则表达式
|
||||
|
||||
// 界面元素
|
||||
cursor: '#000000', // 光标
|
||||
selection: '#77baff', // 选中背景
|
||||
selectionBlur: '#b2c2ca', // 失焦选中背景
|
||||
activeLine: '#0000000a', // 当前行高亮
|
||||
lineNumber: '#00000040', // 行号
|
||||
activeLineNumber: '#000000aa', // 活动行号
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#dfdfdf', // 边框色
|
||||
borderLight: '#0000000c', // 浅色边框
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#005cc5', // 搜索匹配
|
||||
matchingBracket: '#00000019', // 匹配括号
|
||||
};
|
||||
|
||||
// 创建浅色主题
|
||||
export function createLightTheme(colors: ThemeColors = defaultLightColors) {
|
||||
return createBaseTheme({...colors, dark: false});
|
||||
}
|
||||
|
||||
// 默认浅色主题
|
||||
export const defaultLight = createLightTheme(defaultLightColors);
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'githubLight',
|
||||
export const config: ThemeColors = {
|
||||
name: 'github-light',
|
||||
dark: false,
|
||||
|
||||
// 基础色调
|
||||
background: '#fff',
|
||||
foreground: '#444d56',
|
||||
selection: '#0366d625',
|
||||
cursor: '#044289',
|
||||
backgroundSecondary: '#fff',
|
||||
surface: '#fff',
|
||||
dropdownBackground: '#fff',
|
||||
dropdownBorder: '#e1e4e8',
|
||||
activeLine: '#c6c6c622',
|
||||
lineNumber: '#1b1f234d',
|
||||
activeLineNumber: '#24292e',
|
||||
matchingBracket: '#34d05840',
|
||||
keyword: '#d73a49',
|
||||
storage: '#d73a49',
|
||||
variable: '#e36209',
|
||||
parameter: '#24292e',
|
||||
function: '#005cc5',
|
||||
string: '#032f62',
|
||||
constant: '#005cc5',
|
||||
type: '#005cc5',
|
||||
class: '#6f42c1',
|
||||
number: '#005cc5',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#444d56',
|
||||
foregroundSecondary: '#444d56',
|
||||
comment: '#6a737d',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#d73a49',
|
||||
string: '#032f62',
|
||||
function: '#005cc5',
|
||||
number: '#005cc5',
|
||||
operator: '#d73a49',
|
||||
variable: '#e36209',
|
||||
type: '#005cc5',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#005cc5',
|
||||
storage: '#d73a49',
|
||||
parameter: '#24292e',
|
||||
class: '#6f42c1',
|
||||
heading: '#005cc5',
|
||||
invalid: '#cb2431',
|
||||
regexp: '#032f62',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#044289',
|
||||
selection: '#0366d625',
|
||||
selectionBlur: '#0366d625',
|
||||
activeLine: '#c6c6c622',
|
||||
lineNumber: '#1b1f234d',
|
||||
activeLineNumber: '#24292e',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#e1e4e8',
|
||||
borderLight: '#444d5619',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#005cc5',
|
||||
matchingBracket: '#34d05840',
|
||||
}
|
||||
|
||||
export const githubLightTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const githubLightHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const githubLight: Extension = [
|
||||
githubLightTheme,
|
||||
syntaxHighlighting(githubLightHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 GitHub Light 主题
|
||||
export const githubLight: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'materialLight',
|
||||
export const config: ThemeColors = {
|
||||
name: 'material-light',
|
||||
dark: false,
|
||||
|
||||
// 基础色调
|
||||
background: '#FAFAFA',
|
||||
foreground: '#90A4AE',
|
||||
selection: '#80CBC440',
|
||||
cursor: '#272727',
|
||||
backgroundSecondary: '#FAFAFA',
|
||||
surface: '#FAFAFA',
|
||||
dropdownBackground: '#FAFAFA',
|
||||
dropdownBorder: '#00000010',
|
||||
activeLine: '#c2c2c222',
|
||||
lineNumber: '#CFD8DC',
|
||||
activeLineNumber: '#7E939E',
|
||||
matchingBracket: '#FAFAFA',
|
||||
keyword: '#7C4DFF',
|
||||
storage: '#7C4DFF',
|
||||
variable: '#90A4AE',
|
||||
parameter: '#90A4AE',
|
||||
function: '#6182B8',
|
||||
string: '#91B859',
|
||||
constant: '#F76D47',
|
||||
type: '#8796B0',
|
||||
class: '#FFB62C',
|
||||
number: '#F76D47',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#90A4AE',
|
||||
foregroundSecondary: '#90A4AE',
|
||||
comment: '#90A4AE',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#7C4DFF',
|
||||
string: '#91B859',
|
||||
function: '#6182B8',
|
||||
number: '#F76D47',
|
||||
operator: '#7C4DFF',
|
||||
variable: '#90A4AE',
|
||||
type: '#8796B0',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#F76D47',
|
||||
storage: '#7C4DFF',
|
||||
parameter: '#90A4AE',
|
||||
class: '#FFB62C',
|
||||
heading: '#91B859',
|
||||
invalid: '#E53935',
|
||||
regexp: '#39ADB5',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#272727',
|
||||
selection: '#80CBC440',
|
||||
selectionBlur: '#80CBC440',
|
||||
activeLine: '#c2c2c222',
|
||||
lineNumber: '#CFD8DC',
|
||||
activeLineNumber: '#7E939E',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#00000010',
|
||||
borderLight: '#90A4AE19',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#6182B8',
|
||||
matchingBracket: '#FAFAFA',
|
||||
}
|
||||
|
||||
export const materialLightTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const materialLightHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const materialLight: Extension = [
|
||||
materialLightTheme,
|
||||
syntaxHighlighting(materialLightHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Material Light 主题
|
||||
export const materialLight: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'solarizedLight',
|
||||
export const config: ThemeColors = {
|
||||
name: 'solarized-light',
|
||||
dark: false,
|
||||
|
||||
// 基础色调
|
||||
background: '#FDF6E3',
|
||||
foreground: '#586E75',
|
||||
selection: '#EEE8D5',
|
||||
cursor: '#657B83',
|
||||
backgroundSecondary: '#FDF6E3',
|
||||
surface: '#FDF6E3',
|
||||
dropdownBackground: '#FDF6E3',
|
||||
dropdownBorder: '#D3AF86',
|
||||
activeLine: '#d5bd5c22',
|
||||
lineNumber: '#586E75',
|
||||
activeLineNumber: '#567983',
|
||||
matchingBracket: '#EEE8D5',
|
||||
keyword: '#859900',
|
||||
storage: '#586E75',
|
||||
variable: '#268BD2',
|
||||
parameter: '#268BD2',
|
||||
function: '#268BD2',
|
||||
string: '#2AA198',
|
||||
constant: '#CB4B16',
|
||||
type: '#CB4B16',
|
||||
class: '#CB4B16',
|
||||
number: '#D33682',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#586E75',
|
||||
foregroundSecondary: '#586E75',
|
||||
comment: '#93A1A1',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#859900',
|
||||
string: '#2AA198',
|
||||
function: '#268BD2',
|
||||
number: '#D33682',
|
||||
operator: '#859900',
|
||||
variable: '#268BD2',
|
||||
type: '#CB4B16',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#CB4B16',
|
||||
storage: '#586E75',
|
||||
parameter: '#268BD2',
|
||||
class: '#CB4B16',
|
||||
heading: '#268BD2',
|
||||
invalid: '#DC322F',
|
||||
regexp: '#DC322F',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#657B83',
|
||||
selection: '#EEE8D5',
|
||||
selectionBlur: '#EEE8D5',
|
||||
activeLine: '#d5bd5c22',
|
||||
lineNumber: '#586E75',
|
||||
activeLineNumber: '#567983',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#EEE8D5',
|
||||
borderLight: '#586E7519',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#268BD2',
|
||||
matchingBracket: '#EEE8D5',
|
||||
}
|
||||
|
||||
export const solarizedLightTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const solarizedLightHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const solarizedLight: Extension = [
|
||||
solarizedLightTheme,
|
||||
syntaxHighlighting(solarizedLightHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Solarized Light 主题
|
||||
export const solarizedLight: Extension = createBaseTheme(config)
|
||||
|
||||
@@ -1,128 +1,57 @@
|
||||
import {EditorView} from '@codemirror/view'
|
||||
import {Extension} from '@codemirror/state'
|
||||
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
|
||||
import {tags as t} from '@lezer/highlight'
|
||||
import {createBaseTheme} from '../base'
|
||||
import type {ThemeColors} from '../types'
|
||||
|
||||
export const config = {
|
||||
name: 'tokyoNightDay',
|
||||
export const config: ThemeColors = {
|
||||
name: 'tokyo-night-day',
|
||||
dark: false,
|
||||
|
||||
// 基础色调
|
||||
background: '#e1e2e7',
|
||||
foreground: '#6a6f8e',
|
||||
selection: '#8591b840',
|
||||
cursor: '#3760bf',
|
||||
backgroundSecondary: '#e1e2e7',
|
||||
surface: '#e1e2e7',
|
||||
dropdownBackground: '#e1e2e7',
|
||||
dropdownBorder: '#6a6f8e',
|
||||
activeLine: '#a7aaba22',
|
||||
lineNumber: '#b3b6cd',
|
||||
activeLineNumber: '#68709a',
|
||||
matchingBracket: '#e9e9ec',
|
||||
keyword: '#9854f1',
|
||||
storage: '#9854f1',
|
||||
variable: '#3760bf',
|
||||
parameter: '#3760bf',
|
||||
function: '#2e7de9',
|
||||
string: '#587539',
|
||||
constant: '#9854f1',
|
||||
type: '#07879d',
|
||||
class: '#3760bf',
|
||||
number: '#b15c00',
|
||||
|
||||
// 文本颜色
|
||||
foreground: '#6a6f8e',
|
||||
foregroundSecondary: '#6a6f8e',
|
||||
comment: '#9da3c2',
|
||||
|
||||
// 语法高亮色 - 核心
|
||||
keyword: '#9854f1',
|
||||
string: '#587539',
|
||||
function: '#2e7de9',
|
||||
number: '#b15c00',
|
||||
operator: '#9854f1',
|
||||
variable: '#3760bf',
|
||||
type: '#07879d',
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: '#9854f1',
|
||||
storage: '#9854f1',
|
||||
parameter: '#3760bf',
|
||||
class: '#3760bf',
|
||||
heading: '#006a83',
|
||||
invalid: '#ff3e64',
|
||||
regexp: '#2e5857',
|
||||
|
||||
// 界面元素
|
||||
cursor: '#3760bf',
|
||||
selection: '#8591b840',
|
||||
selectionBlur: '#8591b840',
|
||||
activeLine: '#a7aaba22',
|
||||
lineNumber: '#b3b6cd',
|
||||
activeLineNumber: '#68709a',
|
||||
|
||||
// 边框和分割线
|
||||
borderColor: '#e9e9ec',
|
||||
borderLight: '#6a6f8e19',
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch: '#2e7de9',
|
||||
matchingBracket: '#e9e9ec',
|
||||
}
|
||||
|
||||
export const tokyoNightDayTheme = EditorView.theme({
|
||||
'&': {
|
||||
color: config.foreground,
|
||||
backgroundColor: config.background,
|
||||
},
|
||||
|
||||
'.cm-content': {caretColor: config.cursor},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': {borderLeftColor: config.cursor},
|
||||
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {backgroundColor: config.selection},
|
||||
|
||||
'.cm-panels': {backgroundColor: config.dropdownBackground, color: config.foreground},
|
||||
'.cm-panels.cm-panels-top': {borderBottom: '2px solid black'},
|
||||
'.cm-panels.cm-panels-bottom': {borderTop: '2px solid black'},
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: config.dropdownBackground,
|
||||
outline: `1px solid ${config.dropdownBorder}`
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: config.selection
|
||||
},
|
||||
|
||||
'.cm-activeLine': {backgroundColor: config.activeLine},
|
||||
'.cm-selectionMatch': {backgroundColor: config.selection},
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: config.matchingBracket,
|
||||
outline: 'none'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: config.background,
|
||||
color: config.foreground,
|
||||
border: 'none'
|
||||
},
|
||||
'.cm-activeLineGutter': {backgroundColor: config.background},
|
||||
|
||||
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
|
||||
'.cm-lineNumbers .cm-activeLineGutter': {color: config.activeLineNumber},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: config.foreground
|
||||
},
|
||||
'.cm-tooltip': {
|
||||
border: `1px solid ${config.dropdownBorder}`,
|
||||
backgroundColor: config.dropdownBackground,
|
||||
color: config.foreground,
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: config.foreground,
|
||||
borderBottomColor: config.foreground,
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
background: config.selection,
|
||||
color: config.foreground,
|
||||
}
|
||||
}
|
||||
}, {dark: config.dark})
|
||||
|
||||
export const tokyoNightDayHighlightStyle = HighlightStyle.define([
|
||||
{tag: t.keyword, color: config.keyword},
|
||||
{tag: [t.name, t.deleted, t.character, t.macroName], color: config.variable},
|
||||
{tag: [t.propertyName], color: config.function},
|
||||
{tag: [t.processingInstruction, t.string, t.inserted, t.special(t.string)], color: config.string},
|
||||
{tag: [t.function(t.variableName), t.labelName], color: config.function},
|
||||
{tag: [t.color, t.constant(t.name), t.standard(t.name)], color: config.constant},
|
||||
{tag: [t.definition(t.name), t.separator], color: config.variable},
|
||||
{tag: [t.className], color: config.class},
|
||||
{tag: [t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], color: config.number},
|
||||
{tag: [t.typeName], color: config.type, fontStyle: config.type},
|
||||
{tag: [t.operator, t.operatorKeyword], color: config.keyword},
|
||||
{tag: [t.url, t.escape, t.regexp, t.link], color: config.regexp},
|
||||
{tag: [t.meta, t.comment], color: config.comment},
|
||||
{tag: t.strong, fontWeight: 'bold'},
|
||||
{tag: t.emphasis, fontStyle: 'italic'},
|
||||
{tag: t.link, textDecoration: 'underline'},
|
||||
{tag: t.heading, fontWeight: 'bold', color: config.heading},
|
||||
{tag: [t.atom, t.bool, t.special(t.variableName)], color: config.variable},
|
||||
{tag: t.invalid, color: config.invalid},
|
||||
{tag: t.strikethrough, textDecoration: 'line-through'},
|
||||
])
|
||||
|
||||
export const tokyoNightDay: Extension = [
|
||||
tokyoNightDayTheme,
|
||||
syntaxHighlighting(tokyoNightDayHighlightStyle),
|
||||
]
|
||||
// 使用通用主题工厂函数创建 Tokyo Night Day 主题
|
||||
export const tokyoNightDay: Extension = createBaseTheme(config)
|
||||
|
||||
59
frontend/src/views/editor/theme/registry.ts
Normal file
59
frontend/src/views/editor/theme/registry.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Extension } from '@codemirror/state';
|
||||
import type { ThemeColors } from './types';
|
||||
import { createBaseTheme } from './base';
|
||||
|
||||
// 深色主题导入
|
||||
import { config as draculaConfig } from './dark/dracula';
|
||||
import { config as auraConfig } from './dark/aura';
|
||||
import { config as githubDarkConfig } from './dark/github-dark';
|
||||
import { config as materialDarkConfig } from './dark/material-dark';
|
||||
import { config as oneDarkConfig } from './dark/one-dark';
|
||||
import { config as solarizedDarkConfig } from './dark/solarized-dark';
|
||||
import { config as tokyoNightConfig } from './dark/tokyo-night';
|
||||
import { config as tokyoNightStormConfig } from './dark/tokyo-night-storm';
|
||||
|
||||
// 浅色主题导入
|
||||
import { config as githubLightConfig } from './light/github-light';
|
||||
import { config as materialLightConfig } from './light/material-light';
|
||||
import { config as solarizedLightConfig } from './light/solarized-light';
|
||||
import { config as tokyoNightDayConfig } from './light/tokyo-night-day';
|
||||
|
||||
/**
|
||||
* 主题配置映射表
|
||||
* key: 主题名称(与数据库中的 name 字段一致)
|
||||
* value: 主题颜色配置
|
||||
*/
|
||||
const themeConfigMap: Record<string, ThemeColors> = {
|
||||
// 深色主题
|
||||
'dracula': draculaConfig,
|
||||
'aura': auraConfig,
|
||||
'github-dark': githubDarkConfig,
|
||||
'material-dark': materialDarkConfig,
|
||||
'one-dark': oneDarkConfig,
|
||||
'solarized-dark': solarizedDarkConfig,
|
||||
'tokyo-night': tokyoNightConfig,
|
||||
'tokyo-night-storm': tokyoNightStormConfig,
|
||||
|
||||
// 浅色主题
|
||||
'github-light': githubLightConfig,
|
||||
'material-light': materialLightConfig,
|
||||
'solarized-light': solarizedLightConfig,
|
||||
'tokyo-night-day': tokyoNightDayConfig,
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据主题名称获取主题配置
|
||||
*/
|
||||
export function getThemeConfig(themeName: string): ThemeColors | null {
|
||||
return themeConfigMap[themeName] || null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据自定义颜色配置创建主题
|
||||
*/
|
||||
export function createThemeByColors(colors: ThemeColors): Extension {
|
||||
return createBaseTheme(colors);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +1,52 @@
|
||||
export interface ThemeColors {
|
||||
// 主题基本信息
|
||||
name?: string; // 主题名称
|
||||
dark?: boolean; // 是否为深色主题标识
|
||||
name: string; // 主题名称
|
||||
dark: boolean; // 是否为深色主题标识
|
||||
|
||||
// 基础色调
|
||||
background: string; // 主背景色
|
||||
backgroundSecondary?: string; // 次要背景色
|
||||
surface?: string; // 面板背景
|
||||
dropdownBackground?: string; // 下拉菜单背景
|
||||
dropdownBorder?: string; // 下拉菜单边框
|
||||
backgroundSecondary: string; // 次要背景色(用于代码块交替背景)
|
||||
surface: string; // 面板背景
|
||||
dropdownBackground: string; // 下拉菜单背景
|
||||
dropdownBorder: string; // 下拉菜单边框
|
||||
|
||||
// 文本颜色
|
||||
foreground: string; // 主文本色
|
||||
foregroundSecondary?: string; // 次要文本色
|
||||
foregroundSecondary: string; // 次要文本色
|
||||
comment: string; // 注释色
|
||||
|
||||
// 语法高亮色
|
||||
// 语法高亮色 - 核心
|
||||
keyword: string; // 关键字
|
||||
string: string; // 字符串
|
||||
function: string; // 函数名
|
||||
number: string; // 数字
|
||||
operator?: string; // 操作符
|
||||
operator: string; // 操作符
|
||||
variable: string; // 变量
|
||||
type: string; // 类型
|
||||
|
||||
// 语法高亮色 - 扩展
|
||||
constant: string; // 常量
|
||||
storage?: string; // 存储类型
|
||||
parameter?: string; // 参数
|
||||
class?: string; // 类名
|
||||
heading?: string; // 标题
|
||||
invalid?: string; // 无效内容
|
||||
regexp?: string; // 正则表达式
|
||||
storage: string; // 存储类型(如 static, const)
|
||||
parameter: string; // 参数
|
||||
class: string; // 类名
|
||||
heading: string; // 标题(Markdown等)
|
||||
invalid: string; // 无效内容/错误
|
||||
regexp: string; // 正则表达式
|
||||
|
||||
// 界面元素
|
||||
cursor: string; // 光标
|
||||
selection: string; // 选中背景
|
||||
selectionBlur?: string; // 失焦选中背景
|
||||
selectionBlur: string; // 失焦选中背景
|
||||
activeLine: string; // 当前行高亮
|
||||
lineNumber: string; // 行号
|
||||
activeLineNumber: string; // 活动行号颜色
|
||||
|
||||
// 边框和分割线
|
||||
borderColor?: string; // 边框色
|
||||
borderLight?: string; // 浅色边框
|
||||
borderColor: string; // 边框色
|
||||
borderLight: string; // 浅色边框
|
||||
|
||||
// 搜索和匹配
|
||||
searchMatch?: string; // 搜索匹配
|
||||
matchingBracket?: string; // 匹配括号
|
||||
searchMatch: string; // 搜索匹配
|
||||
matchingBracket: string; // 匹配括号
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user