♻️ Refactor code

This commit is contained in:
2025-06-02 13:34:54 +08:00
parent 44f7baad10
commit a516b8973e
53 changed files with 1513 additions and 1094 deletions

View File

@@ -0,0 +1,251 @@
<script setup lang="ts">
import {onBeforeUnmount, onMounted, ref, watch} from 'vue';
import {EditorState, Extension} from '@codemirror/state';
import {EditorView} from '@codemirror/view';
import {useEditorStore} from '@/stores/editorStore';
import {useConfigStore} from '@/stores/configStore';
import {useDocumentStore} from '@/stores/documentStore';
import {useLogStore} from '@/stores/logStore';
import {createBasicSetup} from './extensions/basicSetup';
import {
createStatsUpdateExtension,
createWheelZoomHandler,
getTabExtensions,
updateStats,
updateTabConfig,
createAutoSavePlugin,
createSaveShortcutPlugin,
createFontExtensionFromBackend,
updateFontConfig,
} from './extensions';
import { useI18n } from 'vue-i18n';
import { DocumentService } from '../../../bindings/voidraft/internal/services';
import Toolbar from '@/components/toolbar/Toolbar.vue';
const editorStore = useEditorStore();
const configStore = useConfigStore();
const documentStore = useDocumentStore();
const logStore = useLogStore();
const { t } = useI18n();
const props = defineProps({
initialDoc: {
type: String,
default: ''
}
});
const editorElement = ref<HTMLElement | null>(null);
const editorCreated = ref(false);
let isDestroying = false;
// 创建编辑器
const createEditor = async () => {
if (!editorElement.value || editorCreated.value) return;
editorCreated.value = true;
// 加载文档内容
await documentStore.initialize();
const docContent = documentStore.documentContent || props.initialDoc;
// 获取基本扩展
const basicExtensions = createBasicSetup();
// 获取Tab相关扩展
const tabExtensions = getTabExtensions(
configStore.config.tabSize,
configStore.config.enableTabIndent,
configStore.config.tabType
);
// 创建字体扩展
const fontExtension = createFontExtensionFromBackend({
fontFamily: configStore.config.fontFamily,
fontSize: configStore.config.fontSize,
lineHeight: configStore.config.lineHeight,
fontWeight: configStore.config.fontWeight
});
// 创建统计信息更新扩展
const statsExtension = createStatsUpdateExtension(
editorStore.updateDocumentStats
);
// 创建保存快捷键插件
const saveShortcutPlugin = createSaveShortcutPlugin(() => {
if (editorStore.editorView) {
handleManualSave();
}
});
// 创建自动保存插件
const autoSavePlugin = createAutoSavePlugin({
debounceDelay: 300, // 300毫秒的输入防抖
onSave: (success) => {
if (success) {
documentStore.lastSaved = new Date();
}
}
});
// 组合所有扩展
const extensions: Extension[] = [
...basicExtensions,
...tabExtensions,
fontExtension,
statsExtension,
saveShortcutPlugin,
autoSavePlugin
];
// 创建编辑器状态
const state = EditorState.create({
doc: docContent,
extensions
});
// 创建编辑器视图
const view = new EditorView({
state,
parent: editorElement.value
});
// 将编辑器实例保存到store
editorStore.setEditorView(view);
// 应用初始字体大小
editorStore.applyFontSize();
// 立即更新统计信息
updateStats(view, editorStore.updateDocumentStats);
};
// 创建滚轮事件处理器
const handleWheel = createWheelZoomHandler(
configStore.increaseFontSize,
configStore.decreaseFontSize
);
// 手动保存文档
const handleManualSave = async () => {
if (!editorStore.editorView || isDestroying) return;
const view = editorStore.editorView as EditorView;
const content = view.state.doc.toString();
// 先更新内容
await DocumentService.UpdateActiveDocumentContent(content);
// 然后调用强制保存方法不再传递content参数
const success = await documentStore.forceSaveDocument();
if (success) {
logStore.info(t('document.manualSaveSuccess'));
}
};
// 重新配置编辑器(仅在必要时)
const reconfigureTabSettings = () => {
if (!editorStore.editorView) return;
updateTabConfig(
editorStore.editorView as EditorView,
configStore.config.tabSize,
configStore.config.enableTabIndent,
configStore.config.tabType
);
};
// 重新配置字体设置
const reconfigureFontSettings = () => {
if (!editorStore.editorView) return;
updateFontConfig(editorStore.editorView as EditorView, {
fontFamily: configStore.config.fontFamily,
fontSize: configStore.config.fontSize,
lineHeight: configStore.config.lineHeight,
fontWeight: configStore.config.fontWeight
});
};
// 监听Tab设置变化
watch(() => configStore.config.tabSize, reconfigureTabSettings);
watch(() => configStore.config.enableTabIndent, reconfigureTabSettings);
watch(() => configStore.config.tabType, reconfigureTabSettings);
// 监听字体大小变化
watch(() => configStore.config.fontSize, () => {
reconfigureFontSettings();
editorStore.applyFontSize();
});
// 监听字体族变化
watch(() => configStore.config.fontFamily, reconfigureFontSettings);
// 监听字体粗细变化
watch(() => configStore.config.fontWeight, reconfigureFontSettings);
// 监听行高变化
watch(() => configStore.config.lineHeight, reconfigureFontSettings);
onMounted(() => {
// 创建编辑器
createEditor();
// 添加滚轮事件监听
if (editorElement.value) {
editorElement.value.addEventListener('wheel', handleWheel, {passive: false});
}
// 确保统计信息已更新
if (editorStore.editorView) {
setTimeout(() => {
updateStats(editorStore.editorView as EditorView, editorStore.updateDocumentStats);
}, 100);
}
});
onBeforeUnmount(() => {
isDestroying = true;
// 移除滚轮事件监听
if (editorElement.value) {
editorElement.value.removeEventListener('wheel', handleWheel);
}
// 直接销毁编辑器
if (editorStore.editorView) {
editorStore.editorView.destroy();
editorStore.setEditorView(null);
}
});
</script>
<template>
<div class="editor-container">
<div ref="editorElement" class="editor"></div>
<Toolbar />
</div>
</template>
<style scoped lang="scss">
.editor-container {
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
.editor {
width: 100%;
flex: 1;
overflow: hidden;
}
}
:deep(.cm-editor) {
height: 100%;
width: 100%;
}
:deep(.cm-scroller) {
overflow: auto;
}
</style>

View File

@@ -0,0 +1,99 @@
import { EditorView, ViewPlugin, ViewUpdate } from '@codemirror/view';
import { DocumentService } from '../../../../bindings/voidraft/internal/services';
import { useDebounceFn } from '@vueuse/core';
// 定义自动保存配置选项
export interface AutoSaveOptions {
// 保存回调
onSave?: (success: boolean) => void;
// 内容变更延迟传递(毫秒)- 输入时不会立即发送,有一个小延迟,避免频繁调用后端
debounceDelay?: number;
}
/**
* 创建自动保存插件
* @param options 配置选项
* @returns EditorView.Plugin
*/
export function createAutoSavePlugin(options: AutoSaveOptions = {}) {
const {
onSave = () => {},
debounceDelay = 1000 // 默认1000ms延迟原为300ms
} = options;
return ViewPlugin.fromClass(
class {
private isActive: boolean = true;
private isSaving: boolean = false;
private readonly contentUpdateFn: (view: EditorView) => void;
constructor(private view: EditorView) {
// 创建内容更新函数,简单传递内容给后端
this.contentUpdateFn = this.createDebouncedUpdateFn(debounceDelay);
}
/**
* 创建防抖的内容更新函数
*/
private createDebouncedUpdateFn(delay: number): (view: EditorView) => void {
// 使用VueUse的防抖函数创建一个新函数
return useDebounceFn(async (view: EditorView) => {
// 如果插件已不活跃或正在保存中,不发送
if (!this.isActive || this.isSaving) return;
this.isSaving = true;
const content = view.state.doc.toString();
try {
// 简单将内容传递给后端,让后端处理保存策略
await DocumentService.UpdateActiveDocumentContent(content);
onSave(true);
} catch (err) {
console.error('Failed to update document content:', err);
onSave(false);
} finally {
this.isSaving = false;
}
}, delay);
}
update(update: ViewUpdate) {
// 如果内容没有变化,直接返回
if (!update.docChanged) return;
// 调用防抖函数
this.contentUpdateFn(this.view);
}
destroy() {
// 标记插件不再活跃
this.isActive = false;
// 直接发送最终内容
const content = this.view.state.doc.toString();
DocumentService.UpdateActiveDocumentContent(content)
.then(() => console.log('Successfully sent final content on destroy'))
.catch(err => console.error('Failed to send content on destroy:', err));
}
}
);
}
/**
* 创建处理保存快捷键的插件
* @param onSave 保存回调
* @returns EditorView.Plugin
*/
export function createSaveShortcutPlugin(onSave: () => void) {
return EditorView.domEventHandlers({
keydown: (event) => {
// Ctrl+S / Cmd+S
if ((event.ctrlKey || event.metaKey) && event.key === 's') {
event.preventDefault();
onSave();
return true;
}
return false;
}
});
}

View File

@@ -0,0 +1,75 @@
import {Extension} from '@codemirror/state';
import {
crosshairCursor,
drawSelection,
dropCursor,
EditorView,
highlightActiveLine,
highlightActiveLineGutter,
highlightSpecialChars,
keymap,
lineNumbers,
rectangularSelection,
} from '@codemirror/view';
import {
bracketMatching,
defaultHighlightStyle,
foldGutter,
foldKeymap,
indentOnInput,
syntaxHighlighting,
} from '@codemirror/language';
import {defaultKeymap, history, historyKeymap,} from '@codemirror/commands';
import {highlightSelectionMatches, searchKeymap} from '@codemirror/search';
import {autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap} from '@codemirror/autocomplete';
import {lintKeymap} from '@codemirror/lint';
import {customHighlightActiveLine, defaultDark} from '@/views/editor/theme/default-dark';
// 基本编辑器设置,包含常用扩展
export const createBasicSetup = (): Extension[] => {
return [
// 主题相关
defaultDark,
// 基础UI
lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(),
dropCursor(),
EditorView.lineWrapping,
// 历史记录
history(),
// 代码折叠
foldGutter(),
// 选择与高亮
drawSelection(),
customHighlightActiveLine,
highlightActiveLine(),
highlightSelectionMatches(),
rectangularSelection(),
crosshairCursor(),
// 缩进和编辑辅助
indentOnInput(),
syntaxHighlighting(defaultHighlightStyle, {fallback: true}),
bracketMatching(),
closeBrackets(),
// 自动完成
autocompletion(),
// 键盘映射
keymap.of([
...closeBracketsKeymap,
...defaultKeymap,
...searchKeymap,
...historyKeymap,
...foldKeymap,
...completionKeymap,
...lintKeymap
]),
];
};

View File

@@ -0,0 +1,111 @@
import { EditorView } from '@codemirror/view';
import { Extension, Compartment } from '@codemirror/state';
// 字体配置接口
export interface FontConfig {
fontFamily: string;
fontSize?: number;
lineHeight?: number;
fontWeight?: string;
}
// 创建字体配置compartment
export const fontCompartment = new Compartment();
// 默认字体配置
export const DEFAULT_FONT_CONFIG: FontConfig = {
fontFamily: '"HarmonyOS Sans SC", "HarmonyOS Sans", "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif',
fontSize: 14,
lineHeight: 1.5,
fontWeight: 'normal'
};
// 从后端配置创建字体配置
export function createFontConfigFromBackend(backendConfig: {
fontFamily?: string;
fontSize?: number;
lineHeight?: number;
fontWeight?: string;
}): FontConfig {
return {
fontFamily: backendConfig.fontFamily || DEFAULT_FONT_CONFIG.fontFamily,
fontSize: backendConfig.fontSize || DEFAULT_FONT_CONFIG.fontSize,
lineHeight: backendConfig.lineHeight || DEFAULT_FONT_CONFIG.lineHeight,
fontWeight: backendConfig.fontWeight || DEFAULT_FONT_CONFIG.fontWeight,
};
}
// 创建字体样式扩展
export function createFontExtension(config: Partial<FontConfig> = {}): Extension {
const fontConfig = { ...DEFAULT_FONT_CONFIG, ...config };
const styles: Record<string, any> = {
'&': {
fontFamily: fontConfig.fontFamily,
...(fontConfig.fontSize && { fontSize: `${fontConfig.fontSize}px` }),
...(fontConfig.lineHeight && { lineHeight: fontConfig.lineHeight.toString() }),
...(fontConfig.fontWeight && { fontWeight: fontConfig.fontWeight }),
},
'.cm-content': {
fontFamily: fontConfig.fontFamily,
...(fontConfig.fontSize && { fontSize: `${fontConfig.fontSize}px` }),
...(fontConfig.lineHeight && { lineHeight: fontConfig.lineHeight.toString() }),
...(fontConfig.fontWeight && { fontWeight: fontConfig.fontWeight }),
},
'.cm-editor': {
fontFamily: fontConfig.fontFamily,
},
'.cm-scroller': {
fontFamily: fontConfig.fontFamily,
},
'.cm-gutters': {
fontFamily: fontConfig.fontFamily,
...(fontConfig.fontSize && { fontSize: `${fontConfig.fontSize}px` }),
},
'.cm-lineNumbers': {
fontFamily: fontConfig.fontFamily,
...(fontConfig.fontSize && { fontSize: `${Math.max(10, fontConfig.fontSize - 1)}px` }),
},
'.cm-tooltip': {
fontFamily: fontConfig.fontFamily,
...(fontConfig.fontSize && { fontSize: `${Math.max(12, fontConfig.fontSize - 1)}px` }),
},
'.cm-completionLabel': {
fontFamily: fontConfig.fontFamily,
},
'.cm-completionDetail': {
fontFamily: fontConfig.fontFamily,
}
};
return EditorView.theme(styles);
}
// 创建响应式字体大小扩展
export function createResponsiveFontExtension(baseFontSize: number = 14): Extension {
return fontCompartment.of(createFontExtension({
fontSize: baseFontSize,
lineHeight: 1.5
}));
}
// 从后端配置创建字体扩展
export function createFontExtensionFromBackend(backendConfig: {
fontFamily?: string;
fontSize?: number;
lineHeight?: number;
fontWeight?: string;
}): Extension {
const fontConfig = createFontConfigFromBackend(backendConfig);
return fontCompartment.of(createFontExtension(fontConfig));
}
// 动态更新字体配置
export function updateFontConfig(view: EditorView, config: Partial<FontConfig>): void {
const newFontExtension = createFontExtension(config);
// 使用compartment重新配置字体扩展
view.dispatch({
effects: fontCompartment.reconfigure(newFontExtension)
});
}

View File

@@ -0,0 +1,6 @@
// 统一导出所有扩展
export * from './tabExtension';
export * from './wheelZoomExtension';
export * from './statsExtension';
export * from './autoSaveExtension';
export * from './fontExtension';

View File

@@ -0,0 +1,42 @@
import {Extension} from '@codemirror/state';
import {EditorView} from '@codemirror/view';
import {DocumentStats} from '@/types/editor';
// 更新编辑器文档统计信息
export const updateStats = (
view: EditorView,
updateDocumentStats: (stats: DocumentStats) => void
) => {
if (!view) return;
const state = view.state;
const doc = state.doc;
const text = doc.toString();
// 计算选中的字符数
let selectedChars = 0;
const selections = state.selection;
if (selections) {
for (let i = 0; i < selections.ranges.length; i++) {
const range = selections.ranges[i];
selectedChars += range.to - range.from;
}
}
updateDocumentStats({
lines: doc.lines,
characters: text.length,
selectedCharacters: selectedChars
});
};
// 创建统计信息更新监听器扩展
export const createStatsUpdateExtension = (
updateDocumentStats: (stats: DocumentStats) => void
): Extension => {
return EditorView.updateListener.of(update => {
if (update.docChanged || update.selectionSet) {
updateStats(update.view, updateDocumentStats);
}
});
};

View File

@@ -0,0 +1,78 @@
import {Compartment, Extension} from '@codemirror/state';
import {EditorView, keymap} from '@codemirror/view';
import {indentSelection} from '@codemirror/commands';
import {indentUnit} from '@codemirror/language';
import {TabType} from '../../../../bindings/voidraft/internal/models/models';
// Tab设置相关的compartment
export const tabSizeCompartment = new Compartment();
export const tabKeyCompartment = new Compartment();
// 自定义Tab键处理函数
export const tabHandler = (view: EditorView, tabSize: number, tabType: TabType): boolean => {
// 如果有选中文本使用indentSelection
if (!view.state.selection.main.empty) {
return indentSelection(view);
}
// 根据tabType创建缩进字符
const indent = tabType === 'spaces' ? ' '.repeat(tabSize) : '\t';
// 在光标位置插入缩进字符
const {state, dispatch} = view;
dispatch(state.update(state.replaceSelection(indent), {scrollIntoView: true}));
return true;
};
// 获取Tab相关的扩展
export const getTabExtensions = (tabSize: number, enableTabIndent: boolean, tabType: TabType): Extension[] => {
const extensions: Extension[] = [];
// 根据tabType设置缩进单位
const indentStr = tabType === 'spaces' ? ' '.repeat(tabSize) : '\t';
extensions.push(tabSizeCompartment.of(indentUnit.of(indentStr)));
// 如果启用了Tab缩进添加自定义Tab键映射
if (enableTabIndent) {
extensions.push(
tabKeyCompartment.of(
keymap.of([{
key: "Tab",
run: (view) => tabHandler(view, tabSize, tabType)
}])
)
);
} else {
extensions.push(tabKeyCompartment.of([]));
}
return extensions;
};
// 更新Tab配置
export const updateTabConfig = (
view: EditorView | null,
tabSize: number,
enableTabIndent: boolean,
tabType: TabType
) => {
if (!view) return;
// 根据tabType更新indentUnit配置
const indentStr = tabType === 'spaces' ? ' '.repeat(tabSize) : '\t';
view.dispatch({
effects: tabSizeCompartment.reconfigure(indentUnit.of(indentStr))
});
// 更新Tab键映射
const tabKeymap = enableTabIndent
? keymap.of([{
key: "Tab",
run: (view) => tabHandler(view, tabSize, tabType)
}])
: [];
view.dispatch({
effects: tabKeyCompartment.reconfigure(tabKeymap)
});
};

View File

@@ -0,0 +1,22 @@
// 处理滚轮缩放字体的事件处理函数
export const createWheelZoomHandler = (
increaseFontSize: () => void,
decreaseFontSize: () => void
) => {
return (event: WheelEvent) => {
// 检查是否按住了Ctrl键
if (event.ctrlKey) {
// 阻止默认行为(防止页面缩放)
event.preventDefault();
// 根据滚轮方向增大或减小字体
if (event.deltaY < 0) {
// 向上滚动,增大字体
increaseFontSize();
} else {
// 向下滚动,减小字体
decreaseFontSize();
}
}
};
};

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'aura',
dark: true,
background: '#21202e',
foreground: '#edecee',
selection: '#A198EC7F',
cursor: '#a277ff',
dropdownBackground: '#21202e',
dropdownBorder: '#3b334b',
activeLine: '#4d4b6622',
lineNumber: '#a394f033',
lineNumberActive: '#cdccce',
matchingBracket: '#a394f033',
keyword: '#a277ff',
storage: '#a277ff',
variable: '#edecee',
parameter: '#edecee',
function: '#ffca85',
string: '#61ffca',
constant: '#61ffca',
type: '#82e2ff',
class: '#82e2ff',
number: '#61ffca',
comment: '#6d6d6d',
heading: '#a277ff',
invalid: '#ff6767',
regexp: '#61ffca',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,143 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'base-dark',
dark: true,
background: '#252B37',
foreground: '#9BB586',
selection: '#3381c1',
selectionMatch: '#1A58887F',
cursor: '#F8F8F2',
dropdownBackground: '#282A36',
dropdownBorder: '#191A21',
activeLine: '#2E333F99',
lineNumber: '#676d7c',
lineNumberActive: '#F8F8F2',
lineNumberBackground: '#212731',
matchingBracket: '#44475A',
keyword: '#FF79C6',
storage: '#FF79C6',
variable: '#F8F8F2',
parameter: '#F8F8F2',
function: '#50FA7B',
string: '#F1FA8C',
constant: '#BD93F9',
type: '#8BE9FD',
class: '#8BE9FD',
number: '#BD93F9',
comment: '#6272A4',
heading: '#BD93F9',
invalid: '#FF5555',
regexp: '#F1FA8C',
}
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-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {
backgroundColor: `${config.selection} !important`
},
'.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.selectionMatch} !important`,
borderRadius: '2px'
},
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
backgroundColor: config.matchingBracket,
outline: 'none'
},
'.cm-gutters': {
backgroundColor: config.lineNumberBackground,
color: config.foreground,
border: 'none'
},
'.cm-activeLineGutter': {backgroundColor: config.background},
'.cm-lineNumbers .cm-gutterElement': {color: config.lineNumber},
'.cm-lineNumbers .cm-activeLineGutter': {color: config.lineNumberActive},
'.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 customHighlightActiveLine = EditorView.theme({
'.cm-activeLine': {
backgroundColor: config.activeLine,
}
})
export const defaultDark: Extension = [
draculaTheme,
syntaxHighlighting(draculaHighlightStyle),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'dracula',
dark: true,
background: '#282A36',
foreground: '#F8F8F2',
selection: '#44475A',
cursor: '#F8F8F2',
dropdownBackground: '#282A36',
dropdownBorder: '#191A21',
activeLine: '#53576c22',
lineNumber: '#6272A4',
lineNumberActive: '#F8F8F2',
matchingBracket: '#44475A',
keyword: '#FF79C6',
storage: '#FF79C6',
variable: '#F8F8F2',
parameter: '#F8F8F2',
function: '#50FA7B',
string: '#F1FA8C',
constant: '#BD93F9',
type: '#8BE9FD',
class: '#8BE9FD',
number: '#BD93F9',
comment: '#6272A4',
heading: '#BD93F9',
invalid: '#FF5555',
regexp: '#F1FA8C',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'githubDark',
dark: true,
background: '#24292e',
foreground: '#d1d5da',
selection: '#3392FF44',
cursor: '#c8e1ff',
dropdownBackground: '#24292e',
dropdownBorder: '#1b1f23',
activeLine: '#4d566022',
lineNumber: '#444d56',
lineNumberActive: '#e1e4e8',
matchingBracket: '#17E5E650',
keyword: '#f97583',
storage: '#f97583',
variable: '#ffab70',
parameter: '#e1e4e8',
function: '#79b8ff',
string: '#9ecbff',
constant: '#79b8ff',
type: '#79b8ff',
class: '#b392f0',
number: '#79b8ff',
comment: '#6a737d',
heading: '#79b8ff',
invalid: '#f97583',
regexp: '#9ecbff',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'githubLight',
dark: false,
background: '#fff',
foreground: '#444d56',
selection: '#0366d625',
cursor: '#044289',
dropdownBackground: '#fff',
dropdownBorder: '#e1e4e8',
activeLine: '#c6c6c622',
lineNumber: '#1b1f234d',
lineNumberActive: '#24292e',
matchingBracket: '#34d05840',
keyword: '#d73a49',
storage: '#d73a49',
variable: '#e36209',
parameter: '#24292e',
function: '#005cc5',
string: '#032f62',
constant: '#005cc5',
type: '#005cc5',
class: '#6f42c1',
number: '#005cc5',
comment: '#6a737d',
heading: '#005cc5',
invalid: '#cb2431',
regexp: '#032f62',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'materialDark',
dark: true,
background: '#263238',
foreground: '#EEFFFF',
selection: '#80CBC420',
cursor: '#FFCC00',
dropdownBackground: '#263238',
dropdownBorder: '#FFFFFF10',
activeLine: '#4c616c22',
lineNumber: '#37474F',
lineNumberActive: '#607a86',
matchingBracket: '#263238',
keyword: '#C792EA',
storage: '#C792EA',
variable: '#EEFFFF',
parameter: '#EEFFFF',
function: '#82AAFF',
string: '#C3E88D',
constant: '#F78C6C',
type: '#B2CCD6',
class: '#FFCB6B',
number: '#F78C6C',
comment: '#546E7A',
heading: '#C3E88D',
invalid: '#FF5370',
regexp: '#89DDFF',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'materialLight',
dark: false,
background: '#FAFAFA',
foreground: '#90A4AE',
selection: '#80CBC440',
cursor: '#272727',
dropdownBackground: '#FAFAFA',
dropdownBorder: '#00000010',
activeLine: '#c2c2c222',
lineNumber: '#CFD8DC',
lineNumberActive: '#7E939E',
matchingBracket: '#FAFAFA',
keyword: '#7C4DFF',
storage: '#7C4DFF',
variable: '#90A4AE',
parameter: '#90A4AE',
function: '#6182B8',
string: '#91B859',
constant: '#F76D47',
type: '#8796B0',
class: '#FFB62C',
number: '#F76D47',
comment: '#90A4AE',
heading: '#91B859',
invalid: '#E53935',
regexp: '#39ADB5',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'solarizedDark',
dark: true,
background: '#002B36',
foreground: '#93A1A1',
selection: '#274642',
cursor: '#D30102',
dropdownBackground: '#002B36',
dropdownBorder: '#2AA19899',
activeLine: '#005b7022',
lineNumber: '#93A1A1',
lineNumberActive: '#949494',
matchingBracket: '#073642',
keyword: '#859900',
storage: '#93A1A1',
variable: '#268BD2',
parameter: '#268BD2',
function: '#268BD2',
string: '#2AA198',
constant: '#CB4B16',
type: '#CB4B16',
class: '#CB4B16',
number: '#D33682',
comment: '#586E75',
heading: '#268BD2',
invalid: '#DC322F',
regexp: '#DC322F',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'solarizedLight',
dark: false,
background: '#FDF6E3',
foreground: '#586E75',
selection: '#EEE8D5',
cursor: '#657B83',
dropdownBackground: '#FDF6E3',
dropdownBorder: '#D3AF86',
activeLine: '#d5bd5c22',
lineNumber: '#586E75',
lineNumberActive: '#567983',
matchingBracket: '#EEE8D5',
keyword: '#859900',
storage: '#586E75',
variable: '#268BD2',
parameter: '#268BD2',
function: '#268BD2',
string: '#2AA198',
constant: '#CB4B16',
type: '#CB4B16',
class: '#CB4B16',
number: '#D33682',
comment: '#93A1A1',
heading: '#268BD2',
invalid: '#DC322F',
regexp: '#DC322F',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'tokyoNightDay',
dark: false,
background: '#e1e2e7',
foreground: '#6a6f8e',
selection: '#8591b840',
cursor: '#3760bf',
dropdownBackground: '#e1e2e7',
dropdownBorder: '#6a6f8e',
activeLine: '#a7aaba22',
lineNumber: '#b3b6cd',
lineNumberActive: '#68709a',
matchingBracket: '#e9e9ec',
keyword: '#9854f1',
storage: '#9854f1',
variable: '#3760bf',
parameter: '#3760bf',
function: '#2e7de9',
string: '#587539',
constant: '#9854f1',
type: '#07879d',
class: '#3760bf',
number: '#b15c00',
comment: '#9da3c2',
heading: '#006a83',
invalid: '#ff3e64',
regexp: '#2e5857',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'tokyoNightStorm',
dark: true,
background: '#24283b',
foreground: '#7982a9',
selection: '#6f7bb630',
cursor: '#c0caf5',
dropdownBackground: '#24283b',
dropdownBorder: '#7982a9',
activeLine: '#4d547722',
lineNumber: '#3b4261',
lineNumberActive: '#737aa2',
matchingBracket: '#1f2335',
keyword: '#bb9af7',
storage: '#bb9af7',
variable: '#c0caf5',
parameter: '#c0caf5',
function: '#7aa2f7',
string: '#9ece6a',
constant: '#bb9af7',
type: '#2ac3de',
class: '#c0caf5',
number: '#ff9e64',
comment: '#565f89',
heading: '#89ddff',
invalid: '#ff5370',
regexp: '#b4f9f8',
}
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.lineNumberActive},
'.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),
]

View File

@@ -0,0 +1,128 @@
import {EditorView} from '@codemirror/view'
import {Extension} from '@codemirror/state'
import {HighlightStyle, syntaxHighlighting} from '@codemirror/language'
import {tags as t} from '@lezer/highlight'
export const config = {
name: 'tokyoNight',
dark: true,
background: '#1a1b26',
foreground: '#787c99',
selection: '#515c7e40',
cursor: '#c0caf5',
dropdownBackground: '#1a1b26',
dropdownBorder: '#787c99',
activeLine: '#43455c22',
lineNumber: '#363b54',
lineNumberActive: '#737aa2',
matchingBracket: '#16161e',
keyword: '#bb9af7',
storage: '#bb9af7',
variable: '#c0caf5',
parameter: '#c0caf5',
function: '#7aa2f7',
string: '#9ece6a',
constant: '#bb9af7',
type: '#0db9d7',
class: '#c0caf5',
number: '#ff9e64',
comment: '#444b6a',
heading: '#89ddff',
invalid: '#ff5370',
regexp: '#b4f9f8',
}
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.lineNumberActive},
'.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),
]