Files
OJ2/apps/web/src/shared/themes/codeTheme.ts
T
xuyueandClaude Opus 5.5 a085351a2f
Deploy / deploy (push) Canceled after 0s
style(代码配色): True / False / None 和 NULL 改成关键字蓝;SQL 的 COUNT、AVG、ROUND 这些函数是函数色;编辑器的选区、行号、当前行、括号配对也换成 VS Code 的样子
True / None 原来和数字一个绿色,VS Code 里是 constant.language,和关键字同色。
SQL 的解析器把 COUNT 当关键字、把 avg 当普通名字,现在后面跟着括号的常用函数一律是函数色。

编辑器的框原来沿用 smoothy / One Dark(亮色选区是淡黄),现在照 VS Code 的默认值:选区淡蓝 /
深蓝、行号青色、当前行是一圈边框。当前行只在有焦点时画,免得自学一课十几个代码块每块第一行都框着。
暗色的底色仍用网站的。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:35:34 +08:00

120 lines
4.4 KiB
TypeScript

import { syntaxHighlighting } from "@codemirror/language"
import type { Extension } from "@codemirror/state"
import { EditorView } from "@codemirror/view"
import { codeHighlighter } from "../highlight"
/**
* 编辑器的外观:亮 / 暗两套只管底色、光标、选区、行号这些「框」,
* 代码的颜色两套都是 codeHighlighter 打的 tok-* 类名,跟着 html.dark 在 highlight.css 里切。
* 框的颜色照 VS Code 的默认值(src/vs/editor/common/core/editorColorRegistry.ts 等),
* 只有暗色的底色用网站自己的,不用 VS Code 的 #1E1E1E。
*
* 当前行照 VS Code 是一圈边框不是底色,并且只在编辑器有焦点时画:
* 自学一课里有十几个代码块,不然每块第一行都框着。
*/
const highlighting = syntaxHighlighting(codeHighlighter)
// CodeMirror 自带的选区规则带着 > .cm-scroller > .cm-selectionLayer,选择器短了压不过它
const focusedSelection = "&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground"
const light = EditorView.theme({
"&": {
backgroundColor: "#ffffff",
color: "var(--code-fg)",
},
".cm-content": { caretColor: "#000000" },
".cm-cursor, .cm-dropCursor": { borderLeftColor: "#000000" },
".cm-selectionBackground, .cm-content ::selection": { backgroundColor: "#ADD6FF80" },
[focusedSelection]: { backgroundColor: "#ADD6FF" },
".cm-selectionMatch": { backgroundColor: "#ADD6FF80" },
"&.cm-focused .cm-matchingBracket": {
backgroundColor: "#0064001a",
outline: "1px solid #B9B9B9",
},
".cm-searchMatch": { backgroundColor: "#EA5C0055" },
".cm-searchMatch.cm-searchMatch-selected": { backgroundColor: "#A8AC94" },
".cm-activeLine": { backgroundColor: "transparent" },
"&.cm-focused .cm-activeLine": { boxShadow: "inset 0 0 0 2px #eeeeee" },
".cm-gutters": {
backgroundColor: "#ffffff",
borderRight: "none",
color: "#237893",
},
".cm-activeLineGutter": { backgroundColor: "transparent" },
"&.cm-focused .cm-activeLineGutter": { color: "#0B216F" },
".cm-tooltip": {
border: "1px solid #e0e0e0",
backgroundColor: "#f8f8f8",
},
".cm-tooltip-autocomplete": {
"& > ul > li[aria-selected]": {
backgroundColor: "#e8e8e8",
color: "#000000",
},
},
})
const darkBackground = "#26262a",
background = "#101014", // naive-ui
tooltipBackground = "#353a42",
highlightBackground = "#2c313a"
const dark = EditorView.theme(
{
"&": {
color: "var(--code-fg)",
backgroundColor: background,
},
".cm-content": { caretColor: "#AEAFAD" },
".cm-cursor, .cm-dropCursor": { borderLeftColor: "#AEAFAD" },
".cm-selectionBackground, .cm-content ::selection": { backgroundColor: "#264F7880" },
[focusedSelection]: { backgroundColor: "#264F78" },
".cm-selectionMatch": { backgroundColor: "#ADD6FF26" },
"&.cm-focused .cm-matchingBracket": {
backgroundColor: "#0064001a",
outline: "1px solid #888888",
},
".cm-searchMatch": { backgroundColor: "#EA5C0055" },
".cm-searchMatch.cm-searchMatch-selected": { backgroundColor: "#515C6A" },
".cm-panels": { backgroundColor: darkBackground, color: "var(--code-fg)" },
".cm-panels.cm-panels-top": { borderBottom: "2px solid black" },
".cm-panels.cm-panels-bottom": { borderTop: "2px solid black" },
".cm-activeLine": { backgroundColor: "transparent" },
"&.cm-focused .cm-activeLine": { boxShadow: "inset 0 0 0 2px #282828" },
".cm-gutters": {
backgroundColor: background,
color: "#858585",
border: "none",
},
".cm-activeLineGutter": { backgroundColor: "transparent" },
"&.cm-focused .cm-activeLineGutter": { color: "#C6C6C6" },
".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: "var(--code-fg)",
},
},
},
{ dark: true },
)
export const lightCodeTheme: Extension = [light, highlighting]
export const darkCodeTheme: Extension = [dark, highlighting]