Milkdown嵌套列表缩进调整:3步搞定Tab缩进、indentConfig与快捷键自定义
2026/9/14 17:35:14 网站建设 项目流程

Milkdown嵌套列表缩进调整:3步搞定Tab缩进、indentConfig与快捷键自定义

【免费下载链接】milkdown🍼 Plugin driven WYSIWYG markdown editor framework.项目地址: https://gitcode.com/GitHub_Trending/mi/milkdown

在 Milkdown 里写三级以上的嵌套列表,缩进总失控:Tab 按了没反应、想改缩进宽度不知道去哪配。本文围绕Milkdown 嵌套列表的列表缩进,带你 3 步让 Tab / Shift+Tab 生效、配好 indentConfig、把缩进快捷键自定义成自己的习惯。

嵌套列表为什么总排版失控

先说清楚 Milkdown 里"缩进"到底发生了什么,因为这里有两套机制,混在一起是排错的大头。Milkdown 基于 ProseMirror(一个把文档当树来管的编辑内核),列表项里可以再装一个列表,层级就是树上的父子关系。

  • 列表键位(preset-commonmark 自带):在列表项里按Tab把当前项下沉一级,Shift+Tab升一级,改的是文档树结构;
  • indent 插件:在光标处插入一段缩进字符(默认 2 个空格),改的是纯文本内容。

列表项的默认键位定义在 list-item 节点源码 里,注意它已经内置了 Ctrl 备用键:

SinkListItem: { shortcuts: ['Tab', 'Mod-]'], ... LiftListItem: { shortcuts: ['Shift-Tab', 'Mod-['],

也就是说Ctrl+]/Ctrl+[天生可用,很多人不知道就自己重写了一遍。

30秒上手:让列表缩进立刻生效

装好 commonmark 预设后,列表内的Tab/Shift+Tab开箱即用,一行配置都不用写。只有你需要"插入缩进字符"的行为时,才要引入 indent 插件。下面这段就是最小配置:声明缩进方式并挂载插件。

import { indent, indentConfig } from '@milkdown/plugin-indent' Editor.make() .config((ctx) => { ctx.set(indentConfig.key, { type: 'space', size: 2 }) }) .use(indent) .create()

size从 2 改成 4,Tab 插入的空格就从 2 个变 4 个。顺带一提,官方 Crepe 预设已经把默认缩进改成了 4 空格,如果你用的就是 Crepe,可能根本不用配。

搞懂 indentConfig:空格还是 Tab?

indentConfig一共只有两个参数,看这张表就够了:

参数默认值作用
type'space'插空格,还是插一个真正的制表符\t
size2type为 space 时插几个空格;为 tab 时固定插 1 个\t

size只对空格生效,这是新手最常踩的坑:设type: 'tab'size写多大都没用。核心逻辑就一行,摘自 indent 插件源码:

const text = options.type === 'space' ? Array(options.size).fill(' ').join('') : '\t' return tr.insertText(text, to)

type决定字符种类,size决定空格数量,改完立刻在下一次按键时生效。

🛠️ 快捷键定制:把缩进键改成自己的

想让某个顺手组合触发缩进?给 Milkdown 的 keymap 管理器注册一个新快捷键即可——它按"优先级高先执行、同级按注册顺序"分发按键。下面这段注册了两个自定义键,调用的是和默认 Tab 完全相同的下沉/升级命令:

import { $shortcut } from '@milkdown/utils' import { commandsCtx } from '@milkdown/core' import { sinkListItemCommand, liftListItemCommand, } from '@milkdown/preset-commonmark' export const myIndentKeys = $shortcut((ctx) => ({ 'Ctrl-Shift-]': () => ctx.get(commandsCtx).call(sinkListItemCommand.key), 'Ctrl-Shift-[': () => ctx.get(commandsCtx).call(liftListItemCommand.key), }))

最后.use(myIndentKeys)挂上即可,键名换成你自己的。若同一键位和别的插件撞车,用priority参数提高优先级就能压过对方。

✅ 自查清单:三个高频翻车点

  1. Tab 不生效
    • 先确认位置:代码块里 Tab 归 CodeMirror 管,普通段落归 indent 插件管,列表项里才是层级下沉;
    • 确认挂了.use(indent),漏掉是最常见原因;
    • 在初始化后执行ctx.get(indentConfig.key),控制台看一眼实际值。
  2. 快捷键被覆盖
    • 检查是否有其它插件先注册了同一键位,后注册的排在后面;
    • 给自定义 keymap 传更高的priority,或直接换键位验证是不是冲突。
  3. 配置没生效
    • ctx.set(indentConfig.key, ...)必须在.create()之前完成;
    • 运行中要动态改,用ctx.update(indentConfig.key, v => ({ ...v, size: 4 }))
    • 用了 Crepe 的话记得它的默认值是size: 4,别拿 2 当基准怀疑人生。

掌握这套组合,列表缩进就再也不会失控:默认键位保你 30 秒上手,indentConfig管字符与宽度,keymap 管手感。想深入插件开发规范,可以看仓库的 CONTRIBUTING.md。

【免费下载链接】milkdown🍼 Plugin driven WYSIWYG markdown editor framework.项目地址: https://gitcode.com/GitHub_Trending/mi/milkdown

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询