Skip to content

Commit 108fcce

Browse files
committed
fix: 修复列表有时丢失缩进的问题
1 parent cbc3c74 commit 108fcce

7 files changed

Lines changed: 254 additions & 13 deletions

File tree

lang/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// 导入国际化JSON文件
1+
// 导入国际化JSON文件(合并模式)
22
import langJSON from "./index.json";
33
(function () {
44
// 定义翻译函数
@@ -42,7 +42,7 @@ import langJSON from "./index.json";
4242
globalThis.$t = globalThis.$t || $t;
4343
// 将简单翻译函数挂载到globalThis对象上
4444
globalThis.$$t = $$t;
45-
// 定义从JSON文件中获取指定键的语言对象的方法
45+
// 定义从JSON文件中获取指定键的语言对象的方法(合并模式)
4646
globalThis._getJSONKey = function (key, insertJSONObj = undefined) {
4747
// 获取JSON对象
4848
const JSONObj = insertJSONObj;

src/core/keymap/index.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,55 @@ function createListKeymap(schema: Schema): Record<string, any> {
120120

121121
const parent = $from.parent;
122122

123-
// 检查是否在源码模式下的代码块段落中
123+
// 检查是否在源码模式下
124124
const decorationState = decorationPluginKey.getState(state);
125+
126+
// 源码模式下的列表段落 Enter 处理
127+
if (decorationState?.sourceView && parent.type.name === "paragraph" && parent.attrs.listId) {
128+
if (dispatch) {
129+
const listId = parent.attrs.listId;
130+
const listLineIndex = parent.attrs.listLineIndex;
131+
const listTotalLines = parent.attrs.listTotalLines;
132+
const tr = state.tr.split($from.pos);
133+
134+
// split 后两个段落都继承了原始属性(相同的 listLineIndex)
135+
// 需要更新:第二个段落 listLineIndex+1,后续段落 listLineIndex+1,所有段落 listTotalLines+1
136+
let foundSplit = false;
137+
tr.doc.descendants((node: any, pos: number) => {
138+
if (node.type.name === "paragraph" && node.attrs.listId === listId) {
139+
if (node.attrs.listLineIndex === listLineIndex && !foundSplit) {
140+
foundSplit = true;
141+
tr.setNodeMarkup(pos, null, {
142+
...node.attrs,
143+
listTotalLines: listTotalLines + 1,
144+
});
145+
} else if (node.attrs.listLineIndex === listLineIndex && foundSplit) {
146+
tr.setNodeMarkup(pos, null, {
147+
...node.attrs,
148+
listLineIndex: listLineIndex + 1,
149+
listTotalLines: listTotalLines + 1,
150+
});
151+
} else if (node.attrs.listLineIndex > listLineIndex) {
152+
tr.setNodeMarkup(pos, null, {
153+
...node.attrs,
154+
listLineIndex: node.attrs.listLineIndex + 1,
155+
listTotalLines: listTotalLines + 1,
156+
});
157+
} else {
158+
tr.setNodeMarkup(pos, null, {
159+
...node.attrs,
160+
listTotalLines: listTotalLines + 1,
161+
});
162+
}
163+
}
164+
});
165+
166+
dispatch(tr);
167+
}
168+
return true;
169+
}
170+
171+
// 源码模式下的代码块段落 Enter 处理
125172
if (
126173
decorationState?.sourceView &&
127174
parent.type.name === "paragraph" &&

src/core/parser/index.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -909,8 +909,13 @@ export class MarkdownParser {
909909
// 检查空行后面是否还有缩进内容
910910
if (!inCodeBlock && itemEndIndex + 1 < lines.length) {
911911
const afterEmpty = lines[itemEndIndex + 1];
912-
// 如果后面是新的列表项或没有缩进,则结束
913-
if (BLOCK_PATTERNS.bullet_list.test(afterEmpty) || !afterEmpty.match(/^\s{2,}/)) {
912+
// 如果后面是同级/上级列表项或没有缩进,则结束
913+
const afterBulletMatch = afterEmpty.match(BLOCK_PATTERNS.bullet_list);
914+
if (afterBulletMatch) {
915+
if (afterBulletMatch[1].length < itemIndent) {
916+
break;
917+
}
918+
} else if (!afterEmpty.match(/^\s{2,}/)) {
914919
break;
915920
}
916921
}
@@ -919,9 +924,13 @@ export class MarkdownParser {
919924
continue;
920925
}
921926

922-
// 检查是否是新的列表项(代码块内部不检查)
923-
if (!inCodeBlock && BLOCK_PATTERNS.bullet_list.test(nextLine)) {
924-
break;
927+
// 检查是否是同级/上级的新列表项(代码块内部不检查)
928+
// 嵌套的列表项(缩进 >= itemIndent)不中断,作为子内容收集
929+
if (!inCodeBlock) {
930+
const nextBulletMatch = nextLine.match(BLOCK_PATTERNS.bullet_list);
931+
if (nextBulletMatch && nextBulletMatch[1].length < itemIndent) {
932+
break;
933+
}
925934
}
926935

927936
// 检查是否有足够的缩进
@@ -1027,7 +1036,13 @@ export class MarkdownParser {
10271036
if (nextLine.trim() === "") {
10281037
if (!inCodeBlock && itemEndIndex + 1 < lines.length) {
10291038
const afterEmpty = lines[itemEndIndex + 1];
1030-
if (BLOCK_PATTERNS.ordered_list.test(afterEmpty) || !afterEmpty.match(/^\s{2,}/)) {
1039+
// 如果后面是同级/上级列表项或没有缩进,则结束
1040+
const afterOrderedMatch = afterEmpty.match(BLOCK_PATTERNS.ordered_list);
1041+
if (afterOrderedMatch) {
1042+
if (afterOrderedMatch[1].length < itemIndent) {
1043+
break;
1044+
}
1045+
} else if (!afterEmpty.match(/^\s{2,}/)) {
10311046
break;
10321047
}
10331048
}
@@ -1036,8 +1051,13 @@ export class MarkdownParser {
10361051
continue;
10371052
}
10381053

1039-
if (!inCodeBlock && BLOCK_PATTERNS.ordered_list.test(nextLine)) {
1040-
break;
1054+
// 检查是否是同级/上级的新列表项(代码块内部不检查)
1055+
// 嵌套的列表项(缩进 >= itemIndent)不中断,作为子内容收集
1056+
if (!inCodeBlock) {
1057+
const nextOrderedMatch = nextLine.match(BLOCK_PATTERNS.ordered_list);
1058+
if (nextOrderedMatch && nextOrderedMatch[1].length < itemIndent) {
1059+
break;
1060+
}
10411061
}
10421062

10431063
const lineIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;

0 commit comments

Comments
 (0)