forked from mxx1111/mdlook
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmarkdown.ts
More file actions
137 lines (117 loc) · 4.66 KB
/
Copy pathmarkdown.ts
File metadata and controls
137 lines (117 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete'
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'
import { markdown, markdownLanguage } from '@codemirror/lang-markdown'
import { foldGutter, foldKeymap } from '@codemirror/language'
import { languages } from '@codemirror/language-data'
import { highlightSelectionMatches } from '@codemirror/search'
import { EditorSelection, EditorState, Prec } from '@codemirror/state'
import { EditorView, keymap, placeholder } from '@codemirror/view'
import { indentationMarkers } from '@replit/codemirror-indentation-markers'
import { formatDoc } from '../utils/fileHelpers'
import { applyHeading, formatBold, formatCode, formatItalic, formatLink, formatOrderedList, formatStrikethrough, formatUnorderedList, redoAction, undoAction } from './format'
/**
* Markdown 格式化处理函数
*/
async function formatMarkdown(view: EditorView) {
const content = view.state.doc.toString()
const formatted = await formatDoc(content, `markdown`)
view.dispatch({
changes: { from: 0, to: view.state.doc.length, insert: formatted },
})
}
/**
* 在光标位置插入缩进(空格)
*/
function insertTabAtCursor(view: EditorView): boolean {
const spaces = ` ` // 2 个空格作为缩进
const changes = view.state.changeByRange(range => ({
changes: { from: range.from, to: range.to, insert: spaces },
range: EditorSelection.range(range.from + spaces.length, range.from + spaces.length),
}))
view.dispatch(changes)
return true
}
interface MarkdownKeymapOptions {
onSearch?: (view: EditorView) => void
onReplace?: (view: EditorView) => void
}
/**
* Markdown 编辑器的快捷键映射
*
* @param options - 配置选项
* @param options.onSearch - 搜索回调(可选)
*/
export function markdownKeymap(options?: MarkdownKeymapOptions) {
const { onSearch, onReplace } = options || {}
return keymap.of([
// Tab 键在光标位置插入缩进
{ key: `Tab`, run: insertTabAtCursor },
// 撤销/重做
{ key: `Mod-z`, run: undoAction },
{ key: `Mod-y`, run: redoAction },
// 文本格式
{ key: `Mod-b`, run: (view) => { formatBold(view); return true } },
{ key: `Mod-i`, run: (view) => { formatItalic(view); return true } },
{ key: `Mod-d`, run: (view) => { formatStrikethrough(view); return true } },
{ key: `Mod-k`, run: (view) => { formatLink(view); return true } },
{ key: `Mod-e`, run: (view) => { formatCode(view); return true } },
// 标题(使用 Mod-1 到 Mod-6)
{ key: `Mod-1`, run: (view) => { applyHeading(view, 1); return true } },
{ key: `Mod-2`, run: (view) => { applyHeading(view, 2); return true } },
{ key: `Mod-3`, run: (view) => { applyHeading(view, 3); return true } },
{ key: `Mod-4`, run: (view) => { applyHeading(view, 4); return true } },
{ key: `Mod-5`, run: (view) => { applyHeading(view, 5); return true } },
{ key: `Mod-6`, run: (view) => { applyHeading(view, 6); return true } },
// 列表
{ key: `Mod-u`, run: (view) => { formatUnorderedList(view); return true } },
{ key: `Mod-o`, run: (view) => { formatOrderedList(view); return true } },
// 搜索和替换(可选)
...(onSearch ? [{ key: `Mod-f`, run: (view: EditorView) => { onSearch(view); return true } }] : []),
...(onReplace ? [{ key: `Mod-h`, run: (view: EditorView) => { onReplace(view); return true } }] : []),
// 格式化
{ key: `Shift-Alt-f`, run: (view: EditorView) => { formatMarkdown(view); return true } },
// 阻止 Mod-g(避免触发 CodeMirror 内置搜索)
{ key: `Mod-g`, run: () => true },
])
}
/**
* Markdown 编辑器的基础扩展集合
* 包含语言支持、历史记录、括号匹配等基础功能
*
* 主题请使用统一的 theme() 函数,从 './themes' 导入
*
* @param options - 配置选项(可选)
* @param options.onSearch - 搜索回调,触发快捷键 Mod-f
*
*/
export function markdownSetup(options?: MarkdownKeymapOptions) {
return [
// 基础功能
history(),
highlightSelectionMatches(),
closeBrackets(),
// 缩进标记
indentationMarkers(),
// 语言支持
markdown({
base: markdownLanguage,
codeLanguages: languages,
addKeymap: true,
}),
// Markdown 快捷键(高优先级,优先于默认快捷键)
Prec.high(markdownKeymap(options)),
// 折叠功能
foldGutter(),
// 默认快捷键
keymap.of([
...defaultKeymap,
...historyKeymap,
...closeBracketsKeymap,
...foldKeymap,
]),
// 编辑器配置
EditorView.lineWrapping,
EditorState.allowMultipleSelections.of(true),
placeholder(`输入 "/" 快速添加内容`),
]
}