@coze-editor/preset-prompt 0.1.0-alpha.0fd19e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 coze-dev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,226 @@
1
+ // src/index.ts
2
+ import { sharedPreset } from "@coze-editor/preset-expression";
3
+ import { focusableKeymap } from "@coze-editor/extensions";
4
+ import {
5
+ getMainSelectionRects,
6
+ maxHeight,
7
+ minHeight,
8
+ replaceText,
9
+ undo,
10
+ redo,
11
+ height,
12
+ transformTextInSelection
13
+ } from "@coze-editor/core-plugins";
14
+ import {
15
+ api,
16
+ extension,
17
+ option
18
+ } from "@coze-editor/core";
19
+ import { Prec } from "@codemirror/state";
20
+
21
+ // src/language.ts
22
+ import { inputRules } from "@coze-editor/extensions";
23
+ import { replaceTextByRange } from "@coze-editor/core-plugins";
24
+ import { LanguageSupport } from "@codemirror/language";
25
+ import { closeBrackets } from "@codemirror/autocomplete";
26
+
27
+ // src/languages/prompt/index.ts
28
+ import { parseMixed } from "@lezer/common";
29
+ import { parser as jinjaParser } from "@coze-editor/lezer-parser-jinja2";
30
+ import { LRLanguage as LRLanguage2 } from "@codemirror/language";
31
+
32
+ // src/languages/prompt/markdown.ts
33
+ import {
34
+ parser as parser2,
35
+ GFM,
36
+ Subscript,
37
+ Superscript,
38
+ Emoji,
39
+ parseCode
40
+ } from "@lezer/markdown";
41
+ import { NodeProp } from "@lezer/common";
42
+ import {
43
+ Language,
44
+ defineLanguageFacet,
45
+ foldService,
46
+ indentNodeProp,
47
+ languageDataProp,
48
+ syntaxTree
49
+ } from "@codemirror/language";
50
+
51
+ // src/languages/prompt/html.ts
52
+ import { parser } from "@lezer/html";
53
+ import { LRLanguage } from "@codemirror/language";
54
+ var htmlLanguage = LRLanguage.define({
55
+ parser: parser.configure({
56
+ dialect: "noMatch"
57
+ })
58
+ });
59
+
60
+ // src/languages/prompt/markdown.ts
61
+ var headingProp = new NodeProp();
62
+ function isHeading(type) {
63
+ const match = /^(?:ATX|Setext)Heading(\d)$/.exec(type.name);
64
+ return match ? Number(match[1]) : void 0;
65
+ }
66
+ function findSectionEnd(headerNode, level) {
67
+ let last = headerNode;
68
+ for (; ; ) {
69
+ const next = last.nextSibling;
70
+ let heading;
71
+ if (!next || (heading = isHeading(next.type)) != null && heading <= level) {
72
+ break;
73
+ }
74
+ last = next;
75
+ }
76
+ return last.to;
77
+ }
78
+ var headingFold = foldService.of((state, start, end) => {
79
+ for (let node = syntaxTree(state).resolveInner(end, -1); node; node = node.parent) {
80
+ if (node.from < start) {
81
+ break;
82
+ }
83
+ const heading = node.type.prop(headingProp);
84
+ if (heading == null) {
85
+ continue;
86
+ }
87
+ const upto = findSectionEnd(node, heading);
88
+ if (upto > end) {
89
+ return { from: end, to: upto };
90
+ }
91
+ }
92
+ return null;
93
+ });
94
+ var data = defineLanguageFacet({});
95
+ var html = parseCode({
96
+ htmlParser: htmlLanguage.parser
97
+ });
98
+ var markdownParser = parser2.configure([
99
+ html,
100
+ GFM,
101
+ Subscript,
102
+ Superscript,
103
+ Emoji,
104
+ {
105
+ props: [
106
+ headingProp.add(isHeading),
107
+ indentNodeProp.add({
108
+ Document: () => null
109
+ }),
110
+ languageDataProp.add({
111
+ Document: data
112
+ })
113
+ ]
114
+ }
115
+ ]);
116
+ var markdownLanguage = new Language(data, markdownParser, [], "markdown");
117
+
118
+ // src/languages/prompt/index.ts
119
+ var promptLanguage = LRLanguage2.define({
120
+ parser: jinjaParser.configure({
121
+ wrap: parseMixed((node) => {
122
+ if (node.type.isTop) {
123
+ return {
124
+ parser: markdownLanguage.parser,
125
+ overlay: [
126
+ {
127
+ from: node.from,
128
+ to: node.to
129
+ }
130
+ ]
131
+ };
132
+ }
133
+ return null;
134
+ })
135
+ })
136
+ });
137
+ var support = [
138
+ headingFold
139
+ // autoCloseTags,
140
+ ];
141
+
142
+ // src/language.ts
143
+ var brackets = ["'", '"', "{", "[", "("];
144
+ var autoCloseBrackets = [
145
+ closeBrackets(),
146
+ promptLanguage.data.of({
147
+ closeBrackets: {
148
+ brackets
149
+ }
150
+ }),
151
+ markdownLanguage.data.of({
152
+ closeBrackets: {
153
+ brackets
154
+ }
155
+ }),
156
+ inputRules([
157
+ {
158
+ type: "character",
159
+ triggerCharacter: "%",
160
+ handler({ view, from, to }) {
161
+ const previousChar = view.state.sliceDoc(Math.max(0, from - 1), from);
162
+ const nextChar = view.state.sliceDoc(
163
+ from,
164
+ Math.min(from + 1, view.state.doc.length)
165
+ );
166
+ if (previousChar === "{" && nextChar === "}") {
167
+ replaceTextByRange({ view })({
168
+ from,
169
+ to,
170
+ text: "%%",
171
+ cursorOffset: -1
172
+ });
173
+ return true;
174
+ }
175
+ return false;
176
+ }
177
+ },
178
+ {
179
+ type: "character",
180
+ triggerCharacter: "#",
181
+ handler({ view, from, to }) {
182
+ const previousChar = view.state.sliceDoc(Math.max(0, from - 1), from);
183
+ const nextChar = view.state.sliceDoc(
184
+ from,
185
+ Math.min(from + 1, view.state.doc.length)
186
+ );
187
+ if (previousChar === "{" && nextChar === "}") {
188
+ replaceTextByRange({ view })({
189
+ from,
190
+ to,
191
+ text: "##",
192
+ cursorOffset: -1
193
+ });
194
+ return true;
195
+ }
196
+ return false;
197
+ }
198
+ }
199
+ ])
200
+ ];
201
+ var languageSupport = new LanguageSupport(promptLanguage, [
202
+ support,
203
+ autoCloseBrackets
204
+ ]);
205
+
206
+ // src/index.ts
207
+ var preset = [
208
+ ...sharedPreset,
209
+ option("minHeight", minHeight),
210
+ option("maxHeight", maxHeight),
211
+ option("height", height),
212
+ api("getMainSelectionRects", getMainSelectionRects),
213
+ api("replaceText", replaceText),
214
+ api("undo", undo),
215
+ api("redo", redo),
216
+ api("transformTextInSelection", transformTextInSelection),
217
+ extension([Prec.high(focusableKeymap)])
218
+ ];
219
+ var index_default = preset;
220
+ export {
221
+ index_default as default,
222
+ languageSupport,
223
+ markdownLanguage,
224
+ promptLanguage
225
+ };
226
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/index.ts","../../src/language.ts","../../src/languages/prompt/index.ts","../../src/languages/prompt/markdown.ts","../../src/languages/prompt/html.ts"],"sourcesContent":["// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport { sharedPreset } from '@coze-editor/preset-expression';\nimport { focusableKeymap } from '@coze-editor/extensions';\nimport {\n getMainSelectionRects,\n maxHeight,\n minHeight,\n replaceText,\n undo,\n redo,\n height,\n transformTextInSelection,\n} from '@coze-editor/core-plugins';\nimport {\n type InferEditorAPIFromPlugins,\n api,\n extension,\n option,\n} from '@coze-editor/core';\nimport { Prec } from '@codemirror/state';\n\nimport { languageSupport, markdownLanguage, promptLanguage } from './language';\n\n// const forEachFocusableWidget = ({ view }: { view: EditorView }) => {\n// return (callback: (from, to, widget) => void) => {\n// // use requestMeasure to ensure view is ready\n// view.requestMeasure({\n// read(view) {\n// // @ts-ignore\n// for (const line of view.docView.children) {\n// for (const widget of line.children) {\n// if (widget.isWidget && (widget.widget instanceof FocusableWidget)) {\n// callback(widget.posAtStart, widget.posAtEnd, widget.widget)\n// }\n// }\n// }\n// },\n// })\n// }\n// }\n\n// prompt preset 不使用 drawSelection 的原因:遇到跨行的 inline widget 时光标位置存在问题\nconst preset = [\n ...sharedPreset,\n option('minHeight', minHeight),\n option('maxHeight', maxHeight),\n option('height', height),\n api('getMainSelectionRects', getMainSelectionRects),\n api('replaceText', replaceText),\n api('undo', undo),\n api('redo', redo),\n api('transformTextInSelection', transformTextInSelection),\n extension([Prec.high(focusableKeymap)]),\n];\n\ntype EditorAPI = InferEditorAPIFromPlugins<typeof preset>;\n\nexport default preset;\n\nexport { promptLanguage, markdownLanguage, languageSupport };\n\nexport type { EditorAPI };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport { inputRules } from '@coze-editor/extensions';\nimport { replaceTextByRange } from '@coze-editor/core-plugins';\nimport { LanguageSupport } from '@codemirror/language';\nimport { closeBrackets } from '@codemirror/autocomplete';\n\nimport { promptLanguage, markdownLanguage, support } from './languages/prompt';\n\nconst brackets = [\"'\", '\"', '{', '[', '('];\n\nconst autoCloseBrackets = [\n closeBrackets(),\n promptLanguage.data.of({\n closeBrackets: {\n brackets,\n },\n }),\n\n markdownLanguage.data.of({\n closeBrackets: {\n brackets,\n },\n }),\n\n inputRules([\n {\n type: 'character',\n triggerCharacter: '%',\n handler({ view, from, to }) {\n const previousChar = view.state.sliceDoc(Math.max(0, from - 1), from);\n const nextChar = view.state.sliceDoc(\n from,\n Math.min(from + 1, view.state.doc.length),\n );\n if (previousChar === '{' && nextChar === '}') {\n replaceTextByRange({ view })({\n from,\n to,\n text: '%%',\n cursorOffset: -1,\n });\n return true;\n }\n\n return false;\n },\n },\n {\n type: 'character',\n triggerCharacter: '#',\n handler({ view, from, to }) {\n const previousChar = view.state.sliceDoc(Math.max(0, from - 1), from);\n const nextChar = view.state.sliceDoc(\n from,\n Math.min(from + 1, view.state.doc.length),\n );\n if (previousChar === '{' && nextChar === '}') {\n replaceTextByRange({ view })({\n from,\n to,\n text: '##',\n cursorOffset: -1,\n });\n return true;\n }\n\n return false;\n },\n },\n ]),\n];\n\nconst languageSupport = new LanguageSupport(promptLanguage, [\n support,\n autoCloseBrackets,\n]);\n\nexport { promptLanguage, markdownLanguage, languageSupport };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport { parseMixed } from '@lezer/common';\nimport { parser as jinjaParser } from '@coze-editor/lezer-parser-jinja2';\nimport { LRLanguage } from '@codemirror/language';\n\nimport { headingFold, markdownLanguage } from './markdown';\n\nconst promptLanguage = LRLanguage.define({\n parser: jinjaParser.configure({\n wrap: parseMixed(node => {\n if (node.type.isTop) {\n return {\n parser: markdownLanguage.parser,\n overlay: [\n {\n from: node.from,\n to: node.to,\n },\n ],\n };\n }\n\n return null;\n }),\n }),\n});\n\nconst support = [\n headingFold,\n // autoCloseTags,\n];\n\nexport { promptLanguage, markdownLanguage, support };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport {\n parser,\n GFM,\n Subscript,\n Superscript,\n Emoji,\n parseCode,\n} from '@lezer/markdown';\nimport { NodeProp, type NodeType, type SyntaxNode } from '@lezer/common';\nimport {\n Language,\n defineLanguageFacet,\n foldService,\n indentNodeProp,\n languageDataProp,\n syntaxTree,\n} from '@codemirror/language';\n\nimport { htmlLanguage } from './html';\n\nconst headingProp = new NodeProp();\n\nfunction isHeading(type: NodeType) {\n const match = /^(?:ATX|Setext)Heading(\\d)$/.exec(type.name);\n return match ? Number(match[1]) : undefined;\n}\n\nfunction findSectionEnd(headerNode: SyntaxNode, level: number) {\n let last = headerNode;\n for (;;) {\n const next = last.nextSibling;\n let heading;\n if (\n !next ||\n ((heading = isHeading(next.type)) != null && heading <= level)\n ) {\n break;\n }\n last = next;\n }\n return last.to;\n}\n\nconst headingFold = foldService.of((state, start, end) => {\n for (\n let node: SyntaxNode | null = syntaxTree(state).resolveInner(end, -1);\n node;\n node = node.parent\n ) {\n if (node.from < start) {\n break;\n }\n const heading = node.type.prop(headingProp) as number;\n if (heading == null) {\n continue;\n }\n const upto = findSectionEnd(node, heading);\n if (upto > end) {\n return { from: end, to: upto };\n }\n }\n return null;\n});\n\nconst data = defineLanguageFacet({});\n\nconst html = parseCode({\n htmlParser: htmlLanguage.parser,\n});\n\nconst markdownParser = parser.configure([\n html,\n GFM,\n Subscript,\n Superscript,\n Emoji,\n {\n props: [\n headingProp.add(isHeading),\n indentNodeProp.add({\n Document: () => null,\n }),\n languageDataProp.add({\n Document: data,\n }),\n ],\n },\n]);\n\nconst markdownLanguage = new Language(data, markdownParser, [], 'markdown');\n\nexport { markdownLanguage, headingFold };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport { parser } from '@lezer/html';\nimport { LRLanguage } from '@codemirror/language';\n\nconst htmlLanguage = LRLanguage.define({\n parser: parser.configure({\n dialect: 'noMatch',\n }),\n});\n\n// function elementName(doc: Text, tree: SyntaxNode | null | undefined, max = doc.length) {\n// if (!tree) return ''\n// let tag = tree.firstChild\n// let name = tag && tag.getChild('TagName')\n// return name ? doc.sliceString(name.from, Math.min(name.to, max)) : ''\n// }\n\n// const selfClosers = new Set(\n// 'area base br col command embed frame hr img input keygen link meta param source track wbr menuitem'\n// .split(' ')\n// )\n\n// const autoCloseTags = EditorView.inputHandler.of((view, from, to, text, insertTransaction) => {\n// if (\n// view.composing ||\n// view.state.readOnly ||\n// from != to ||\n// (text != '>' && text != '/')\n// ) {\n// return false\n// }\n\n// const base = insertTransaction(), { state } = base\n\n// if (!htmlLanguage.isActiveAt(state, from, -1)) {\n// return false\n// }\n\n// const closeTags = state.changeByRange(range => {\n// const didType = state.doc.sliceString(range.from - 1, range.to) == text\n// const { head } = range\n// const after = syntaxTree(state).resolveInner(head, -1)\n// let name\n\n// if (didType && text == '>' && after.name == 'EndTag') {\n// const tag = after.parent!\n// if (\n// (name = elementName(state.doc, tag.parent, head)) &&\n// !selfClosers.has(name)) {\n// const to = head + (state.doc.sliceString(head, head + 1) === '>' ? 1 : 0)\n// const insert = `</${name}>`\n// return { range, changes: { from: head, to, insert } }\n// }\n// } else if (didType && text == '/' && after.name == 'IncompleteCloseTag') {\n// const tag = after.parent!\n// if (after.from == head - 2 && tag.lastChild?.name != 'CloseTag' &&\n// (name = elementName(state.doc, tag, head)) && !selfClosers.has(name)) {\n// const to = head + (state.doc.sliceString(head, head + 1) === '>' ? 1 : 0)\n// const insert = `${name}>`\n// return {\n// range: EditorSelection.cursor(head + insert.length, -1),\n// changes: { from: head, to, insert }\n// }\n// }\n// }\n// return { range }\n// })\n// if (closeTags.changes.empty) return false\n// view.dispatch([\n// base,\n// state.update(closeTags, {\n// userEvent: 'input.complete',\n// scrollIntoView: true\n// })\n// ])\n// return true\n// })\n\nexport { htmlLanguage };\n"],"mappings":"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","names":["LRLanguage","parser","parser","LRLanguage"]}
@@ -0,0 +1,36 @@
1
+ import * as _codemirror_view from '@codemirror/view';
2
+ import * as _coze_editor_core_plugins from '@coze-editor/core-plugins';
3
+ import * as _coze_editor_extensions from '@coze-editor/extensions';
4
+ import * as _coze_editor_core from '@coze-editor/core';
5
+ import { InferEditorAPIFromPlugins } from '@coze-editor/core';
6
+ import { Language, LRLanguage, LanguageSupport } from '@codemirror/language';
7
+
8
+ declare const markdownLanguage: Language;
9
+
10
+ declare const promptLanguage: LRLanguage;
11
+
12
+ declare const languageSupport: LanguageSupport;
13
+
14
+ declare const preset: (_coze_editor_core.ExtensionPluginSpec | _coze_editor_core.OptionPluginSpec<"fontSize", number> | _coze_editor_core.OptionPluginSpec<"placeholder", string | HTMLElement> | _coze_editor_core.OptionPluginSpec<"readOnly", boolean> | _coze_editor_core.OptionPluginSpec<"editable", boolean> | _coze_editor_core.OptionPluginSpec<"inputRules", _coze_editor_extensions.InputRule[]> | _coze_editor_core.OptionPluginSpec<"contentAttributes", _coze_editor_core_plugins.Attrs | ((view: _codemirror_view.EditorView) => _coze_editor_core_plugins.Attrs | null)> | _coze_editor_core.EventPluginSpec<"change", {
15
+ value: string;
16
+ }> | _coze_editor_core.EventPluginSpec<"focus", symbol> | _coze_editor_core.EventPluginSpec<"blur", symbol> | _coze_editor_core.EventPluginSpec<"selectionChange", {
17
+ selection: {
18
+ from: number;
19
+ to: number;
20
+ head: number;
21
+ anchor: number;
22
+ };
23
+ update: _codemirror_view.ViewUpdate;
24
+ }> | _coze_editor_core.EventPluginSpec<"viewUpdate", _codemirror_view.ViewUpdate> | _coze_editor_core.DOMEventHandlerPluginSpec<"compositionstart"> | _coze_editor_core.DOMEventHandlerPluginSpec<"compositionend"> | _coze_editor_core.DOMEventHandlerPluginSpec<"mousedown"> | _coze_editor_core.DOMEventHandlerPluginSpec<"mouseup"> | _coze_editor_core.APIPluginSpec<"disableKeybindings", [keys: string[]], void> | _coze_editor_core.APIPluginSpec<"getView", [], _codemirror_view.EditorView> | _coze_editor_core.APIPluginSpec<"matchBefore", [match: RegExp], {
25
+ from: number;
26
+ to: number;
27
+ text: string;
28
+ }> | _coze_editor_core.APIPluginSpec<"updateWholeDecorations", [], void> | _coze_editor_core.APIPluginSpec<"getValue", [], string> | _coze_editor_core.APIPluginSpec<"setValue", [value: string], void> | _coze_editor_core.APIPluginSpec<"focus", [], void> | _coze_editor_core.APIPluginSpec<"blur", [], void> | _coze_editor_core.APIPluginSpec<"isFocused", [], boolean> | _coze_editor_core.APIPluginSpec<"getCursorPosition", [], number> | _coze_editor_core.APIPluginSpec<"setCursorPosition", [pos: number], void> | _coze_editor_core.APIPluginSpec<"getSelection", [], {
29
+ from: number;
30
+ to: number;
31
+ anchor: number;
32
+ head: number;
33
+ }> | _coze_editor_core.APIPluginSpec<"replaceTextByRange", [_coze_editor_core_plugins.ReplaceTextByRangeOptions], void> | _coze_editor_core.OptionPluginSpec<"minHeight", string | number> | _coze_editor_core.OptionPluginSpec<"maxHeight", string | number> | _coze_editor_core.OptionPluginSpec<"height", string | number> | _coze_editor_core.APIPluginSpec<"getMainSelectionRects", [], Pick<_codemirror_view.RectangleMarker, keyof _codemirror_view.RectangleMarker>[]> | _coze_editor_core.APIPluginSpec<"replaceText", [options: _coze_editor_core_plugins.ReplaceTextOptions], void> | _coze_editor_core.APIPluginSpec<"undo", [], void> | _coze_editor_core.APIPluginSpec<"redo", [], void> | _coze_editor_core.APIPluginSpec<"transformTextInSelection", [transformer: (text: string) => string | undefined], void>)[];
34
+ type EditorAPI = InferEditorAPIFromPlugins<typeof preset>;
35
+
36
+ export { type EditorAPI, preset as default, languageSupport, markdownLanguage, promptLanguage };
@@ -0,0 +1,36 @@
1
+ import * as _codemirror_view from '@codemirror/view';
2
+ import * as _coze_editor_core_plugins from '@coze-editor/core-plugins';
3
+ import * as _coze_editor_extensions from '@coze-editor/extensions';
4
+ import * as _coze_editor_core from '@coze-editor/core';
5
+ import { InferEditorAPIFromPlugins } from '@coze-editor/core';
6
+ import { Language, LRLanguage, LanguageSupport } from '@codemirror/language';
7
+
8
+ declare const markdownLanguage: Language;
9
+
10
+ declare const promptLanguage: LRLanguage;
11
+
12
+ declare const languageSupport: LanguageSupport;
13
+
14
+ declare const preset: (_coze_editor_core.ExtensionPluginSpec | _coze_editor_core.OptionPluginSpec<"fontSize", number> | _coze_editor_core.OptionPluginSpec<"placeholder", string | HTMLElement> | _coze_editor_core.OptionPluginSpec<"readOnly", boolean> | _coze_editor_core.OptionPluginSpec<"editable", boolean> | _coze_editor_core.OptionPluginSpec<"inputRules", _coze_editor_extensions.InputRule[]> | _coze_editor_core.OptionPluginSpec<"contentAttributes", _coze_editor_core_plugins.Attrs | ((view: _codemirror_view.EditorView) => _coze_editor_core_plugins.Attrs | null)> | _coze_editor_core.EventPluginSpec<"change", {
15
+ value: string;
16
+ }> | _coze_editor_core.EventPluginSpec<"focus", symbol> | _coze_editor_core.EventPluginSpec<"blur", symbol> | _coze_editor_core.EventPluginSpec<"selectionChange", {
17
+ selection: {
18
+ from: number;
19
+ to: number;
20
+ head: number;
21
+ anchor: number;
22
+ };
23
+ update: _codemirror_view.ViewUpdate;
24
+ }> | _coze_editor_core.EventPluginSpec<"viewUpdate", _codemirror_view.ViewUpdate> | _coze_editor_core.DOMEventHandlerPluginSpec<"compositionstart"> | _coze_editor_core.DOMEventHandlerPluginSpec<"compositionend"> | _coze_editor_core.DOMEventHandlerPluginSpec<"mousedown"> | _coze_editor_core.DOMEventHandlerPluginSpec<"mouseup"> | _coze_editor_core.APIPluginSpec<"disableKeybindings", [keys: string[]], void> | _coze_editor_core.APIPluginSpec<"getView", [], _codemirror_view.EditorView> | _coze_editor_core.APIPluginSpec<"matchBefore", [match: RegExp], {
25
+ from: number;
26
+ to: number;
27
+ text: string;
28
+ }> | _coze_editor_core.APIPluginSpec<"updateWholeDecorations", [], void> | _coze_editor_core.APIPluginSpec<"getValue", [], string> | _coze_editor_core.APIPluginSpec<"setValue", [value: string], void> | _coze_editor_core.APIPluginSpec<"focus", [], void> | _coze_editor_core.APIPluginSpec<"blur", [], void> | _coze_editor_core.APIPluginSpec<"isFocused", [], boolean> | _coze_editor_core.APIPluginSpec<"getCursorPosition", [], number> | _coze_editor_core.APIPluginSpec<"setCursorPosition", [pos: number], void> | _coze_editor_core.APIPluginSpec<"getSelection", [], {
29
+ from: number;
30
+ to: number;
31
+ anchor: number;
32
+ head: number;
33
+ }> | _coze_editor_core.APIPluginSpec<"replaceTextByRange", [_coze_editor_core_plugins.ReplaceTextByRangeOptions], void> | _coze_editor_core.OptionPluginSpec<"minHeight", string | number> | _coze_editor_core.OptionPluginSpec<"maxHeight", string | number> | _coze_editor_core.OptionPluginSpec<"height", string | number> | _coze_editor_core.APIPluginSpec<"getMainSelectionRects", [], Pick<_codemirror_view.RectangleMarker, keyof _codemirror_view.RectangleMarker>[]> | _coze_editor_core.APIPluginSpec<"replaceText", [options: _coze_editor_core_plugins.ReplaceTextOptions], void> | _coze_editor_core.APIPluginSpec<"undo", [], void> | _coze_editor_core.APIPluginSpec<"redo", [], void> | _coze_editor_core.APIPluginSpec<"transformTextInSelection", [transformer: (text: string) => string | undefined], void>)[];
34
+ type EditorAPI = InferEditorAPIFromPlugins<typeof preset>;
35
+
36
+ export { type EditorAPI, preset as default, languageSupport, markdownLanguage, promptLanguage };
package/dist/index.js ADDED
@@ -0,0 +1,225 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ default: () => index_default,
23
+ languageSupport: () => languageSupport,
24
+ markdownLanguage: () => markdownLanguage,
25
+ promptLanguage: () => promptLanguage
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var import_preset_expression = require("@coze-editor/preset-expression");
29
+ var import_extensions2 = require("@coze-editor/extensions");
30
+ var import_core_plugins2 = require("@coze-editor/core-plugins");
31
+ var import_core = require("@coze-editor/core");
32
+ var import_state = require("@codemirror/state");
33
+
34
+ // src/language.ts
35
+ var import_extensions = require("@coze-editor/extensions");
36
+ var import_core_plugins = require("@coze-editor/core-plugins");
37
+ var import_language4 = require("@codemirror/language");
38
+ var import_autocomplete = require("@codemirror/autocomplete");
39
+
40
+ // src/languages/prompt/index.ts
41
+ var import_common2 = require("@lezer/common");
42
+ var import_lezer_parser_jinja2 = require("@coze-editor/lezer-parser-jinja2");
43
+ var import_language3 = require("@codemirror/language");
44
+
45
+ // src/languages/prompt/markdown.ts
46
+ var import_markdown = require("@lezer/markdown");
47
+ var import_common = require("@lezer/common");
48
+ var import_language2 = require("@codemirror/language");
49
+
50
+ // src/languages/prompt/html.ts
51
+ var import_html = require("@lezer/html");
52
+ var import_language = require("@codemirror/language");
53
+ var htmlLanguage = import_language.LRLanguage.define({
54
+ parser: import_html.parser.configure({
55
+ dialect: "noMatch"
56
+ })
57
+ });
58
+
59
+ // src/languages/prompt/markdown.ts
60
+ var headingProp = new import_common.NodeProp();
61
+ function isHeading(type) {
62
+ const match = /^(?:ATX|Setext)Heading(\d)$/.exec(type.name);
63
+ return match ? Number(match[1]) : void 0;
64
+ }
65
+ function findSectionEnd(headerNode, level) {
66
+ let last = headerNode;
67
+ for (; ; ) {
68
+ const next = last.nextSibling;
69
+ let heading;
70
+ if (!next || (heading = isHeading(next.type)) != null && heading <= level) {
71
+ break;
72
+ }
73
+ last = next;
74
+ }
75
+ return last.to;
76
+ }
77
+ var headingFold = import_language2.foldService.of((state, start, end) => {
78
+ for (let node = (0, import_language2.syntaxTree)(state).resolveInner(end, -1); node; node = node.parent) {
79
+ if (node.from < start) {
80
+ break;
81
+ }
82
+ const heading = node.type.prop(headingProp);
83
+ if (heading == null) {
84
+ continue;
85
+ }
86
+ const upto = findSectionEnd(node, heading);
87
+ if (upto > end) {
88
+ return { from: end, to: upto };
89
+ }
90
+ }
91
+ return null;
92
+ });
93
+ var data = (0, import_language2.defineLanguageFacet)({});
94
+ var html = (0, import_markdown.parseCode)({
95
+ htmlParser: htmlLanguage.parser
96
+ });
97
+ var markdownParser = import_markdown.parser.configure([
98
+ html,
99
+ import_markdown.GFM,
100
+ import_markdown.Subscript,
101
+ import_markdown.Superscript,
102
+ import_markdown.Emoji,
103
+ {
104
+ props: [
105
+ headingProp.add(isHeading),
106
+ import_language2.indentNodeProp.add({
107
+ Document: () => null
108
+ }),
109
+ import_language2.languageDataProp.add({
110
+ Document: data
111
+ })
112
+ ]
113
+ }
114
+ ]);
115
+ var markdownLanguage = new import_language2.Language(data, markdownParser, [], "markdown");
116
+
117
+ // src/languages/prompt/index.ts
118
+ var promptLanguage = import_language3.LRLanguage.define({
119
+ parser: import_lezer_parser_jinja2.parser.configure({
120
+ wrap: (0, import_common2.parseMixed)((node) => {
121
+ if (node.type.isTop) {
122
+ return {
123
+ parser: markdownLanguage.parser,
124
+ overlay: [
125
+ {
126
+ from: node.from,
127
+ to: node.to
128
+ }
129
+ ]
130
+ };
131
+ }
132
+ return null;
133
+ })
134
+ })
135
+ });
136
+ var support = [
137
+ headingFold
138
+ // autoCloseTags,
139
+ ];
140
+
141
+ // src/language.ts
142
+ var brackets = ["'", '"', "{", "[", "("];
143
+ var autoCloseBrackets = [
144
+ (0, import_autocomplete.closeBrackets)(),
145
+ promptLanguage.data.of({
146
+ closeBrackets: {
147
+ brackets
148
+ }
149
+ }),
150
+ markdownLanguage.data.of({
151
+ closeBrackets: {
152
+ brackets
153
+ }
154
+ }),
155
+ (0, import_extensions.inputRules)([
156
+ {
157
+ type: "character",
158
+ triggerCharacter: "%",
159
+ handler({ view, from, to }) {
160
+ const previousChar = view.state.sliceDoc(Math.max(0, from - 1), from);
161
+ const nextChar = view.state.sliceDoc(
162
+ from,
163
+ Math.min(from + 1, view.state.doc.length)
164
+ );
165
+ if (previousChar === "{" && nextChar === "}") {
166
+ (0, import_core_plugins.replaceTextByRange)({ view })({
167
+ from,
168
+ to,
169
+ text: "%%",
170
+ cursorOffset: -1
171
+ });
172
+ return true;
173
+ }
174
+ return false;
175
+ }
176
+ },
177
+ {
178
+ type: "character",
179
+ triggerCharacter: "#",
180
+ handler({ view, from, to }) {
181
+ const previousChar = view.state.sliceDoc(Math.max(0, from - 1), from);
182
+ const nextChar = view.state.sliceDoc(
183
+ from,
184
+ Math.min(from + 1, view.state.doc.length)
185
+ );
186
+ if (previousChar === "{" && nextChar === "}") {
187
+ (0, import_core_plugins.replaceTextByRange)({ view })({
188
+ from,
189
+ to,
190
+ text: "##",
191
+ cursorOffset: -1
192
+ });
193
+ return true;
194
+ }
195
+ return false;
196
+ }
197
+ }
198
+ ])
199
+ ];
200
+ var languageSupport = new import_language4.LanguageSupport(promptLanguage, [
201
+ support,
202
+ autoCloseBrackets
203
+ ]);
204
+
205
+ // src/index.ts
206
+ var preset = [
207
+ ...import_preset_expression.sharedPreset,
208
+ (0, import_core.option)("minHeight", import_core_plugins2.minHeight),
209
+ (0, import_core.option)("maxHeight", import_core_plugins2.maxHeight),
210
+ (0, import_core.option)("height", import_core_plugins2.height),
211
+ (0, import_core.api)("getMainSelectionRects", import_core_plugins2.getMainSelectionRects),
212
+ (0, import_core.api)("replaceText", import_core_plugins2.replaceText),
213
+ (0, import_core.api)("undo", import_core_plugins2.undo),
214
+ (0, import_core.api)("redo", import_core_plugins2.redo),
215
+ (0, import_core.api)("transformTextInSelection", import_core_plugins2.transformTextInSelection),
216
+ (0, import_core.extension)([import_state.Prec.high(import_extensions2.focusableKeymap)])
217
+ ];
218
+ var index_default = preset;
219
+ // Annotate the CommonJS export names for ESM import in node:
220
+ 0 && (module.exports = {
221
+ languageSupport,
222
+ markdownLanguage,
223
+ promptLanguage
224
+ });
225
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/language.ts","../src/languages/prompt/index.ts","../src/languages/prompt/markdown.ts","../src/languages/prompt/html.ts"],"sourcesContent":["// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport { sharedPreset } from '@coze-editor/preset-expression';\nimport { focusableKeymap } from '@coze-editor/extensions';\nimport {\n getMainSelectionRects,\n maxHeight,\n minHeight,\n replaceText,\n undo,\n redo,\n height,\n transformTextInSelection,\n} from '@coze-editor/core-plugins';\nimport {\n type InferEditorAPIFromPlugins,\n api,\n extension,\n option,\n} from '@coze-editor/core';\nimport { Prec } from '@codemirror/state';\n\nimport { languageSupport, markdownLanguage, promptLanguage } from './language';\n\n// const forEachFocusableWidget = ({ view }: { view: EditorView }) => {\n// return (callback: (from, to, widget) => void) => {\n// // use requestMeasure to ensure view is ready\n// view.requestMeasure({\n// read(view) {\n// // @ts-ignore\n// for (const line of view.docView.children) {\n// for (const widget of line.children) {\n// if (widget.isWidget && (widget.widget instanceof FocusableWidget)) {\n// callback(widget.posAtStart, widget.posAtEnd, widget.widget)\n// }\n// }\n// }\n// },\n// })\n// }\n// }\n\n// prompt preset 不使用 drawSelection 的原因:遇到跨行的 inline widget 时光标位置存在问题\nconst preset = [\n ...sharedPreset,\n option('minHeight', minHeight),\n option('maxHeight', maxHeight),\n option('height', height),\n api('getMainSelectionRects', getMainSelectionRects),\n api('replaceText', replaceText),\n api('undo', undo),\n api('redo', redo),\n api('transformTextInSelection', transformTextInSelection),\n extension([Prec.high(focusableKeymap)]),\n];\n\ntype EditorAPI = InferEditorAPIFromPlugins<typeof preset>;\n\nexport default preset;\n\nexport { promptLanguage, markdownLanguage, languageSupport };\n\nexport type { EditorAPI };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport { inputRules } from '@coze-editor/extensions';\nimport { replaceTextByRange } from '@coze-editor/core-plugins';\nimport { LanguageSupport } from '@codemirror/language';\nimport { closeBrackets } from '@codemirror/autocomplete';\n\nimport { promptLanguage, markdownLanguage, support } from './languages/prompt';\n\nconst brackets = [\"'\", '\"', '{', '[', '('];\n\nconst autoCloseBrackets = [\n closeBrackets(),\n promptLanguage.data.of({\n closeBrackets: {\n brackets,\n },\n }),\n\n markdownLanguage.data.of({\n closeBrackets: {\n brackets,\n },\n }),\n\n inputRules([\n {\n type: 'character',\n triggerCharacter: '%',\n handler({ view, from, to }) {\n const previousChar = view.state.sliceDoc(Math.max(0, from - 1), from);\n const nextChar = view.state.sliceDoc(\n from,\n Math.min(from + 1, view.state.doc.length),\n );\n if (previousChar === '{' && nextChar === '}') {\n replaceTextByRange({ view })({\n from,\n to,\n text: '%%',\n cursorOffset: -1,\n });\n return true;\n }\n\n return false;\n },\n },\n {\n type: 'character',\n triggerCharacter: '#',\n handler({ view, from, to }) {\n const previousChar = view.state.sliceDoc(Math.max(0, from - 1), from);\n const nextChar = view.state.sliceDoc(\n from,\n Math.min(from + 1, view.state.doc.length),\n );\n if (previousChar === '{' && nextChar === '}') {\n replaceTextByRange({ view })({\n from,\n to,\n text: '##',\n cursorOffset: -1,\n });\n return true;\n }\n\n return false;\n },\n },\n ]),\n];\n\nconst languageSupport = new LanguageSupport(promptLanguage, [\n support,\n autoCloseBrackets,\n]);\n\nexport { promptLanguage, markdownLanguage, languageSupport };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport { parseMixed } from '@lezer/common';\nimport { parser as jinjaParser } from '@coze-editor/lezer-parser-jinja2';\nimport { LRLanguage } from '@codemirror/language';\n\nimport { headingFold, markdownLanguage } from './markdown';\n\nconst promptLanguage = LRLanguage.define({\n parser: jinjaParser.configure({\n wrap: parseMixed(node => {\n if (node.type.isTop) {\n return {\n parser: markdownLanguage.parser,\n overlay: [\n {\n from: node.from,\n to: node.to,\n },\n ],\n };\n }\n\n return null;\n }),\n }),\n});\n\nconst support = [\n headingFold,\n // autoCloseTags,\n];\n\nexport { promptLanguage, markdownLanguage, support };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport {\n parser,\n GFM,\n Subscript,\n Superscript,\n Emoji,\n parseCode,\n} from '@lezer/markdown';\nimport { NodeProp, type NodeType, type SyntaxNode } from '@lezer/common';\nimport {\n Language,\n defineLanguageFacet,\n foldService,\n indentNodeProp,\n languageDataProp,\n syntaxTree,\n} from '@codemirror/language';\n\nimport { htmlLanguage } from './html';\n\nconst headingProp = new NodeProp();\n\nfunction isHeading(type: NodeType) {\n const match = /^(?:ATX|Setext)Heading(\\d)$/.exec(type.name);\n return match ? Number(match[1]) : undefined;\n}\n\nfunction findSectionEnd(headerNode: SyntaxNode, level: number) {\n let last = headerNode;\n for (;;) {\n const next = last.nextSibling;\n let heading;\n if (\n !next ||\n ((heading = isHeading(next.type)) != null && heading <= level)\n ) {\n break;\n }\n last = next;\n }\n return last.to;\n}\n\nconst headingFold = foldService.of((state, start, end) => {\n for (\n let node: SyntaxNode | null = syntaxTree(state).resolveInner(end, -1);\n node;\n node = node.parent\n ) {\n if (node.from < start) {\n break;\n }\n const heading = node.type.prop(headingProp) as number;\n if (heading == null) {\n continue;\n }\n const upto = findSectionEnd(node, heading);\n if (upto > end) {\n return { from: end, to: upto };\n }\n }\n return null;\n});\n\nconst data = defineLanguageFacet({});\n\nconst html = parseCode({\n htmlParser: htmlLanguage.parser,\n});\n\nconst markdownParser = parser.configure([\n html,\n GFM,\n Subscript,\n Superscript,\n Emoji,\n {\n props: [\n headingProp.add(isHeading),\n indentNodeProp.add({\n Document: () => null,\n }),\n languageDataProp.add({\n Document: data,\n }),\n ],\n },\n]);\n\nconst markdownLanguage = new Language(data, markdownParser, [], 'markdown');\n\nexport { markdownLanguage, headingFold };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport { parser } from '@lezer/html';\nimport { LRLanguage } from '@codemirror/language';\n\nconst htmlLanguage = LRLanguage.define({\n parser: parser.configure({\n dialect: 'noMatch',\n }),\n});\n\n// function elementName(doc: Text, tree: SyntaxNode | null | undefined, max = doc.length) {\n// if (!tree) return ''\n// let tag = tree.firstChild\n// let name = tag && tag.getChild('TagName')\n// return name ? doc.sliceString(name.from, Math.min(name.to, max)) : ''\n// }\n\n// const selfClosers = new Set(\n// 'area base br col command embed frame hr img input keygen link meta param source track wbr menuitem'\n// .split(' ')\n// )\n\n// const autoCloseTags = EditorView.inputHandler.of((view, from, to, text, insertTransaction) => {\n// if (\n// view.composing ||\n// view.state.readOnly ||\n// from != to ||\n// (text != '>' && text != '/')\n// ) {\n// return false\n// }\n\n// const base = insertTransaction(), { state } = base\n\n// if (!htmlLanguage.isActiveAt(state, from, -1)) {\n// return false\n// }\n\n// const closeTags = state.changeByRange(range => {\n// const didType = state.doc.sliceString(range.from - 1, range.to) == text\n// const { head } = range\n// const after = syntaxTree(state).resolveInner(head, -1)\n// let name\n\n// if (didType && text == '>' && after.name == 'EndTag') {\n// const tag = after.parent!\n// if (\n// (name = elementName(state.doc, tag.parent, head)) &&\n// !selfClosers.has(name)) {\n// const to = head + (state.doc.sliceString(head, head + 1) === '>' ? 1 : 0)\n// const insert = `</${name}>`\n// return { range, changes: { from: head, to, insert } }\n// }\n// } else if (didType && text == '/' && after.name == 'IncompleteCloseTag') {\n// const tag = after.parent!\n// if (after.from == head - 2 && tag.lastChild?.name != 'CloseTag' &&\n// (name = elementName(state.doc, tag, head)) && !selfClosers.has(name)) {\n// const to = head + (state.doc.sliceString(head, head + 1) === '>' ? 1 : 0)\n// const insert = `${name}>`\n// return {\n// range: EditorSelection.cursor(head + insert.length, -1),\n// changes: { from: head, to, insert }\n// }\n// }\n// }\n// return { range }\n// })\n// if (closeTags.changes.empty) return false\n// view.dispatch([\n// base,\n// state.update(closeTags, {\n// userEvent: 'input.complete',\n// scrollIntoView: true\n// })\n// ])\n// return true\n// })\n\nexport { htmlLanguage };\n"],"mappings":"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","names":["import_extensions","import_core_plugins","import_language","import_common","import_language","import_language","jinjaParser"]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@coze-editor/preset-prompt",
3
+ "version": "0.1.0-alpha.0fd19e",
4
+ "description": "preset-prompt",
5
+ "license": "MIT",
6
+ "author": "fengzilong",
7
+ "maintainers": [],
8
+ "sideEffects": [
9
+ "**/*.css",
10
+ "**/*.less",
11
+ "**/*.sass",
12
+ "**/*.scss"
13
+ ],
14
+ "main": "./dist/esm/index.js",
15
+ "module": "./dist/esm/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsup",
22
+ "dev": "vite --force",
23
+ "lint": "eslint && tsc --noEmit"
24
+ },
25
+ "dependencies": {
26
+ "@codemirror/autocomplete": "^6.18.0",
27
+ "@codemirror/language": "^6.10.1",
28
+ "@coze-editor/core": "0.1.0-alpha.0fd19e",
29
+ "@coze-editor/core-plugins": "0.1.0-alpha.0fd19e",
30
+ "@coze-editor/extensions": "0.1.0-alpha.0fd19e",
31
+ "@coze-editor/lezer-parser-jinja2": "0.1.0-alpha.0fd19e",
32
+ "@coze-editor/preset-expression": "0.1.0-alpha.0fd19e",
33
+ "@lezer/common": "^1.2.2",
34
+ "@lezer/html": "^1.3.10",
35
+ "@lezer/markdown": "^1.3.1"
36
+ },
37
+ "devDependencies": {
38
+ "@codemirror/state": "^6.4.1",
39
+ "@codemirror/view": "^6.26.1",
40
+ "@coze-arch/ts-config": "workspace:*",
41
+ "@coze-editor/eslint-config": "workspace:*",
42
+ "@types/node": "^22",
43
+ "eslint": "9.14.0",
44
+ "tsup": "^8.0.1",
45
+ "typescript": "^5.8.2"
46
+ },
47
+ "peerDependencies": {
48
+ "@codemirror/state": "^6.4.1",
49
+ "@codemirror/view": "^6.26.1"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public",
53
+ "registry": "https://registry.npmjs.org"
54
+ },
55
+ "test:main": "./src/index.ts"
56
+ }