@type32/codemirror-rich-obsidian-editor 0.0.3

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.
Files changed (84) hide show
  1. package/README.md +99 -0
  2. package/dist/module.d.mts +8 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +25 -0
  5. package/dist/runtime/assets/css/editor.css +1 -0
  6. package/dist/runtime/components/Editor/ImageEmbedComponent.vue +11 -0
  7. package/dist/runtime/components/Editor/ImageEmbedComponent.vue.d.ts +5 -0
  8. package/dist/runtime/components/Editor/TestCustomCodeBlock.vue +16 -0
  9. package/dist/runtime/components/Editor/TestCustomCodeBlock.vue.d.ts +5 -0
  10. package/dist/runtime/components/Editor.client.vue +182 -0
  11. package/dist/runtime/components/Editor.client.vue.d.ts +23 -0
  12. package/dist/runtime/editor/lezer-parsers/customOFMParsers.d.ts +1 -0
  13. package/dist/runtime/editor/lezer-parsers/customOFMParsers.js +23 -0
  14. package/dist/runtime/editor/lezer-parsers/lezerCalloutParser.d.ts +8 -0
  15. package/dist/runtime/editor/lezer-parsers/lezerCalloutParser.js +53 -0
  16. package/dist/runtime/editor/lezer-parsers/lezerHashtagParser.d.ts +6 -0
  17. package/dist/runtime/editor/lezer-parsers/lezerHashtagParser.js +35 -0
  18. package/dist/runtime/editor/lezer-parsers/lezerIndentationParser.d.ts +4 -0
  19. package/dist/runtime/editor/lezer-parsers/lezerIndentationParser.js +23 -0
  20. package/dist/runtime/editor/lezer-parsers/lezerInternalLinkParser.d.ts +10 -0
  21. package/dist/runtime/editor/lezer-parsers/lezerInternalLinkParser.js +110 -0
  22. package/dist/runtime/editor/lezer-parsers/lezerLatexParser.d.ts +7 -0
  23. package/dist/runtime/editor/lezer-parsers/lezerLatexParser.js +75 -0
  24. package/dist/runtime/editor/lezer-parsers/lezerYamlFrontmatterParser.d.ts +13 -0
  25. package/dist/runtime/editor/lezer-parsers/lezerYamlFrontmatterParser.js +55 -0
  26. package/dist/runtime/editor/plugins/codemirror-editor-plugins/customBracketClosingPlugin.d.ts +4 -0
  27. package/dist/runtime/editor/plugins/codemirror-editor-plugins/customBracketClosingPlugin.js +94 -0
  28. package/dist/runtime/editor/plugins/codemirror-editor-plugins/editorAttributesPlugin.d.ts +8 -0
  29. package/dist/runtime/editor/plugins/codemirror-editor-plugins/editorAttributesPlugin.js +136 -0
  30. package/dist/runtime/editor/plugins/codemirror-editor-plugins/editorInternalLinkAutocompletePlugin.d.ts +1 -0
  31. package/dist/runtime/editor/plugins/codemirror-editor-plugins/editorInternalLinkAutocompletePlugin.js +43 -0
  32. package/dist/runtime/editor/plugins/codemirror-editor-plugins/editorKeymapPlugin.d.ts +1 -0
  33. package/dist/runtime/editor/plugins/codemirror-editor-plugins/editorKeymapPlugin.js +95 -0
  34. package/dist/runtime/editor/plugins/codemirror-editor-plugins/editorLinkClickPlugin.d.ts +1 -0
  35. package/dist/runtime/editor/plugins/codemirror-editor-plugins/editorLinkClickPlugin.js +43 -0
  36. package/dist/runtime/editor/plugins/codemirror-editor-plugins/indentationGuidesPlugin.d.ts +10 -0
  37. package/dist/runtime/editor/plugins/codemirror-editor-plugins/indentationGuidesPlugin.js +121 -0
  38. package/dist/runtime/editor/plugins/codemirror-editor-plugins/indentationListPlugin.d.ts +5 -0
  39. package/dist/runtime/editor/plugins/codemirror-editor-plugins/indentationListPlugin.js +66 -0
  40. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseCalloutPlugin.d.ts +3 -0
  41. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseCalloutPlugin.js +63 -0
  42. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseCodeBlockCodemirrorViewPlugin.d.ts +3 -0
  43. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseCodeBlockCodemirrorViewPlugin.js +98 -0
  44. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseHashtagCodemirrorViewPlugin.d.ts +3 -0
  45. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseHashtagCodemirrorViewPlugin.js +27 -0
  46. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseHighlightCodemirrorViewPlugin.d.ts +3 -0
  47. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseHighlightCodemirrorViewPlugin.js +51 -0
  48. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseInternalLinkCodemirrorViewPlugin.d.ts +6 -0
  49. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseInternalLinkCodemirrorViewPlugin.js +112 -0
  50. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseLatexCodemirrorViewPlugin.d.ts +2 -0
  51. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseLatexCodemirrorViewPlugin.js +160 -0
  52. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseLinkCodemirrorViewPlugin.d.ts +3 -0
  53. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseLinkCodemirrorViewPlugin.js +98 -0
  54. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseQuoteblockCodemirrorViewPlugin.d.ts +3 -0
  55. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseQuoteblockCodemirrorViewPlugin.js +76 -0
  56. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseTaskListPlugin.d.ts +8 -0
  57. package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseTaskListPlugin.js +106 -0
  58. package/dist/runtime/editor/plugins/codemirror-widgets/proseCalloutWidget.d.ts +13 -0
  59. package/dist/runtime/editor/plugins/codemirror-widgets/proseCalloutWidget.js +87 -0
  60. package/dist/runtime/editor/plugins/codemirror-widgets/proseCodeBlockWidgets.d.ts +15 -0
  61. package/dist/runtime/editor/plugins/codemirror-widgets/proseCodeBlockWidgets.js +53 -0
  62. package/dist/runtime/editor/plugins/codemirror-widgets/proseLatexWidgets.d.ts +11 -0
  63. package/dist/runtime/editor/plugins/codemirror-widgets/proseLatexWidgets.js +50 -0
  64. package/dist/runtime/editor/plugins/codemirror-widgets/proseVueComponentEmbedWidget.d.ts +12 -0
  65. package/dist/runtime/editor/plugins/codemirror-widgets/proseVueComponentEmbedWidget.js +32 -0
  66. package/dist/runtime/editor/plugins/customBracketClosingConfig.d.ts +2 -0
  67. package/dist/runtime/editor/plugins/customBracketClosingConfig.js +4 -0
  68. package/dist/runtime/editor/plugins/lezerStylesHighlightingPlugin.d.ts +3 -0
  69. package/dist/runtime/editor/plugins/lezerStylesHighlightingPlugin.js +55 -0
  70. package/dist/runtime/editor/plugins/linkMappingConfig.d.ts +3 -0
  71. package/dist/runtime/editor/plugins/linkMappingConfig.js +4 -0
  72. package/dist/runtime/editor/plugins/richTextPlugin.d.ts +10 -0
  73. package/dist/runtime/editor/plugins/richTextPlugin.js +94 -0
  74. package/dist/runtime/editor/plugins/specialCodeBlockMappingConfig.d.ts +3 -0
  75. package/dist/runtime/editor/plugins/specialCodeBlockMappingConfig.js +4 -0
  76. package/dist/runtime/editor/types/editor-types.d.ts +17 -0
  77. package/dist/runtime/editor/utility/decorations.d.ts +9 -0
  78. package/dist/runtime/editor/utility/decorations.js +9 -0
  79. package/dist/runtime/editor/utility/tools.d.ts +12 -0
  80. package/dist/runtime/editor/utility/tools.js +32 -0
  81. package/dist/runtime/editor/wysiwyg.d.ts +4 -0
  82. package/dist/runtime/editor/wysiwyg.js +80 -0
  83. package/dist/types.d.mts +3 -0
  84. package/package.json +80 -0
@@ -0,0 +1,110 @@
1
+ import { Tag } from "@lezer/highlight";
2
+ export const lezerHighlightEmbed = Tag.define("Embed");
3
+ export const lezerHighlightEmbedMark = Tag.define("EmbedMark");
4
+ export const lezerHighlightInternalLink = Tag.define("InternalLink");
5
+ export const lezerHighlightInternalMark = Tag.define("InternalMark", lezerHighlightInternalLink);
6
+ export const lezerHighlightInternalPath = Tag.define("InternalPath", lezerHighlightInternalLink);
7
+ export const lezerHighlightInternalSubpath = Tag.define("InternalSubpath", lezerHighlightInternalLink);
8
+ export const lezerHighlightInternalDisplay = Tag.define("InternalDisplay", lezerHighlightInternalLink);
9
+ export const lezerInternalLinkParser = {
10
+ defineNodes: [
11
+ { name: "Embed", style: lezerHighlightEmbed },
12
+ { name: "EmbedMark", style: lezerHighlightEmbedMark },
13
+ // For "!"
14
+ { name: "InternalLink", style: lezerHighlightInternalLink },
15
+ // For [[link]] itself
16
+ { name: "InternalMark", style: lezerHighlightInternalMark },
17
+ // For "[[" and "]]" and "|"
18
+ { name: "InternalPath", style: lezerHighlightInternalPath },
19
+ // For "link" part
20
+ { name: "InternalSubpath", style: lezerHighlightInternalSubpath },
21
+ // For "#subpath" part
22
+ { name: "InternalDisplay", style: lezerHighlightInternalDisplay }
23
+ // For "alias" part
24
+ ],
25
+ parseInline: [
26
+ {
27
+ name: "InternalLink",
28
+ parse(cx, _, pos) {
29
+ const el = parseInternalLink(cx, pos);
30
+ if (el) {
31
+ return cx.addElement(el);
32
+ }
33
+ return -1;
34
+ },
35
+ before: "Link"
36
+ },
37
+ {
38
+ name: "Embed",
39
+ parse(cx, next, pos) {
40
+ if (next != 33) {
41
+ return -1;
42
+ }
43
+ const linkElement = parseInternalLink(cx, pos + 1);
44
+ if (linkElement) {
45
+ const embedMark = cx.elt("EmbedMark", pos, pos + 1);
46
+ return cx.addElement(
47
+ cx.elt("Embed", pos, linkElement.to, [embedMark, linkElement])
48
+ );
49
+ }
50
+ return -1;
51
+ },
52
+ before: "Image"
53
+ // Parse before standard images ![]()
54
+ }
55
+ ]
56
+ };
57
+ function parseInternalLink(cx, pos) {
58
+ if (cx.char(pos) != 91 || cx.char(pos + 1) != 91) {
59
+ return null;
60
+ }
61
+ let endMarkerPos = -1;
62
+ for (let i = pos + 2; i < cx.end - 1; i++) {
63
+ if (cx.char(i) === 93 && cx.char(i + 1) === 93) {
64
+ if (i === pos + 2) return null;
65
+ endMarkerPos = i;
66
+ break;
67
+ }
68
+ if (cx.char(i) === 91 && cx.char(i + 1) === 91) {
69
+ return null;
70
+ }
71
+ }
72
+ if (endMarkerPos === -1) return null;
73
+ const children = [];
74
+ children.push(cx.elt("InternalMark", pos, pos + 2));
75
+ let currentPos = pos + 2;
76
+ let pathEnd = endMarkerPos;
77
+ const pipePos = cx.slice(currentPos, endMarkerPos).indexOf("|");
78
+ if (pipePos !== -1) {
79
+ pathEnd = currentPos + pipePos;
80
+ }
81
+ const pathText = cx.slice(currentPos, pathEnd).trim();
82
+ if (pathText.length > 0) {
83
+ const hashPos = pathText.indexOf("#");
84
+ if (hashPos !== -1) {
85
+ const mainPath = pathText.substring(0, hashPos);
86
+ const subPath = pathText.substring(hashPos);
87
+ if (mainPath.length > 0) {
88
+ children.push(cx.elt("InternalPath", currentPos, currentPos + mainPath.length));
89
+ }
90
+ if (subPath.length > 0) {
91
+ children.push(cx.elt("InternalSubpath", currentPos + mainPath.length, currentPos + pathText.length));
92
+ }
93
+ } else {
94
+ children.push(cx.elt("InternalPath", currentPos, currentPos + pathText.length));
95
+ }
96
+ }
97
+ currentPos = pathEnd;
98
+ if (pipePos !== -1 && currentPos < endMarkerPos) {
99
+ children.push(cx.elt("InternalMark", currentPos, currentPos + 1));
100
+ currentPos += 1;
101
+ const displayText = cx.slice(currentPos, endMarkerPos).trim();
102
+ if (displayText.length > 0) {
103
+ children.push(cx.elt("InternalDisplay", currentPos, currentPos + displayText.length));
104
+ }
105
+ currentPos += displayText.length;
106
+ }
107
+ children.push(cx.elt("InternalMark", endMarkerPos, endMarkerPos + 2));
108
+ if (children.length <= 2) return null;
109
+ return cx.elt("InternalLink", pos, endMarkerPos + 2, children);
110
+ }
@@ -0,0 +1,7 @@
1
+ import type { MarkdownConfig } from '@lezer/markdown';
2
+ import { Tag } from "@lezer/highlight";
3
+ export declare const lezerHighlightLatex: Tag;
4
+ export declare const lezerHighlightLatexBlock: Tag;
5
+ export declare const lezerHighlightLatexInline: Tag;
6
+ export declare const lezerHighlightLatexMarker: Tag;
7
+ export declare const lezerLatexParser: MarkdownConfig;
@@ -0,0 +1,75 @@
1
+ import { Tag } from "@lezer/highlight";
2
+ const TexDelim = { resolve: "TexInline", mark: "TexMarker" };
3
+ export const lezerHighlightLatex = Tag.define("Tex");
4
+ export const lezerHighlightLatexBlock = Tag.define("TexBlock");
5
+ export const lezerHighlightLatexInline = Tag.define("TexInline");
6
+ export const lezerHighlightLatexMarker = Tag.define("TexMarker");
7
+ export const lezerLatexParser = {
8
+ defineNodes: [
9
+ { name: "Tex", style: lezerHighlightLatex },
10
+ { name: "TexBlock", style: lezerHighlightLatexBlock },
11
+ { name: "TexInline", style: lezerHighlightLatexInline },
12
+ { name: "TexMarker", style: lezerHighlightLatexMarker }
13
+ ],
14
+ parseBlock: [
15
+ {
16
+ name: "TexBlock",
17
+ endLeaf: (_, line) => line.text.slice(line.pos, line.pos + 2) == "$$",
18
+ // Check for "$$" at line start
19
+ parse(cx, line) {
20
+ if (line.text.slice(line.pos, line.pos + 2) != "$$") {
21
+ return false;
22
+ }
23
+ const start = cx.lineStart + line.pos;
24
+ const markers = [cx.elt("TexMarker", start, start + 2)];
25
+ const regex = /(^|[^\\])\$\$/;
26
+ let remaining = line.text.slice(line.pos + 2);
27
+ let startOffset = 2;
28
+ let match;
29
+ while (!(match = regex.exec(remaining)) && cx.nextLine()) {
30
+ remaining = line.text;
31
+ startOffset = 0;
32
+ }
33
+ let end;
34
+ if (match) {
35
+ const lineEnd = match.index + match[0].length + startOffset;
36
+ end = cx.lineStart + lineEnd;
37
+ markers.push(cx.elt("TexMarker", end - 2, end));
38
+ if (lineEnd == line.text.length || /^\s*$/.test(line.text.slice(lineEnd))) {
39
+ cx.nextLine();
40
+ } else {
41
+ line.pos = line.skipSpace(lineEnd);
42
+ }
43
+ } else {
44
+ end = cx.lineStart + line.text.length;
45
+ }
46
+ cx.addElement(cx.elt("TexBlock", start, end, markers));
47
+ return true;
48
+ },
49
+ before: "FencedCode"
50
+ // Run before fenced code blocks
51
+ }
52
+ ],
53
+ parseInline: [
54
+ {
55
+ name: "TexInline",
56
+ parse(cx, next, pos) {
57
+ if (next != 36) {
58
+ return -1;
59
+ }
60
+ if (cx.char(pos + 1) == 36) return -1;
61
+ const before = cx.slice(pos - 1, pos);
62
+ const after = cx.slice(pos + 1, pos + 2);
63
+ let canOpen = !/\s/.test(after) && after !== "$";
64
+ let canClose = !/\s/.test(before) && before !== "$";
65
+ if (cx.char(pos - 1) === 32 && cx.char(pos + 1) === 32) {
66
+ canOpen = false;
67
+ canClose = false;
68
+ }
69
+ return cx.addDelimiter(TexDelim, pos, pos + 1, canOpen, canClose);
70
+ },
71
+ before: "Emphasis"
72
+ // Or "Escape"
73
+ }
74
+ ]
75
+ };
@@ -0,0 +1,13 @@
1
+ import type { Input } from "@lezer/common";
2
+ import type { MarkdownConfig } from '@lezer/markdown';
3
+ import { Tag } from "@lezer/highlight";
4
+ export declare const lezerHighlightYamlFrontmatter: Tag;
5
+ export declare const lezerHighlightYamlMarker: Tag;
6
+ export declare const lezerHighlightYamlContent: Tag;
7
+ declare module "@lezer/markdown" {
8
+ interface BlockContext {
9
+ readonly input: Input;
10
+ checkedYaml?: boolean | null;
11
+ }
12
+ }
13
+ export declare const lezerYamlFrontmatterParser: MarkdownConfig;
@@ -0,0 +1,55 @@
1
+ import { Tag } from "@lezer/highlight";
2
+ export const lezerHighlightYamlFrontmatter = Tag.define("YAMLFrontMatter");
3
+ export const lezerHighlightYamlMarker = Tag.define("YAMLMarker", lezerHighlightYamlFrontmatter);
4
+ export const lezerHighlightYamlContent = Tag.define("YAMLContent", lezerHighlightYamlFrontmatter);
5
+ export const lezerYamlFrontmatterParser = {
6
+ defineNodes: [
7
+ { name: "YAMLFrontMatter", style: lezerHighlightYamlFrontmatter },
8
+ { name: "YAMLMarker", style: lezerHighlightYamlMarker },
9
+ { name: "YAMLContent", style: lezerHighlightYamlContent }
10
+ ],
11
+ parseBlock: [
12
+ {
13
+ name: "YAMLFrontMatter",
14
+ parse(cx, line) {
15
+ if (!Object.prototype.hasOwnProperty.call(cx, "checkedYaml")) {
16
+ cx.checkedYaml = null;
17
+ }
18
+ if (cx.checkedYaml || cx.lineStart !== 0) {
19
+ return false;
20
+ }
21
+ cx.checkedYaml = true;
22
+ if (line.text.slice(line.pos) !== "---") {
23
+ return false;
24
+ }
25
+ const start = cx.lineStart + line.pos;
26
+ const markers = [cx.elt("YAMLMarker", start, start + 3)];
27
+ let contentStart = -1;
28
+ let contentEnd = -1;
29
+ let end = -1;
30
+ while (cx.nextLine()) {
31
+ if (contentStart === -1) contentStart = cx.lineStart;
32
+ const lineText = line.text.slice(line.pos);
33
+ if (lineText === "---" || lineText === "...") {
34
+ contentEnd = cx.lineStart - 1;
35
+ if (contentStart > contentEnd && contentStart !== -1) contentEnd = contentStart;
36
+ end = cx.lineStart + line.pos + 3;
37
+ markers.push(cx.elt("YAMLMarker", cx.lineStart + line.pos, end));
38
+ cx.nextLine();
39
+ break;
40
+ }
41
+ }
42
+ if (end === -1) return false;
43
+ if (contentStart !== -1 && contentEnd !== -1 && contentStart <= contentEnd) {
44
+ markers.splice(1, 0, cx.elt("YAMLContent", contentStart, contentEnd));
45
+ } else if (contentStart !== -1 && contentEnd === -1) {
46
+ contentEnd = cx.docLen;
47
+ markers.splice(1, 0, cx.elt("YAMLContent", contentStart, contentEnd));
48
+ }
49
+ cx.addElement(cx.elt("YAMLFrontMatter", start, end, markers));
50
+ return true;
51
+ },
52
+ before: "LinkReference"
53
+ }
54
+ ]
55
+ };
@@ -0,0 +1,4 @@
1
+ import { ViewPlugin, type ViewUpdate } from '@codemirror/view';
2
+ export declare const customBracketClosingPlugin: ViewPlugin<{
3
+ update(update: ViewUpdate): void;
4
+ }, undefined>;
@@ -0,0 +1,94 @@
1
+ import { ViewPlugin } from "@codemirror/view";
2
+ import { EditorSelection } from "@codemirror/state";
3
+ import { customBracketClosingConfig } from "../customBracketClosingConfig.js";
4
+ const bracketMap = {
5
+ "(": ")",
6
+ "{": "}",
7
+ "'": "'",
8
+ '"': '"',
9
+ "[": "]"
10
+ };
11
+ const bracketClosingEventHandlers = {
12
+ keydown(event, view) {
13
+ if (!view.state.facet(customBracketClosingConfig)) return false;
14
+ if (bracketMap[event.key]) {
15
+ const closingBracket = bracketMap[event.key];
16
+ const { state, dispatch } = view;
17
+ const { selection } = state;
18
+ if (selection.ranges.length > 1) return false;
19
+ const range = selection.main;
20
+ if (!range.empty) {
21
+ const selectedText = state.doc.sliceString(range.from, range.to);
22
+ const changes2 = {
23
+ from: range.from,
24
+ to: range.to,
25
+ insert: `${event.key}${selectedText}${closingBracket}`
26
+ };
27
+ dispatch(
28
+ state.update({
29
+ changes: changes2,
30
+ selection: EditorSelection.range(range.from + 1, range.to + 1),
31
+ userEvent: "input.type"
32
+ })
33
+ );
34
+ event.preventDefault();
35
+ return true;
36
+ }
37
+ const charAfter = state.doc.sliceString(range.from, range.from + 1);
38
+ if (charAfter === closingBracket) {
39
+ dispatch(
40
+ state.update({
41
+ selection: { anchor: range.from + 1 },
42
+ userEvent: "input.type"
43
+ })
44
+ );
45
+ event.preventDefault();
46
+ return true;
47
+ }
48
+ const changes = {
49
+ from: range.from,
50
+ insert: `${event.key}${closingBracket}`
51
+ };
52
+ dispatch(
53
+ state.update({
54
+ changes,
55
+ selection: { anchor: range.from + 1 },
56
+ userEvent: "input.type"
57
+ })
58
+ );
59
+ event.preventDefault();
60
+ return true;
61
+ }
62
+ if (event.key === "Backspace") {
63
+ if (!view.state.facet(customBracketClosingConfig)) return false;
64
+ const { state, dispatch } = view;
65
+ const { selection } = state;
66
+ if (selection.ranges.length > 1 || !selection.main.empty) return false;
67
+ const range = selection.main;
68
+ const charBefore = state.doc.sliceString(range.from - 1, range.from);
69
+ const charAfter = state.doc.sliceString(range.from, range.from + 1);
70
+ if (bracketMap[charBefore] === charAfter) {
71
+ dispatch(
72
+ state.update({
73
+ changes: { from: range.from - 1, to: range.from + 1, insert: "" },
74
+ userEvent: "delete.backward"
75
+ })
76
+ );
77
+ event.preventDefault();
78
+ return true;
79
+ }
80
+ }
81
+ return false;
82
+ }
83
+ };
84
+ export const customBracketClosingPlugin = ViewPlugin.fromClass(
85
+ class {
86
+ constructor(view) {
87
+ }
88
+ update(update) {
89
+ }
90
+ },
91
+ {
92
+ eventHandlers: bracketClosingEventHandlers
93
+ }
94
+ );
@@ -0,0 +1,8 @@
1
+ import { EditorView, type DecorationSet, ViewUpdate, ViewPlugin } from '@codemirror/view';
2
+ declare const editorAttributesPlugin: ViewPlugin<{
3
+ decorations: DecorationSet;
4
+ update(update: ViewUpdate): void;
5
+ destroy(): void;
6
+ buildDecorations(view: EditorView): DecorationSet;
7
+ }, undefined>;
8
+ export { editorAttributesPlugin };
@@ -0,0 +1,136 @@
1
+ import { RangeSetBuilder } from "@codemirror/state";
2
+ import { EditorView, Decoration, WidgetType, ViewPlugin } from "@codemirror/view";
3
+ import { EditorSelection } from "@codemirror/state";
4
+ import { syntaxTree, foldable, foldEffect, unfoldEffect, foldedRanges } from "@codemirror/language";
5
+ class FoldWidget extends WidgetType {
6
+ isFolded;
7
+ isHeader;
8
+ constructor(isFolded, isHeader = false) {
9
+ super();
10
+ this.isFolded = isFolded;
11
+ this.isHeader = isHeader;
12
+ }
13
+ eq(other) {
14
+ return other.isFolded == this.isFolded;
15
+ }
16
+ toDOM() {
17
+ let el = document.createElement("div");
18
+ el.className = "cm-fold-widget collapse-indicator collapse-icon";
19
+ if (this.isFolded) el.classList.add("is-collapsed");
20
+ this.isHeader ? el.classList.add("heading-collapse-indicator") : el.classList.add("list-collapse-indicator");
21
+ const icon = document.createElement("span");
22
+ icon.innerText = "\u25B8";
23
+ icon.style.cursor = "pointer";
24
+ icon.style.transform = this.isFolded ? "rotate(0deg)" : "rotate(90deg)";
25
+ el.appendChild(icon);
26
+ return el;
27
+ }
28
+ ignoreEvent() {
29
+ return false;
30
+ }
31
+ }
32
+ function foldExists(state, from, to) {
33
+ const folded = foldedRanges(state);
34
+ let found = false;
35
+ folded.between(from, from, (a, b) => {
36
+ if (a == from && b == to) found = true;
37
+ });
38
+ return found;
39
+ }
40
+ function announceFold(view, range, fold = true) {
41
+ let lineFrom = view.state.doc.lineAt(range.from).number, lineTo = view.state.doc.lineAt(range.to).number;
42
+ return EditorView.announce.of(
43
+ `${view.state.phrase(fold ? "Folded lines" : "Unfolded lines")} ${lineFrom} ${view.state.phrase(
44
+ "to"
45
+ )} ${lineTo}.`
46
+ );
47
+ }
48
+ const editorAttributesPlugin = ViewPlugin.fromClass(
49
+ class {
50
+ decorations;
51
+ constructor(view) {
52
+ this.decorations = this.buildDecorations(view);
53
+ }
54
+ update(update) {
55
+ if (update.docChanged || update.viewportChanged || update.selectionSet) {
56
+ this.decorations = this.buildDecorations(update.view);
57
+ } else if (update.geometryChanged) {
58
+ for (let tr of update.transactions) {
59
+ for (let effect of tr.effects) {
60
+ if (effect && effect.value) {
61
+ if (effect.is(foldEffect) || effect.is(unfoldEffect)) {
62
+ this.decorations = this.buildDecorations(update.view);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
69
+ destroy() {
70
+ }
71
+ buildDecorations(view) {
72
+ const hashTagRegexp = /#(?:[^\u2000-\u206F\u2E00-\u2E7F'!"#$%&()*+,.:;<=>?@^`{|}~\[\]\\\s])+/g;
73
+ let builder = new RangeSetBuilder();
74
+ const processedLinesForTags = /* @__PURE__ */ new Set();
75
+ for (let { from, to } of view.visibleRanges) {
76
+ syntaxTree(view.state).iterate({
77
+ from,
78
+ to,
79
+ enter: (node) => {
80
+ const isHeader = node.name.startsWith("ATXHeading");
81
+ const isList = node.name === "ListItem";
82
+ if (isList || isHeader) {
83
+ let range, line = view.state.doc.lineAt(node.from);
84
+ if (range = foldable(view.state, line.from, line.to)) {
85
+ const isFolded = foldExists(view.state, range.from, range.to);
86
+ let deco = Decoration.widget({
87
+ widget: new FoldWidget(isFolded, isHeader)
88
+ });
89
+ builder.add(node.from, node.from, deco);
90
+ }
91
+ }
92
+ if (node.name === "HashtagTag") {
93
+ const line = view.state.doc.lineAt(node.from);
94
+ if (!processedLinesForTags.has(line.number)) {
95
+ const tags = line.text.match(hashTagRegexp);
96
+ if (tags) {
97
+ const tagAttribute = tags.join(" ").replace(/#/g, "");
98
+ let deco = Decoration.line({
99
+ attributes: { "data-tags": tagAttribute }
100
+ });
101
+ builder.add(line.from, line.from, deco);
102
+ }
103
+ processedLinesForTags.add(line.number);
104
+ }
105
+ }
106
+ }
107
+ });
108
+ }
109
+ return builder.finish();
110
+ }
111
+ },
112
+ {
113
+ decorations: (v) => v.decorations,
114
+ eventHandlers: {
115
+ mousedown: (e, view) => {
116
+ let target = e.target.closest(".cm-fold-widget");
117
+ if (target) {
118
+ const foldMarkerPos = view.posAtDOM(target);
119
+ const line = view.state.doc.lineAt(foldMarkerPos);
120
+ let range = foldable(view.state, line.from, line.to);
121
+ if (range) {
122
+ let curPos = view.state.selection.main.head;
123
+ let effect = foldExists(view.state, range.from, range.to) ? unfoldEffect : foldEffect;
124
+ let transaction = { effects: effect.of(range) };
125
+ if (curPos >= range.from && curPos <= range.to) {
126
+ transaction.selection = EditorSelection.cursor(range.to);
127
+ }
128
+ view.dispatch(transaction);
129
+ return true;
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
135
+ );
136
+ export { editorAttributesPlugin };
@@ -0,0 +1 @@
1
+ export declare const editorInternalLinkAutocompletePlugin: import("@codemirror/state").Extension;
@@ -0,0 +1,43 @@
1
+ import { autocompletion } from "@codemirror/autocomplete";
2
+ import { syntaxTree } from "@codemirror/language";
3
+ import { internalLinkMapFacet } from "../linkMappingConfig.js";
4
+ function internalLinkSource(context) {
5
+ const node = syntaxTree(context.state).resolve(context.pos, -1);
6
+ let textBefore = context.state.sliceDoc(node.from, context.pos);
7
+ let from = node.from;
8
+ if (node.name !== "InternalLink" && node.name !== "InternalPath") {
9
+ const precursor = context.state.sliceDoc(context.pos - 2, context.pos);
10
+ if (precursor === "[[") {
11
+ textBefore = "";
12
+ from = context.pos;
13
+ } else {
14
+ return null;
15
+ }
16
+ } else {
17
+ from = node.from;
18
+ if (node.name === "InternalLink") {
19
+ const pathNode = node.node.getChild("InternalPath");
20
+ if (pathNode) {
21
+ from = pathNode.from;
22
+ } else {
23
+ from = context.pos;
24
+ }
25
+ }
26
+ }
27
+ const linkMap = context.state.facet(internalLinkMapFacet);
28
+ const options = linkMap.filter((link) => link.internalLinkName.toLowerCase().includes(textBefore.toLowerCase())).map((link) => ({
29
+ label: link.internalLinkName,
30
+ detail: link.redirectToPath,
31
+ apply: `${link.internalLinkName}`
32
+ }));
33
+ if (options.length === 0) return null;
34
+ return {
35
+ from,
36
+ options,
37
+ validFor: /^[\w\s]*$/
38
+ };
39
+ }
40
+ export const editorInternalLinkAutocompletePlugin = autocompletion({
41
+ override: [internalLinkSource],
42
+ icons: false
43
+ });
@@ -0,0 +1 @@
1
+ export declare const editorKeymapPlugin: import("@codemirror/state").Extension;
@@ -0,0 +1,95 @@
1
+ import { keymap } from "@codemirror/view";
2
+ import { EditorSelection } from "@codemirror/state";
3
+ import { completionKeymap } from "@codemirror/autocomplete";
4
+ const toggleMarkdownFormatting = (mark) => {
5
+ return (view) => {
6
+ const { state, dispatch } = view;
7
+ const { selection } = state;
8
+ if (selection.ranges.length === 0) {
9
+ return false;
10
+ }
11
+ const transactions = selection.ranges.map((range) => {
12
+ if (range.empty) {
13
+ const { from } = range;
14
+ const word = state.wordAt(from);
15
+ if (word) {
16
+ const wordText = state.doc.sliceString(word.from, word.to);
17
+ const textBeforeWord = state.doc.sliceString(word.from - mark.length, word.from);
18
+ const textAfterWord = state.doc.sliceString(word.to, word.to + mark.length);
19
+ if (textBeforeWord === mark && textAfterWord === mark) {
20
+ return state.update({
21
+ changes: [
22
+ { from: word.from - mark.length, to: word.from, insert: "" },
23
+ { from: word.to, to: word.to + mark.length, insert: "" }
24
+ ],
25
+ selection: { anchor: word.from - mark.length, head: word.to - mark.length }
26
+ });
27
+ }
28
+ return state.update({
29
+ changes: {
30
+ from: word.from,
31
+ to: word.to,
32
+ insert: `${mark}${wordText}${mark}`
33
+ },
34
+ selection: EditorSelection.range(word.from + mark.length, word.to + mark.length)
35
+ });
36
+ }
37
+ return state.update({
38
+ changes: { from, insert: `${mark}${mark}` },
39
+ selection: { anchor: from + mark.length }
40
+ });
41
+ } else {
42
+ const selectedText = state.doc.sliceString(range.from, range.to);
43
+ const textBefore = state.doc.sliceString(range.from - mark.length, range.from);
44
+ const textAfter = state.doc.sliceString(range.to, range.to + mark.length);
45
+ if (textBefore === mark && textAfter === mark) {
46
+ return state.update({
47
+ changes: [
48
+ { from: range.from - mark.length, to: range.from },
49
+ { from: range.to, to: range.to + mark.length }
50
+ ],
51
+ selection: { anchor: range.from - mark.length, head: range.to - mark.length }
52
+ });
53
+ } else {
54
+ return state.update({
55
+ changes: { from: range.from, to: range.to, insert: `${mark}${selectedText}${mark}` },
56
+ selection: { anchor: range.from + mark.length, head: range.to + mark.length }
57
+ });
58
+ }
59
+ }
60
+ });
61
+ const transaction = transactions.reduce((acc, tr) => {
62
+ if (!tr) return acc;
63
+ const changes = acc.changes.compose(tr.changes);
64
+ return {
65
+ changes,
66
+ selection: tr.selection ? tr.selection : acc.selection?.map(changes),
67
+ effects: acc.effects.concat(tr.effects)
68
+ };
69
+ }, state.update({}));
70
+ if (transaction.changes.empty) {
71
+ return false;
72
+ }
73
+ dispatch(state.update(transaction));
74
+ return true;
75
+ };
76
+ };
77
+ export const editorKeymapPlugin = keymap.of([
78
+ {
79
+ key: "Mod-b",
80
+ run: toggleMarkdownFormatting("**")
81
+ },
82
+ {
83
+ key: "Mod-i",
84
+ run: toggleMarkdownFormatting("*")
85
+ },
86
+ {
87
+ key: "Mod-Shift-x",
88
+ run: toggleMarkdownFormatting("~~")
89
+ },
90
+ {
91
+ key: "Mod-Shift-h",
92
+ run: toggleMarkdownFormatting("==")
93
+ },
94
+ ...completionKeymap
95
+ ]);
@@ -0,0 +1 @@
1
+ export declare const editorLinkClickPlugin: import("@codemirror/state").Extension;