fix(editor): 修复 CodeMirror 折叠图标垂直不居中

折叠三角 (▾/▸) 在每行行框里偏低,根因有二:

1. 图标字符本身基线不稳。codemirror 包的 basicSetup 调 foldGutter() 用默认
   openText "⌄" (U+2304「下花括号」),这是个基线/字形表现不稳定的符号字符,
   在多数 mono 字体里墨迹落在字符框底部,三角明显偏低。本地内联一份 basicSetup
   (CodeMirror 官方推荐的定制方式),改用几何形状块字符 ▾ (U+25BE) /
   ▸ (U+25B8),字形本身在字符框内居中;同时把 foldGutter() 展开后丢弃的
   @codemirror/{lint,search} 显式声明为依赖。

2. core 没给图标 <span> 设 vertical-align/display。baseTheme 只给
   .cm-foldGutter span 设了 padding/cursor,图标默认按基线贴在格子底部。
   themes.ts 加一条 flex 居中规则,把 .cm-foldGutter .cm-gutterElement 变成
   flex 容器,三角稳稳落在行框中央。

文章页 CodeRunner 与后台 SQL 控制台共用同一份 editor.js,一处修复两处生效。
This commit is contained in:
xfy 2026-07-08 13:04:30 +08:00
parent 7d0922c0f9
commit 533f12e851
4 changed files with 107 additions and 3 deletions

View File

@ -18,6 +18,8 @@
"@codemirror/lang-python": "^6.2.0",
"@codemirror/lang-sql": "^6.10.0",
"@codemirror/language": "^6.11.0",
"@codemirror/lint": "^6.9.7",
"@codemirror/search": "^6.7.1",
"@codemirror/state": "^6.5.0",
"@codemirror/view": "^6.36.0",
"@replit/codemirror-vim": "^6.3.0",

View File

@ -1,12 +1,87 @@
import {
autocompletion,
closeBrackets,
closeBracketsKeymap,
completionKeymap,
} from '@codemirror/autocomplete';
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
import { javascript } from '@codemirror/lang-javascript';
import { python } from '@codemirror/lang-python';
import { PostgreSQL, sql } from '@codemirror/lang-sql';
import {
bracketMatching,
codeFolding,
defaultHighlightStyle,
foldGutter,
foldKeymap,
indentOnInput,
syntaxHighlighting,
} from '@codemirror/language';
import { lintKeymap } from '@codemirror/lint';
import { highlightSelectionMatches, searchKeymap } from '@codemirror/search';
import { Compartment, EditorState, type Extension, Prec } from '@codemirror/state';
import { EditorView, keymap } from '@codemirror/view';
import {
crosshairCursor,
drawSelection,
dropCursor,
EditorView,
highlightActiveLine,
highlightActiveLineGutter,
highlightSpecialChars,
keymap,
lineNumbers,
rectangularSelection,
} from '@codemirror/view';
import { vim } from '@replit/codemirror-vim';
import { basicSetup } from 'codemirror';
import { type ThemeName, themeExtension } from './themes';
/**
* basicSetup `codemirror` 便
*
*
* `codemirror` basicSetup `foldGutter()` `openText: "⌄"`
* (U+2304 DOWNWARDS HARPOON WITH BARB )线/
* mono
* `` (U+25BE BLACK DOWN-POINTING SMALL TRIANGLE) / ``
* (U+25B8 BLACK RIGHT-POINTING SMALL TRIANGLE)
* themes.ts flex
*
* CodeMirror basicSetup does not allow customization
* copy this package's source ... and adjust as desired
*/
const basicSetup: Extension[] = [
lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(),
history(),
foldGutter({
openText: '▾',
closedText: '▸',
}),
drawSelection(),
dropCursor(),
EditorState.allowMultipleSelections.of(true),
indentOnInput(),
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
bracketMatching(),
closeBrackets(),
autocompletion(),
rectangularSelection(),
crosshairCursor(),
highlightActiveLine(),
highlightSelectionMatches(),
keymap.of([
...closeBracketsKeymap,
...defaultKeymap,
...searchKeymap,
...historyKeymap,
...foldKeymap,
...completionKeymap,
...lintKeymap,
]),
codeFolding(),
];
/** SQL 补全用 schema 数据(由 Rust 侧从实时库拉取注入)。 */
export interface SqlSchema {
tables: { name: string; columns: string[] }[];

View File

@ -28,8 +28,29 @@ const gutterBackgroundOverride: Extension = EditorView.theme({
},
});
/**
* CodeMirror fold gutter /
*
* core baseTheme@codemirror/language `.cm-foldGutter span`
* `padding`/`cursor` `display`/`vertical-align` <span>
* `.cm-gutterElement` core 线
*
*
* editor.ts 线 ``(U+2304)/``(U+203A)
* ``(U+25BE)/``(U+25B8) flex
* `.cm-foldGutter`
* 线
*/
const foldGutterCenterOverride: Extension = EditorView.theme({
'.cm-foldGutter .cm-gutterElement': {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
});
/** 根据主题名返回对应的 CodeMirror 主题 Extension。 */
export function themeExtension(name: ThemeName): Extension {
const catppuccin = name === 'light' ? catppuccinLatte : catppuccinMocha;
return [catppuccin, gutterBackgroundOverride];
return [catppuccin, gutterBackgroundOverride, foldGutterCenterOverride];
}

6
libs/pnpm-lock.yaml generated
View File

@ -47,6 +47,12 @@ importers:
'@codemirror/language':
specifier: ^6.11.0
version: 6.12.4
'@codemirror/lint':
specifier: ^6.9.7
version: 6.9.7
'@codemirror/search':
specifier: ^6.7.1
version: 6.7.1
'@codemirror/state':
specifier: ^6.5.0
version: 6.7.0