完整代码块工具栏
示例给代码围栏增加语言选择器。修改语言仅改变 header 的语言字段;代码正文、围栏字符和其他内容保留。切换只读后语言选择器禁用,撤销恢复原语言。
先选择定制层
| 需求 | 入口 |
|---|---|
| 改代码字体、背景、间距 | EditorView.theme() 和语法高亮 |
| 增加语言、复制、菜单控件 | CodeBlock.extend({ addNodeView() {} }) |
| 支持 TypeScript、JSON 等语法着色 | 创建选项 codeLanguages |
| Mermaid、ECharts 或 flow DSL 图形输出 | 独立语义扩展 + 块级投影,见 图表预览 |
CodeBlock 的 NodeView 位于围栏前方,属于 placement: 'before'。它不是整个代码正文的替换入口,也没有 contentDOM 供你接管输入。
覆盖预设中的一个功能
import { StarterKit } from '@quirekit/msfe-starter-kit'
import { CodeBlock } from '@quirekit/msfe-code-block'
import { VueNodeViewRenderer } from '@quirekit/msfe-vue'
import Toolbar from './toolbar.vue'
const CustomCodeBlock = CodeBlock.extend({
addNodeView() { return VueNodeViewRenderer(Toolbar) },
})
const extensions = [StarterKit.configure({ codeBlock: CustomCodeBlock })]
不要同时安装 StarterKit 和同名 CustomCodeBlock。如果使用更小的按需预设,也可以禁用预设中的 codeBlock 后单独安装一个实现。
控件可读写什么
组件接收 nodeView: MsfeNodeViewProps<CodeBlockAttributes>。目前持久属性只有 language,可调用 nodeView.updateAttributes({ language: 'json' })。合法语言 token 长度不超过 40,允许字母、数字、下划线及 + # . -,不允许换行和任意 header 注入。
也可在当前代码块选区使用 editor.commands.setCodeLanguage('typescript')。它依赖已确认的围栏语法和适用选区;返回 false 时检查结果。语言高亮目录和语言字段校验分别负责不同的事,某个字段合法不代表安装了对应高亮器。
复制源码属于读取动作:由宿主读取当前已确认的 CodeText 范围,保持换行和缩进。NodeView 的 getRange() 只提供范围,不承诺给你一份可直接当作代码正文的字符串。跨弹窗动作使用 锚点。
按需加载语言
示例 code-block/languages.ts 提供 TypeScript、JavaScript 和 JSON,相关依赖为 @quirekit/cm-lang-javascript 与 @quirekit/cm-lang-json。创建编辑器时传 codeLanguages。
name 与 aliases 精确匹配且大小写不敏感。load(signal) 返回 LanguageSupport;未知语言保持纯文本,不推测文件名或动态下载任意包。动态导入不能真正中断,宿主资源需要观察信号,过期结果不能覆盖新的编辑器状态。
没有正文行的空围栏
CodeBlock 默认给相邻的开闭围栏提供「输入代码」占位行。点击或用 Enter / Space 激活后,
通过普通编辑命令插入一行,保留引用和列表缩进,并把光标放入代码正文。显示占位、滚动和
切换模式不改变 Markdown;已有真实空行不重复占位。只读不能激活,插入支持撤销和重做。
使用 CodeBlock.configure({ emptyLine: false }) 可关闭;emptyLineLabel 设置可访问的提示文字。
MD Editor 通过 features.codeBlock: ProseCodeBlock.configure({ emptyLine: false }) 配置,默认按界面语言显示提示。
源码模式始终展示真实围栏和换行,不显示占位。
MD Editor 默认提供 mdCodeLanguages:TypeScript、JavaScript / JSX、TSX、JSON、CSS、HTML、
Python、Bash 和 Markdown,按需加载;传 codeLanguages 会替换整份目录,传 [] 禁用默认目录。
自定义主题和语法包必须共享同一版本的 @lezer/highlight,否则标记身份不一致会导致已解析却无颜色。
样式和源码活动状态
可从 .msfe-code-line、.msfe-code-start、.msfe-code-body-start、.msfe-code-end、.msfe-code-indented 等语义类设置外观,并由 HighlightStyle 定义代码 token。语言 token 隐藏与编辑器行布局应由运行时处理;不要隐藏所有 .cm-line 或把代码正文移到另一个 contenteditable。
进入围栏源码范围时,活动源码会显露。中文组合输入、跨块拖选、复制和撤销都应继续走原生编辑链路。高度变化使用组件测量入口,详见 投影层。
验证范围
至少测试:切换语言、撤销、空/未知语言、长代码、未闭合围栏、反引号和波浪线围栏、只读、Tab 缩进,以及主题切换后代码仍可编辑。完整选项和组件协议见 渲染 API。