codemirror-obsidian-md 0.0.0 → 0.2.0

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 (93) hide show
  1. package/README.md +114 -3
  2. package/dist/editor/editing/auto-pair.d.ts +24 -0
  3. package/dist/editor/editing/auto-pair.d.ts.map +1 -0
  4. package/dist/editor/editing/auto-pair.js +93 -0
  5. package/dist/editor/editing/auto-pair.js.map +1 -0
  6. package/dist/editor/editing/backspace.d.ts +14 -0
  7. package/dist/editor/editing/backspace.d.ts.map +1 -0
  8. package/dist/editor/editing/backspace.js +19 -0
  9. package/dist/editor/editing/backspace.js.map +1 -0
  10. package/dist/editor/editing/code-fence.d.ts +9 -0
  11. package/dist/editor/editing/code-fence.d.ts.map +1 -0
  12. package/dist/editor/editing/code-fence.js +36 -0
  13. package/dist/editor/editing/code-fence.js.map +1 -0
  14. package/dist/editor/editing/composition.d.ts +6 -0
  15. package/dist/editor/editing/composition.d.ts.map +1 -0
  16. package/dist/editor/editing/composition.js +5 -0
  17. package/dist/editor/editing/composition.js.map +1 -0
  18. package/dist/editor/editing/emphasis.d.ts +4 -0
  19. package/dist/editor/editing/emphasis.d.ts.map +1 -0
  20. package/dist/editor/editing/emphasis.js +68 -0
  21. package/dist/editor/editing/emphasis.js.map +1 -0
  22. package/dist/editor/editing/line-text.d.ts +6 -0
  23. package/dist/editor/editing/line-text.d.ts.map +1 -0
  24. package/dist/editor/editing/line-text.js +10 -0
  25. package/dist/editor/editing/line-text.js.map +1 -0
  26. package/dist/editor/editing/link.d.ts +6 -0
  27. package/dist/editor/editing/link.d.ts.map +1 -0
  28. package/dist/editor/editing/link.js +16 -0
  29. package/dist/editor/editing/link.js.map +1 -0
  30. package/dist/editor/editing/list-continuation.d.ts +9 -0
  31. package/dist/editor/editing/list-continuation.d.ts.map +1 -0
  32. package/dist/editor/editing/list-continuation.js +117 -0
  33. package/dist/editor/editing/list-continuation.js.map +1 -0
  34. package/dist/editor/editing/list-indent.d.ts +10 -0
  35. package/dist/editor/editing/list-indent.d.ts.map +1 -0
  36. package/dist/editor/editing/list-indent.js +163 -0
  37. package/dist/editor/editing/list-indent.js.map +1 -0
  38. package/dist/editor/editing/list-line.d.ts +28 -0
  39. package/dist/editor/editing/list-line.d.ts.map +1 -0
  40. package/dist/editor/editing/list-line.js +56 -0
  41. package/dist/editor/editing/list-line.js.map +1 -0
  42. package/dist/editor/editing/pairs.d.ts +7 -0
  43. package/dist/editor/editing/pairs.d.ts.map +1 -0
  44. package/dist/editor/editing/pairs.js +11 -0
  45. package/dist/editor/editing/pairs.js.map +1 -0
  46. package/dist/editor/editing/paste-url.d.ts +7 -0
  47. package/dist/editor/editing/paste-url.d.ts.map +1 -0
  48. package/dist/editor/editing/paste-url.js +37 -0
  49. package/dist/editor/editing/paste-url.js.map +1 -0
  50. package/dist/editor/editing/selection-wrap.d.ts +15 -0
  51. package/dist/editor/editing/selection-wrap.d.ts.map +1 -0
  52. package/dist/editor/editing/selection-wrap.js +30 -0
  53. package/dist/editor/editing/selection-wrap.js.map +1 -0
  54. package/dist/editor/editing/task-toggle.d.ts +4 -0
  55. package/dist/editor/editing/task-toggle.d.ts.map +1 -0
  56. package/dist/editor/editing/task-toggle.js +32 -0
  57. package/dist/editor/editing/task-toggle.js.map +1 -0
  58. package/dist/editor/editing/typing.d.ts +16 -0
  59. package/dist/editor/editing/typing.d.ts.map +1 -0
  60. package/dist/editor/editing/typing.js +52 -0
  61. package/dist/editor/editing/typing.js.map +1 -0
  62. package/dist/editor/editing-shortcuts.d.ts +25 -0
  63. package/dist/editor/editing-shortcuts.d.ts.map +1 -0
  64. package/dist/editor/editing-shortcuts.js +67 -0
  65. package/dist/editor/editing-shortcuts.js.map +1 -0
  66. package/dist/editor/index.d.ts +1 -0
  67. package/dist/editor/index.d.ts.map +1 -1
  68. package/dist/editor/index.js +1 -0
  69. package/dist/editor/index.js.map +1 -1
  70. package/dist/editor/mount.d.ts.map +1 -1
  71. package/dist/editor/mount.js +2 -0
  72. package/dist/editor/mount.js.map +1 -1
  73. package/dist/editor/multi-cursor.d.ts +10 -0
  74. package/dist/editor/multi-cursor.d.ts.map +1 -0
  75. package/dist/editor/multi-cursor.js +28 -0
  76. package/dist/editor/multi-cursor.js.map +1 -0
  77. package/dist/editor/parse.js +34 -1
  78. package/dist/editor/parse.js.map +1 -1
  79. package/dist/editor/picker.d.ts +1 -0
  80. package/dist/editor/picker.d.ts.map +1 -1
  81. package/dist/editor/picker.js +4 -0
  82. package/dist/editor/picker.js.map +1 -1
  83. package/dist/editor/providers/callout-embed.d.ts.map +1 -1
  84. package/dist/editor/providers/callout-embed.js +55 -32
  85. package/dist/editor/providers/callout-embed.js.map +1 -1
  86. package/dist/editor/providers/inline.d.ts.map +1 -1
  87. package/dist/editor/providers/inline.js +22 -5
  88. package/dist/editor/providers/inline.js.map +1 -1
  89. package/dist/editor/providers/markdown.d.ts.map +1 -1
  90. package/dist/editor/providers/markdown.js +4 -2
  91. package/dist/editor/providers/markdown.js.map +1 -1
  92. package/dist/styles.css +313 -0
  93. package/package.json +5 -4
@@ -0,0 +1,117 @@
1
+ import { EditorSelection, Prec } from "@codemirror/state";
2
+ import { keymap } from "@codemirror/view";
3
+ import { isCrlf } from "../state.js";
4
+ import { plainBackspace } from "./backspace.js";
5
+ import { fencedLines } from "./code-fence.js";
6
+ import { isComposing } from "./composition.js";
7
+ import { contentEnd } from "./line-text.js";
8
+ import { indentListItem, unindentListItem } from "./list-indent.js";
9
+ import { continuationPrefix, parseListLine } from "./list-line.js";
10
+ /** The whitespace a line starts with, up to `pos`. */
11
+ function leadingIndent(state, pos) {
12
+ const line = state.doc.lineAt(pos);
13
+ return /^[ \t]*/.exec(line.text.slice(0, pos - line.from))?.[0] ?? "";
14
+ }
15
+ /** Enter continues the list item, quote or Callout line the cursor is on. */
16
+ const continueList = (view) => {
17
+ if (isComposing(view))
18
+ return false;
19
+ const { state } = view;
20
+ const crlf = isCrlf(state.doc.toString());
21
+ const lineBreak = crlf ? "\r\n" : "\n";
22
+ const fenced = fencedLines(state.doc);
23
+ const ranges = state.selection.ranges.map((range) => {
24
+ const line = state.doc.lineAt(range.from);
25
+ if (fenced.has(line.number))
26
+ return null;
27
+ const item = parseListLine(line.text);
28
+ return item && range.from - line.from >= item.contentStart ? item : null;
29
+ });
30
+ if (!ranges.some(Boolean))
31
+ return false;
32
+ let i = 0;
33
+ view.dispatch(state.update(state.changeByRange((range) => {
34
+ const item = ranges[i++];
35
+ if (item && !item.content.trim() && range.empty) {
36
+ const line = state.doc.lineAt(range.from);
37
+ const end = contentEnd(state, line.to);
38
+ return {
39
+ changes: { from: line.from, to: end, insert: "" },
40
+ range: EditorSelection.cursor(line.from),
41
+ };
42
+ }
43
+ // Off a list line the new line keeps the indentation, as the stock
44
+ // Enter does.
45
+ const prefix = item
46
+ ? continuationPrefix(item)
47
+ : leadingIndent(state, range.from);
48
+ const insert = lineBreak + prefix;
49
+ // A cursor past a CRLF line's `\r` goes before it.
50
+ const at = item && range.empty ? contentEnd(state, range.from) : range.from;
51
+ return {
52
+ changes: {
53
+ from: at,
54
+ to: range.empty ? at : range.to,
55
+ insert,
56
+ },
57
+ range: EditorSelection.cursor(at + insert.length),
58
+ };
59
+ }), { scrollIntoView: true, userEvent: "input" }));
60
+ return true;
61
+ };
62
+ /**
63
+ * Backspace after an empty marker removes the marker. With several cursors
64
+ * each range decides for itself; the others delete a character as usual.
65
+ */
66
+ const removeEmptyMarker = (view) => {
67
+ if (isComposing(view))
68
+ return false;
69
+ const { state } = view;
70
+ const fenced = fencedLines(state.doc);
71
+ const emptyLines = state.selection.ranges.map((range) => {
72
+ if (!range.empty)
73
+ return null;
74
+ const line = state.doc.lineAt(range.from);
75
+ if (fenced.has(line.number))
76
+ return null;
77
+ const item = parseListLine(line.text);
78
+ return item &&
79
+ !item.content.trim() &&
80
+ range.from >= contentEnd(state, line.to)
81
+ ? line
82
+ : null;
83
+ });
84
+ if (!emptyLines.some(Boolean))
85
+ return false;
86
+ let i = 0;
87
+ view.dispatch(state.update(state.changeByRange((range) => {
88
+ const line = emptyLines[i++];
89
+ if (!line)
90
+ return plainBackspace(state, range);
91
+ return {
92
+ changes: {
93
+ from: line.from,
94
+ to: contentEnd(state, line.to),
95
+ insert: "",
96
+ },
97
+ range: EditorSelection.cursor(line.from),
98
+ };
99
+ }), { scrollIntoView: true, userEvent: "delete.backward" }));
100
+ return true;
101
+ };
102
+ /**
103
+ * List continuation (Enter, Backspace), above the stock and CRLF Enter.
104
+ *
105
+ * Tab and Shift-Tab are registered here too, on purpose: they are part of the
106
+ * list behavior and have no key override of their own, so the
107
+ * `listContinuation` flag switches them off with Enter and Backspace (ADR 0016).
108
+ */
109
+ export function listContinuation() {
110
+ return Prec.highest(keymap.of([
111
+ { key: "Enter", run: continueList },
112
+ { key: "Backspace", run: removeEmptyMarker },
113
+ { key: "Tab", run: indentListItem },
114
+ { key: "Shift-Tab", run: unindentListItem },
115
+ ]));
116
+ }
117
+ //# sourceMappingURL=list-continuation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-continuation.js","sourceRoot":"","sources":["../../../src/editor/editing/list-continuation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Command } from "@codemirror/view";
2
+ /** Tab on a list item indents it. */
3
+ export declare const indentListItem: Command;
4
+ /** Shift-Tab on a list item unindents it. */
5
+ export declare const unindentListItem: Command;
6
+ /** Mod-] indents every selected line, list or not. */
7
+ export declare const indentSelection: Command;
8
+ /** Mod-[ unindents every selected line, list or not. */
9
+ export declare const unindentSelection: Command;
10
+ //# sourceMappingURL=list-indent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-indent.d.ts","sourceRoot":"","sources":["../../../src/editor/editing/list-indent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAc,MAAM,kBAAkB,CAAC;AAiJ5D,qCAAqC;AACrC,eAAO,MAAM,cAAc,EAAE,OAI5B,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB,EAAE,OAI9B,CAAC;AASF,sDAAsD;AACtD,eAAO,MAAM,eAAe,EAAE,OACc,CAAC;AAE7C,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,EAAE,OACa,CAAC"}
@@ -0,0 +1,163 @@
1
+ import { fencedLines } from "./code-fence.js";
2
+ import { isComposing } from "./composition.js";
3
+ import { parseListLine } from "./list-line.js";
4
+ /** One indent level, as Obsidian writes it. */
5
+ const INDENT = "\t";
6
+ /** The line numbers (1-based) the selection touches, in order. */
7
+ function touchedLines(state) {
8
+ const seen = new Set();
9
+ for (const range of state.selection.ranges) {
10
+ const first = state.doc.lineAt(range.from).number;
11
+ const last = state.doc.lineAt(range.to).number;
12
+ for (let n = first; n <= last; n++)
13
+ seen.add(n);
14
+ }
15
+ return [...seen].sort((a, b) => a - b);
16
+ }
17
+ /** The touched lines that are list items outside fenced code. */
18
+ function listItemLines(state) {
19
+ const fenced = fencedLines(state.doc);
20
+ return touchedLines(state).filter((n) => parseListLine(state.doc.line(n).text) && !fenced.has(n));
21
+ }
22
+ const LEADING = /^(?:\t| {1,4})/;
23
+ /** Columns of leading whitespace, a tab counting as four. */
24
+ function width(indent) {
25
+ let columns = 0;
26
+ for (const ch of indent)
27
+ columns += ch === "\t" ? 4 : 1;
28
+ return columns;
29
+ }
30
+ /** The indent width of a list line, `null` for any other line. */
31
+ function levelOf(line) {
32
+ const item = line === undefined ? null : parseListLine(line);
33
+ return item ? width(item.indent) : null;
34
+ }
35
+ /** Replaces the number of a numbered line, keeping the rest as written. */
36
+ function withNumber(line, number) {
37
+ return line.replace(/^([ \t]*)\d{1,9}/, `$1${number}`);
38
+ }
39
+ /**
40
+ * Renumbers the numbered run the item at `index` belongs to: the consecutive
41
+ * items at its indent, stepping over their deeper children. It counts up from
42
+ * the run's first number, or from 1 when that first item was just moved.
43
+ */
44
+ function renumberRun(lines, index, moved) {
45
+ const level = levelOf(lines[index]);
46
+ if (level === null)
47
+ return;
48
+ let top = index;
49
+ for (let i = index - 1; i >= 0; i--) {
50
+ const at = levelOf(lines[i]);
51
+ if (at === null || at < level)
52
+ break;
53
+ if (at === level) {
54
+ if (parseListLine(lines[i])?.kind !== "numbered")
55
+ break;
56
+ top = i;
57
+ }
58
+ }
59
+ const first = parseListLine(lines[top]);
60
+ if (first?.kind !== "numbered")
61
+ return;
62
+ let next = moved.has(top) ? 1 : (first.number ?? 1);
63
+ for (let i = top; i < lines.length; i++) {
64
+ const at = levelOf(lines[i]);
65
+ if (at === null || at < level)
66
+ break;
67
+ if (at > level)
68
+ continue;
69
+ if (parseListLine(lines[i])?.kind !== "numbered")
70
+ break;
71
+ lines[i] = withNumber(lines[i], next++);
72
+ }
73
+ }
74
+ /** The first line after `index` at `level`, past deeper lines; or -1. */
75
+ function followerAt(lines, index, level) {
76
+ for (let i = index + 1; i < lines.length; i++) {
77
+ const at = levelOf(lines[i]);
78
+ if (at === null || at < level)
79
+ return -1;
80
+ if (at === level)
81
+ return i;
82
+ }
83
+ return -1;
84
+ }
85
+ /** The edit turning `before` into `after`, trimmed to what differs. */
86
+ function lineEdit(from, before, after) {
87
+ let start = 0;
88
+ while (start < before.length &&
89
+ start < after.length &&
90
+ before[start] === after[start])
91
+ start++;
92
+ let end = 0;
93
+ while (end < before.length - start &&
94
+ end < after.length - start &&
95
+ before[before.length - 1 - end] === after[after.length - 1 - end])
96
+ end++;
97
+ return {
98
+ from: from + start,
99
+ to: from + before.length - end,
100
+ insert: after.slice(start, after.length - end),
101
+ };
102
+ }
103
+ /** Indents (`1`) or unindents (`-1`) the given lines, renumbering lists. */
104
+ function shiftLines(view, lineNumbers, direction) {
105
+ const { state } = view;
106
+ const before = state.doc.toString().split("\n");
107
+ const lines = [...before];
108
+ const moved = new Set();
109
+ const followers = [];
110
+ for (const n of lineNumbers) {
111
+ const i = n - 1;
112
+ const text = lines[i];
113
+ const oldLevel = levelOf(text) ?? width(/^[ \t]*/.exec(text)[0]);
114
+ if (direction === 1)
115
+ lines[i] = INDENT + text;
116
+ else
117
+ lines[i] = text.replace(LEADING, "");
118
+ if (lines[i] === text)
119
+ continue;
120
+ moved.add(i);
121
+ followers.push(followerAt(lines, i, oldLevel));
122
+ }
123
+ for (const i of followers)
124
+ if (i >= 0)
125
+ renumberRun(lines, i, moved);
126
+ for (const i of moved)
127
+ renumberRun(lines, i, moved);
128
+ const changes = [];
129
+ let from = 0;
130
+ for (let i = 0; i < lines.length; i++) {
131
+ if (lines[i] !== before[i])
132
+ changes.push(lineEdit(from, before[i], lines[i]));
133
+ from += before[i].length + 1;
134
+ }
135
+ if (changes.length)
136
+ view.dispatch(state.update({ changes, userEvent: "input.indent" }));
137
+ return true;
138
+ }
139
+ /** Tab on a list item indents it. */
140
+ export const indentListItem = (view) => {
141
+ if (isComposing(view))
142
+ return false;
143
+ const items = listItemLines(view.state);
144
+ return items.length > 0 && shiftLines(view, items, 1);
145
+ };
146
+ /** Shift-Tab on a list item unindents it. */
147
+ export const unindentListItem = (view) => {
148
+ if (isComposing(view))
149
+ return false;
150
+ const items = listItemLines(view.state);
151
+ return items.length > 0 && shiftLines(view, items, -1);
152
+ };
153
+ /** The touched lines that carry text, or the one line a cursor is on. */
154
+ function textLines(state) {
155
+ const lines = touchedLines(state);
156
+ const filled = lines.filter((n) => state.doc.line(n).text.trim());
157
+ return lines.length === 1 ? lines : filled;
158
+ }
159
+ /** Mod-] indents every selected line, list or not. */
160
+ export const indentSelection = (view) => shiftLines(view, textLines(view.state), 1);
161
+ /** Mod-[ unindents every selected line, list or not. */
162
+ export const unindentSelection = (view) => shiftLines(view, textLines(view.state), -1);
163
+ //# sourceMappingURL=list-indent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-indent.js","sourceRoot":"","sources":["../../../src/editor/editing/list-indent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /** What kind of list marker a line starts with. */
2
+ export type ListKind = "bullet" | "numbered" | "quote";
3
+ /** One line of a Note, split into its list parts. */
4
+ export interface ListLine {
5
+ kind: ListKind;
6
+ /** Leading whitespace. */
7
+ indent: string;
8
+ /** The marker as written: `-`, `*`, `+`, `1.`, `1)`, or `>` (nested: `> >`). */
9
+ marker: string;
10
+ /** The number of a numbered item, else `null`. */
11
+ number: number | null;
12
+ /** The task state char (` `, `x`, ...) of a `[ ]` item, else `null`. */
13
+ task: string | null;
14
+ /** Whitespace between the marker and what follows it. */
15
+ gap: string;
16
+ /** The text after the marker; empty for an empty item. */
17
+ content: string;
18
+ /** Offset in the line where `content` starts. */
19
+ contentStart: number;
20
+ }
21
+ /**
22
+ * Parses a line (without its line break) as a list item, quote or Callout
23
+ * line; `null` when it is none of them.
24
+ */
25
+ export declare function parseListLine(line: string): ListLine | null;
26
+ /** The prefix (indent, marker, task box) a continued line starts with. */
27
+ export declare function continuationPrefix(item: ListLine): string;
28
+ //# sourceMappingURL=list-line.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-line.d.ts","sourceRoot":"","sources":["../../../src/editor/editing/list-line.ts"],"names":[],"mappings":"AAEA,mDAAmD;AACnD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,qDAAqD;AACrD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,wEAAwE;IACxE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAsC3D;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAOzD"}
@@ -0,0 +1,56 @@
1
+ import { stripCr } from "./line-text.js";
2
+ const LIST = /^([ \t]*)(?:([-*+])|(\d{1,9})([.)]))([ \t]+)/;
3
+ const QUOTE = /^([ \t]*)((?:>[ \t]?)+)/;
4
+ const TASK = /^\[(.)\]([ \t]+|$)/;
5
+ /**
6
+ * Parses a line (without its line break) as a list item, quote or Callout
7
+ * line; `null` when it is none of them.
8
+ */
9
+ export function parseListLine(line) {
10
+ const text = stripCr(line);
11
+ const list = LIST.exec(text);
12
+ if (list) {
13
+ const [whole, indent = "", bullet, digits, delimiter, gap = ""] = list;
14
+ let contentStart = whole.length;
15
+ let task = null;
16
+ const box = TASK.exec(text.slice(contentStart));
17
+ if (box) {
18
+ task = box[1] ?? " ";
19
+ contentStart += box[0].length;
20
+ }
21
+ return {
22
+ kind: bullet ? "bullet" : "numbered",
23
+ indent,
24
+ marker: bullet ?? `${digits}${delimiter}`,
25
+ number: digits ? Number(digits) : null,
26
+ task,
27
+ gap,
28
+ content: text.slice(contentStart),
29
+ contentStart,
30
+ };
31
+ }
32
+ const quote = QUOTE.exec(text);
33
+ if (quote) {
34
+ const [whole, indent = "", markers = ""] = quote;
35
+ return {
36
+ kind: "quote",
37
+ indent,
38
+ marker: markers.trimEnd(),
39
+ number: null,
40
+ task: null,
41
+ gap: markers.slice(markers.trimEnd().length),
42
+ content: text.slice(whole.length),
43
+ contentStart: whole.length,
44
+ };
45
+ }
46
+ return null;
47
+ }
48
+ /** The prefix (indent, marker, task box) a continued line starts with. */
49
+ export function continuationPrefix(item) {
50
+ const marker = item.kind === "numbered"
51
+ ? `${(item.number ?? 0) + 1}${item.marker.slice(-1)}`
52
+ : item.marker;
53
+ const box = item.task === null ? "" : "[ ] ";
54
+ return `${item.indent}${marker}${item.gap || " "}${box}`;
55
+ }
56
+ //# sourceMappingURL=list-line.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-line.js","sourceRoot":"","sources":["../../../src/editor/editing/list-line.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAwBzC,MAAM,IAAI,GAAG,8CAA8C,CAAC;AAC5D,MAAM,KAAK,GAAG,yBAAyB,CAAC;AACxC,MAAM,IAAI,GAAG,oBAAoB,CAAC;AAElC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;QACvE,IAAI,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;QAChC,IAAI,IAAI,GAAkB,IAAI,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;QAChD,IAAI,GAAG,EAAE,CAAC;YACR,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;YACrB,YAAY,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAChC,CAAC;QACD,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU;YACpC,MAAM;YACN,MAAM,EAAE,MAAM,IAAI,GAAG,MAAM,GAAG,SAAS,EAAE;YACzC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;YACtC,IAAI;YACJ,GAAG;YACH,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;YACjC,YAAY;SACb,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;QACjD,OAAO;YACL,IAAI,EAAE,OAAO;YACb,MAAM;YACN,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE;YACzB,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC;YAC5C,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;YACjC,YAAY,EAAE,KAAK,CAAC,MAAM;SAC3B,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAAC,IAAc;IAC/C,MAAM,MAAM,GACV,IAAI,CAAC,IAAI,KAAK,UAAU;QACtB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;QACrD,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAClB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7C,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Bracket openers and their closers. Selection Wrap and Auto-pair both draw
3
+ * on this; quotes and the backtick close with themselves. Fixed, not
4
+ * configurable (ADR 0016).
5
+ */
6
+ export declare const BRACKET_CLOSERS: Readonly<Record<string, string>>;
7
+ //# sourceMappingURL=pairs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairs.d.ts","sourceRoot":"","sources":["../../../src/editor/editing/pairs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI5D,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Bracket openers and their closers. Selection Wrap and Auto-pair both draw
3
+ * on this; quotes and the backtick close with themselves. Fixed, not
4
+ * configurable (ADR 0016).
5
+ */
6
+ export const BRACKET_CLOSERS = {
7
+ "(": ")",
8
+ "[": "]",
9
+ "{": "}",
10
+ };
11
+ //# sourceMappingURL=pairs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairs.js","sourceRoot":"","sources":["../../../src/editor/editing/pairs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqC;IAC/D,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;CACT,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Pasting a single http(s) URL over selected text makes `[text](url)`. Empty
3
+ * ranges (several cursors) get the URL as plain text; with no selected range
4
+ * at all the paste is left to the browser.
5
+ */
6
+ export declare const pasteUrlAsLink: import("@codemirror/state").Extension;
7
+ //# sourceMappingURL=paste-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste-url.d.ts","sourceRoot":"","sources":["../../../src/editor/editing/paste-url.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,eAAO,MAAM,cAAc,uCA4BzB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { EditorSelection } from "@codemirror/state";
2
+ import { EditorView } from "@codemirror/view";
3
+ import { isComposing } from "./composition.js";
4
+ const URL_PATTERN = /^https?:\/\/\S+$/i;
5
+ /**
6
+ * Pasting a single http(s) URL over selected text makes `[text](url)`. Empty
7
+ * ranges (several cursors) get the URL as plain text; with no selected range
8
+ * at all the paste is left to the browser.
9
+ */
10
+ export const pasteUrlAsLink = EditorView.domEventHandlers({
11
+ paste(event, view) {
12
+ if (isComposing(view))
13
+ return false;
14
+ const url = event.clipboardData?.getData("text/plain").trim() ?? "";
15
+ if (!URL_PATTERN.test(url))
16
+ return false;
17
+ const { state } = view;
18
+ if (state.selection.ranges.every((range) => range.empty))
19
+ return false;
20
+ event.preventDefault();
21
+ view.dispatch(state.update(state.changeByRange((range) => {
22
+ if (range.empty) {
23
+ return {
24
+ changes: { from: range.from, insert: url },
25
+ range: EditorSelection.cursor(range.from + url.length),
26
+ };
27
+ }
28
+ const insert = `[${state.sliceDoc(range.from, range.to)}](${url})`;
29
+ return {
30
+ changes: { from: range.from, to: range.to, insert },
31
+ range: EditorSelection.cursor(range.from + insert.length),
32
+ };
33
+ }), { userEvent: "input.paste", scrollIntoView: true }));
34
+ return true;
35
+ },
36
+ });
37
+ //# sourceMappingURL=paste-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste-url.js","sourceRoot":"","sources":["../../../src/editor/editing/paste-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC,gBAAgB,CAAC;IACxD,KAAK,CAAC,KAAK,EAAE,IAAI;QACf,IAAI,WAAW,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACpC,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACpE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;QACvB,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACvE,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,QAAQ,CACX,KAAK,CAAC,MAAM,CACV,KAAK,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,OAAO;oBACL,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;oBAC1C,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;iBACvD,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC;YACnE,OAAO;gBACL,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE;gBACnD,KAAK,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;aAC1D,CAAC;QACJ,CAAC,CAAC,EACF,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,CACnD,CACF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type SelectionRange } from "@codemirror/state";
2
+ /** Typed characters that wrap a selection. Fixed, not configurable (ADR 0016). */
3
+ export declare const WRAP_CHARS: Set<string>;
4
+ /**
5
+ * Typing a wrap character over a non-empty `range` wraps it instead of
6
+ * replacing it, leaving the inner text selected.
7
+ */
8
+ export declare function wrapRange(range: SelectionRange, text: string): {
9
+ changes: {
10
+ from: number;
11
+ insert: string;
12
+ }[];
13
+ range: SelectionRange;
14
+ };
15
+ //# sourceMappingURL=selection-wrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-wrap.d.ts","sourceRoot":"","sources":["../../../src/editor/editing/selection-wrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAIzE,kFAAkF;AAClF,eAAO,MAAM,UAAU,aAWrB,CAAC;AAEH;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM;;;;;;EAY5D"}
@@ -0,0 +1,30 @@
1
+ import { EditorSelection } from "@codemirror/state";
2
+ import { BRACKET_CLOSERS } from "./pairs.js";
3
+ /** Typed characters that wrap a selection. Fixed, not configurable (ADR 0016). */
4
+ export const WRAP_CHARS = new Set([
5
+ "*",
6
+ "_",
7
+ "`",
8
+ "~",
9
+ "=",
10
+ "[",
11
+ "(",
12
+ "{",
13
+ '"',
14
+ "'",
15
+ ]);
16
+ /**
17
+ * Typing a wrap character over a non-empty `range` wraps it instead of
18
+ * replacing it, leaving the inner text selected.
19
+ */
20
+ export function wrapRange(range, text) {
21
+ const close = BRACKET_CLOSERS[text] ?? text;
22
+ return {
23
+ changes: [
24
+ { from: range.from, insert: text },
25
+ { from: range.to, insert: close },
26
+ ],
27
+ range: EditorSelection.range(range.anchor + text.length, range.head + text.length),
28
+ };
29
+ }
30
+ //# sourceMappingURL=selection-wrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-wrap.js","sourceRoot":"","sources":["../../../src/editor/editing/selection-wrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAuB,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,kFAAkF;AAClF,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IAChC,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;CACJ,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB,EAAE,IAAY;IAC3D,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAC5C,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;YAClC,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;SAClC;QACD,KAAK,EAAE,eAAe,CAAC,KAAK,CAC1B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAC1B,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CACzB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Command } from "@codemirror/view";
2
+ /** Mod-Enter toggles the task on the list item at each cursor. */
3
+ export declare const toggleTask: Command;
4
+ //# sourceMappingURL=task-toggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-toggle.d.ts","sourceRoot":"","sources":["../../../src/editor/editing/task-toggle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAKhD,kEAAkE;AAClE,eAAO,MAAM,UAAU,EAAE,OAyBxB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { fencedLines } from "./code-fence.js";
2
+ import { parseListLine } from "./list-line.js";
3
+ /** Mod-Enter toggles the task on the list item at each cursor. */
4
+ export const toggleTask = (view) => {
5
+ const { state } = view;
6
+ const fenced = fencedLines(state.doc);
7
+ const seen = new Set();
8
+ const changes = [];
9
+ for (const range of state.selection.ranges) {
10
+ const line = state.doc.lineAt(range.head);
11
+ if (seen.has(line.number) || fenced.has(line.number))
12
+ continue;
13
+ seen.add(line.number);
14
+ const item = parseListLine(line.text);
15
+ if (!item || item.kind === "quote")
16
+ continue;
17
+ if (item.task === null) {
18
+ changes.push({ from: line.from + item.contentStart, insert: "[ ] " });
19
+ continue;
20
+ }
21
+ const box = item.indent.length + item.marker.length + item.gap.length;
22
+ changes.push({
23
+ from: line.from + box + 1,
24
+ to: line.from + box + 2,
25
+ insert: item.task === " " ? "x" : " ",
26
+ });
27
+ }
28
+ if (changes.length)
29
+ view.dispatch(state.update({ changes, userEvent: "input.toggle" }));
30
+ return true;
31
+ };
32
+ //# sourceMappingURL=task-toggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-toggle.js","sourceRoot":"","sources":["../../../src/editor/editing/task-toggle.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,kEAAkE;AAClE,MAAM,CAAC,MAAM,UAAU,GAAY,CAAC,IAAI,EAAE,EAAE;IAC1C,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACvB,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,SAAS;QAC/D,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;YAAE,SAAS;QAC7C,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACtE,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;QACtE,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC;YACzB,EAAE,EAAE,IAAI,CAAC,IAAI,GAAG,GAAG,GAAG,CAAC;YACvB,MAAM,EAAE,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;SACtC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,OAAO,CAAC,MAAM;QAChB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type Extension } from "@codemirror/state";
2
+ export interface TypingOptions {
3
+ /** Selection Wrap: a typed wrap character wraps a selected range. */
4
+ wrap: boolean;
5
+ /** Auto-pair: a typed opener inserts its closer at an empty range. */
6
+ pair: boolean;
7
+ /** `[[` -> `[[]]`, on its own when `pair` is off. */
8
+ wikiLinkAutoClose: boolean;
9
+ }
10
+ /**
11
+ * The typed-character behaviors. They share one input handler because each
12
+ * range decides for itself: a non-empty range wraps (Selection Wrap) while an
13
+ * empty one auto-pairs, in the same keystroke.
14
+ */
15
+ export declare function typingBehaviors(options: TypingOptions): Extension;
16
+ //# sourceMappingURL=typing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typing.d.ts","sourceRoot":"","sources":["../../../src/editor/editing/typing.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAOpE,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,IAAI,EAAE,OAAO,CAAC;IACd,sEAAsE;IACtE,IAAI,EAAE,OAAO,CAAC;IACd,qDAAqD;IACrD,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAyCjE"}