@neo4j-cypher/react-codemirror 2.0.0-next.1 → 2.0.0-next.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.
- package/CHANGELOG.md +14 -0
- package/README.md +4 -1
- package/dist/cjs/index.cjs +202 -205
- package/dist/cjs/index.cjs.map +4 -4
- package/dist/esm/index.mjs +196 -199
- package/dist/esm/index.mjs.map +4 -4
- package/dist/types/CypherEditor.d.ts +3 -8
- package/dist/types/history-navigation.d.ts +7 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/CypherEditor.tsx +46 -25
- package/src/e2e_tests/history-navigation.spec.tsx +63 -11
- package/src/e2e_tests/syntax-validation.spec.tsx +0 -1
- package/src/{repl-mode.ts → history-navigation.ts} +6 -29
- package/dist/types/repl-mode.d.ts +0 -8
package/dist/esm/index.mjs
CHANGED
|
@@ -14,6 +14,167 @@ import {
|
|
|
14
14
|
} from "@codemirror/view";
|
|
15
15
|
import { Component, createRef } from "react";
|
|
16
16
|
|
|
17
|
+
// src/history-navigation.ts
|
|
18
|
+
import { StateEffect } from "@codemirror/state";
|
|
19
|
+
import { keymap } from "@codemirror/view";
|
|
20
|
+
import { StateField } from "@codemirror/state";
|
|
21
|
+
var DRAFT_ENTRY_INDEX = -1;
|
|
22
|
+
var historyInitialState = {
|
|
23
|
+
history: [],
|
|
24
|
+
index: DRAFT_ENTRY_INDEX,
|
|
25
|
+
documentUpdate: null,
|
|
26
|
+
draft: ""
|
|
27
|
+
};
|
|
28
|
+
var historyState = StateField.define({
|
|
29
|
+
create() {
|
|
30
|
+
return historyInitialState;
|
|
31
|
+
},
|
|
32
|
+
toJSON(value) {
|
|
33
|
+
return JSON.stringify(value);
|
|
34
|
+
},
|
|
35
|
+
update(value, transaction) {
|
|
36
|
+
for (const effect of transaction.effects) {
|
|
37
|
+
if (effect.is(moveInHistory)) {
|
|
38
|
+
if (value.history.length === 0) {
|
|
39
|
+
return {
|
|
40
|
+
...value,
|
|
41
|
+
documentUpdate: null
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const currentHistoryIndex = value.index;
|
|
45
|
+
if (effect.value === "BACK") {
|
|
46
|
+
const newHistoryIndex = currentHistoryIndex + 1;
|
|
47
|
+
if (newHistoryIndex === value.history.length) {
|
|
48
|
+
return {
|
|
49
|
+
...value,
|
|
50
|
+
documentUpdate: null
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
let draft = value.draft;
|
|
54
|
+
if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
55
|
+
draft = transaction.state.doc.toString();
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
...value,
|
|
59
|
+
draft,
|
|
60
|
+
index: newHistoryIndex,
|
|
61
|
+
documentUpdate: value.history[newHistoryIndex]
|
|
62
|
+
};
|
|
63
|
+
} else if (effect.value === "FORWARDS") {
|
|
64
|
+
const newHistoryIndex = currentHistoryIndex - 1;
|
|
65
|
+
if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
66
|
+
return { ...value, documentUpdate: null };
|
|
67
|
+
}
|
|
68
|
+
if (newHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
69
|
+
return {
|
|
70
|
+
...value,
|
|
71
|
+
index: newHistoryIndex,
|
|
72
|
+
documentUpdate: value.draft
|
|
73
|
+
};
|
|
74
|
+
} else {
|
|
75
|
+
return {
|
|
76
|
+
...value,
|
|
77
|
+
index: newHistoryIndex,
|
|
78
|
+
documentUpdate: value.history[newHistoryIndex]
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} else if (effect.is(replaceHistory)) {
|
|
83
|
+
return {
|
|
84
|
+
...value,
|
|
85
|
+
index: DRAFT_ENTRY_INDEX,
|
|
86
|
+
history: effect.value
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return value;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
var moveInHistory = StateEffect.define();
|
|
94
|
+
var replaceHistory = StateEffect.define();
|
|
95
|
+
function navigateHistory(view, direction) {
|
|
96
|
+
view.dispatch(
|
|
97
|
+
view.state.update({
|
|
98
|
+
effects: moveInHistory.of(direction),
|
|
99
|
+
selection: { anchor: view.state.doc.length }
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
const updatedHistory = view.state.field(historyState, false);
|
|
103
|
+
if (updatedHistory.documentUpdate !== null) {
|
|
104
|
+
view.dispatch(
|
|
105
|
+
view.state.update({
|
|
106
|
+
changes: {
|
|
107
|
+
from: 0,
|
|
108
|
+
to: view.state.doc.length,
|
|
109
|
+
insert: updatedHistory.documentUpdate
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
var replMode = ({ history: history2 }) => {
|
|
116
|
+
return [
|
|
117
|
+
historyState.init(() => ({
|
|
118
|
+
...historyInitialState,
|
|
119
|
+
history: history2
|
|
120
|
+
})),
|
|
121
|
+
keymap.of([
|
|
122
|
+
{
|
|
123
|
+
key: "ArrowUp",
|
|
124
|
+
preventDefault: true,
|
|
125
|
+
run: (view) => {
|
|
126
|
+
const { empty, head } = view.state.selection.main;
|
|
127
|
+
if (!empty || head !== 0) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
navigateHistory(view, "BACK");
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
mac: "Cmd-ArrowUp",
|
|
136
|
+
win: "Ctrl-ArrowUp",
|
|
137
|
+
linux: "Ctrl-ArrowUp",
|
|
138
|
+
preventDefault: true,
|
|
139
|
+
run: (view) => {
|
|
140
|
+
const { empty, head } = view.state.selection.main;
|
|
141
|
+
if (!empty || head !== 0) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
navigateHistory(view, "BACK");
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
key: "ArrowDown",
|
|
150
|
+
preventDefault: true,
|
|
151
|
+
run: (view) => {
|
|
152
|
+
const { empty, head } = view.state.selection.main;
|
|
153
|
+
if (!empty || head !== view.state.doc.length) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
navigateHistory(view, "FORWARDS");
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
mac: "Cmd-ArrowDown",
|
|
162
|
+
win: "Ctrl-ArrowDown",
|
|
163
|
+
linux: "Ctrl-ArrowDown",
|
|
164
|
+
preventDefault: true,
|
|
165
|
+
run: (view) => {
|
|
166
|
+
const { empty, head } = view.state.selection.main;
|
|
167
|
+
if (!empty || head !== view.state.doc.length) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
navigateHistory(view, "FORWARDS");
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
])
|
|
175
|
+
];
|
|
176
|
+
};
|
|
177
|
+
|
|
17
178
|
// src/lang-cypher/lang-cypher.ts
|
|
18
179
|
import {
|
|
19
180
|
defineLanguageFacet,
|
|
@@ -266,9 +427,9 @@ import {
|
|
|
266
427
|
crosshairCursor,
|
|
267
428
|
drawSelection,
|
|
268
429
|
dropCursor,
|
|
269
|
-
EditorView,
|
|
430
|
+
EditorView as EditorView2,
|
|
270
431
|
highlightSpecialChars,
|
|
271
|
-
keymap,
|
|
432
|
+
keymap as keymap2,
|
|
272
433
|
rectangularSelection
|
|
273
434
|
} from "@codemirror/view";
|
|
274
435
|
import { lintKeymap } from "@codemirror/lint";
|
|
@@ -396,7 +557,7 @@ var basicNeo4jSetup = () => {
|
|
|
396
557
|
addToOptions: [
|
|
397
558
|
{
|
|
398
559
|
render(completion, state) {
|
|
399
|
-
const isDarkTheme = state.facet(
|
|
560
|
+
const isDarkTheme = state.facet(EditorView2.darkTheme);
|
|
400
561
|
const icon = document.createElement("span");
|
|
401
562
|
icon.innerHTML = getIconForType(completion.type, isDarkTheme);
|
|
402
563
|
const svgElement = icon.children[0];
|
|
@@ -412,191 +573,10 @@ var basicNeo4jSetup = () => {
|
|
|
412
573
|
extensions.push(rectangularSelection());
|
|
413
574
|
extensions.push(crosshairCursor());
|
|
414
575
|
extensions.push(highlightSelectionMatches());
|
|
415
|
-
extensions.push(
|
|
576
|
+
extensions.push(keymap2.of(keymaps));
|
|
416
577
|
return extensions;
|
|
417
578
|
};
|
|
418
579
|
|
|
419
|
-
// src/repl-mode.ts
|
|
420
|
-
import { StateEffect } from "@codemirror/state";
|
|
421
|
-
import { keymap as keymap2 } from "@codemirror/view";
|
|
422
|
-
import { StateField } from "@codemirror/state";
|
|
423
|
-
var DRAFT_ENTRY_INDEX = -1;
|
|
424
|
-
var historyInitialState = {
|
|
425
|
-
history: [],
|
|
426
|
-
index: DRAFT_ENTRY_INDEX,
|
|
427
|
-
documentUpdate: null,
|
|
428
|
-
draft: ""
|
|
429
|
-
};
|
|
430
|
-
var historyState = StateField.define({
|
|
431
|
-
create() {
|
|
432
|
-
return historyInitialState;
|
|
433
|
-
},
|
|
434
|
-
toJSON(value) {
|
|
435
|
-
return JSON.stringify(value);
|
|
436
|
-
},
|
|
437
|
-
update(value, transaction) {
|
|
438
|
-
for (const effect of transaction.effects) {
|
|
439
|
-
if (effect.is(moveInHistory)) {
|
|
440
|
-
if (value.history.length === 0) {
|
|
441
|
-
return {
|
|
442
|
-
...value,
|
|
443
|
-
documentUpdate: null
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
const currentHistoryIndex = value.index;
|
|
447
|
-
if (effect.value === "BACK") {
|
|
448
|
-
const newHistoryIndex = currentHistoryIndex + 1;
|
|
449
|
-
if (newHistoryIndex === value.history.length) {
|
|
450
|
-
return {
|
|
451
|
-
...value,
|
|
452
|
-
documentUpdate: null
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
let draft = value.draft;
|
|
456
|
-
if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
457
|
-
draft = transaction.state.doc.toString();
|
|
458
|
-
}
|
|
459
|
-
return {
|
|
460
|
-
...value,
|
|
461
|
-
draft,
|
|
462
|
-
index: newHistoryIndex,
|
|
463
|
-
documentUpdate: value.history[newHistoryIndex]
|
|
464
|
-
};
|
|
465
|
-
} else if (effect.value === "FORWARDS") {
|
|
466
|
-
const newHistoryIndex = currentHistoryIndex - 1;
|
|
467
|
-
if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
468
|
-
return { ...value, documentUpdate: null };
|
|
469
|
-
}
|
|
470
|
-
if (newHistoryIndex === DRAFT_ENTRY_INDEX) {
|
|
471
|
-
return {
|
|
472
|
-
...value,
|
|
473
|
-
index: newHistoryIndex,
|
|
474
|
-
documentUpdate: value.draft
|
|
475
|
-
};
|
|
476
|
-
} else {
|
|
477
|
-
return {
|
|
478
|
-
...value,
|
|
479
|
-
index: newHistoryIndex,
|
|
480
|
-
documentUpdate: value.history[newHistoryIndex]
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
} else if (effect.is(pushToHistory)) {
|
|
485
|
-
return {
|
|
486
|
-
...value,
|
|
487
|
-
index: DRAFT_ENTRY_INDEX,
|
|
488
|
-
history: [effect.value, ...value.history]
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
return value;
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
var moveInHistory = StateEffect.define();
|
|
496
|
-
var pushToHistory = StateEffect.define();
|
|
497
|
-
function navigateHistory(view, direction) {
|
|
498
|
-
view.dispatch(
|
|
499
|
-
view.state.update({
|
|
500
|
-
effects: moveInHistory.of(direction),
|
|
501
|
-
selection: { anchor: view.state.doc.length }
|
|
502
|
-
})
|
|
503
|
-
);
|
|
504
|
-
const updatedHistory = view.state.field(historyState, false);
|
|
505
|
-
if (updatedHistory.documentUpdate !== null) {
|
|
506
|
-
view.dispatch(
|
|
507
|
-
view.state.update({
|
|
508
|
-
changes: {
|
|
509
|
-
from: 0,
|
|
510
|
-
to: view.state.doc.length,
|
|
511
|
-
insert: updatedHistory.documentUpdate
|
|
512
|
-
}
|
|
513
|
-
})
|
|
514
|
-
);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
var replMode = ({
|
|
518
|
-
onExecute,
|
|
519
|
-
onNewHistoryEntry,
|
|
520
|
-
initialHistory
|
|
521
|
-
}) => {
|
|
522
|
-
return [
|
|
523
|
-
historyState.init(() => ({
|
|
524
|
-
...historyInitialState,
|
|
525
|
-
history: initialHistory
|
|
526
|
-
})),
|
|
527
|
-
keymap2.of([
|
|
528
|
-
{
|
|
529
|
-
key: "Ctrl-Enter",
|
|
530
|
-
mac: "Mod-Enter",
|
|
531
|
-
preventDefault: true,
|
|
532
|
-
run: (view) => {
|
|
533
|
-
const doc = view.state.doc.toString();
|
|
534
|
-
if (doc.trim() !== "") {
|
|
535
|
-
onExecute?.(doc);
|
|
536
|
-
onNewHistoryEntry?.(doc);
|
|
537
|
-
view.dispatch({
|
|
538
|
-
effects: pushToHistory.of(doc)
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
return true;
|
|
542
|
-
}
|
|
543
|
-
},
|
|
544
|
-
{
|
|
545
|
-
key: "ArrowUp",
|
|
546
|
-
preventDefault: true,
|
|
547
|
-
run: (view) => {
|
|
548
|
-
const { empty, head } = view.state.selection.main;
|
|
549
|
-
if (!empty || head !== 0) {
|
|
550
|
-
return false;
|
|
551
|
-
}
|
|
552
|
-
navigateHistory(view, "BACK");
|
|
553
|
-
return true;
|
|
554
|
-
}
|
|
555
|
-
},
|
|
556
|
-
{
|
|
557
|
-
mac: "Cmd-ArrowUp",
|
|
558
|
-
win: "Ctrl-ArrowUp",
|
|
559
|
-
linux: "Ctrl-ArrowUp",
|
|
560
|
-
preventDefault: true,
|
|
561
|
-
run: (view) => {
|
|
562
|
-
const { empty, head } = view.state.selection.main;
|
|
563
|
-
if (!empty || head !== 0) {
|
|
564
|
-
return false;
|
|
565
|
-
}
|
|
566
|
-
navigateHistory(view, "BACK");
|
|
567
|
-
return true;
|
|
568
|
-
}
|
|
569
|
-
},
|
|
570
|
-
{
|
|
571
|
-
key: "ArrowDown",
|
|
572
|
-
preventDefault: true,
|
|
573
|
-
run: (view) => {
|
|
574
|
-
const { empty, head } = view.state.selection.main;
|
|
575
|
-
if (!empty || head !== view.state.doc.length) {
|
|
576
|
-
return false;
|
|
577
|
-
}
|
|
578
|
-
navigateHistory(view, "FORWARDS");
|
|
579
|
-
return true;
|
|
580
|
-
}
|
|
581
|
-
},
|
|
582
|
-
{
|
|
583
|
-
mac: "Cmd-ArrowDown",
|
|
584
|
-
win: "Ctrl-ArrowDown",
|
|
585
|
-
linux: "Ctrl-ArrowDown",
|
|
586
|
-
preventDefault: true,
|
|
587
|
-
run: (view) => {
|
|
588
|
-
const { empty, head } = view.state.selection.main;
|
|
589
|
-
if (!empty || head !== view.state.doc.length) {
|
|
590
|
-
return false;
|
|
591
|
-
}
|
|
592
|
-
navigateHistory(view, "FORWARDS");
|
|
593
|
-
return true;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
])
|
|
597
|
-
];
|
|
598
|
-
};
|
|
599
|
-
|
|
600
580
|
// src/themes.ts
|
|
601
581
|
import { light, mirage } from "ayu";
|
|
602
582
|
|
|
@@ -1282,6 +1262,20 @@ function getThemeExtension(theme, inheritBgColor) {
|
|
|
1282
1262
|
|
|
1283
1263
|
// src/CypherEditor.tsx
|
|
1284
1264
|
import { jsx } from "react/jsx-runtime";
|
|
1265
|
+
var executeKeybinding = (onExecute) => onExecute ? [
|
|
1266
|
+
{
|
|
1267
|
+
key: "Ctrl-Enter",
|
|
1268
|
+
mac: "Mod-Enter",
|
|
1269
|
+
preventDefault: true,
|
|
1270
|
+
run: (view) => {
|
|
1271
|
+
const doc = view.state.doc.toString();
|
|
1272
|
+
if (doc.trim() !== "") {
|
|
1273
|
+
onExecute(doc);
|
|
1274
|
+
}
|
|
1275
|
+
return true;
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
] : [];
|
|
1285
1279
|
var themeCompartment = new Compartment();
|
|
1286
1280
|
var keyBindingCompartment = new Compartment();
|
|
1287
1281
|
var ExternalEdit = Annotation.define();
|
|
@@ -1335,28 +1329,21 @@ var CypherEditor = class extends Component {
|
|
|
1335
1329
|
overrideThemeBackgroundColor: false,
|
|
1336
1330
|
lineWrap: false,
|
|
1337
1331
|
extraKeybindings: [],
|
|
1338
|
-
|
|
1332
|
+
history: [],
|
|
1339
1333
|
theme: "light"
|
|
1340
1334
|
};
|
|
1341
1335
|
componentDidMount() {
|
|
1342
1336
|
const {
|
|
1343
1337
|
theme,
|
|
1344
|
-
onExecute,
|
|
1345
|
-
initialHistory,
|
|
1346
|
-
onNewHistoryEntry,
|
|
1347
1338
|
extraKeybindings,
|
|
1348
1339
|
lineWrap,
|
|
1349
1340
|
overrideThemeBackgroundColor,
|
|
1350
1341
|
schema,
|
|
1351
1342
|
lint,
|
|
1352
|
-
onChange
|
|
1343
|
+
onChange,
|
|
1344
|
+
onExecute
|
|
1353
1345
|
} = this.props;
|
|
1354
1346
|
this.schemaRef.current = { schema, lint };
|
|
1355
|
-
const maybeReplMode = onExecute ? replMode({
|
|
1356
|
-
onExecute,
|
|
1357
|
-
initialHistory,
|
|
1358
|
-
onNewHistoryEntry
|
|
1359
|
-
}) : [];
|
|
1360
1347
|
const themeExtension = getThemeExtension(
|
|
1361
1348
|
theme,
|
|
1362
1349
|
overrideThemeBackgroundColor
|
|
@@ -1375,12 +1362,14 @@ var CypherEditor = class extends Component {
|
|
|
1375
1362
|
] : [];
|
|
1376
1363
|
this.editorState.current = EditorState2.create({
|
|
1377
1364
|
extensions: [
|
|
1378
|
-
|
|
1365
|
+
keyBindingCompartment.of(
|
|
1366
|
+
keymap3.of([...executeKeybinding(onExecute), ...extraKeybindings])
|
|
1367
|
+
),
|
|
1368
|
+
replMode(this.props),
|
|
1379
1369
|
basicNeo4jSetup(),
|
|
1380
1370
|
themeCompartment.of(themeExtension),
|
|
1381
1371
|
changeListener,
|
|
1382
1372
|
cypher(this.schemaRef.current),
|
|
1383
|
-
keyBindingCompartment.of(keymap3.of(extraKeybindings)),
|
|
1384
1373
|
lineWrap ? EditorView4.lineWrapping : [],
|
|
1385
1374
|
lineNumbers({
|
|
1386
1375
|
formatNumber: (a, state) => {
|
|
@@ -1430,13 +1419,21 @@ var CypherEditor = class extends Component {
|
|
|
1430
1419
|
)
|
|
1431
1420
|
});
|
|
1432
1421
|
}
|
|
1433
|
-
if (prevProps.extraKeybindings !== this.props.extraKeybindings) {
|
|
1422
|
+
if (prevProps.extraKeybindings !== this.props.extraKeybindings || prevProps.onExecute !== this.props.onExecute) {
|
|
1434
1423
|
this.editorView.current.dispatch({
|
|
1435
1424
|
effects: keyBindingCompartment.reconfigure(
|
|
1436
|
-
keymap3.of(
|
|
1425
|
+
keymap3.of([
|
|
1426
|
+
...executeKeybinding(this.props.onExecute),
|
|
1427
|
+
...this.props.extraKeybindings
|
|
1428
|
+
])
|
|
1437
1429
|
)
|
|
1438
1430
|
});
|
|
1439
1431
|
}
|
|
1432
|
+
if (prevProps.history?.length !== this.props.history?.length) {
|
|
1433
|
+
this.editorView.current.dispatch({
|
|
1434
|
+
effects: replaceHistory.of(this.props.history ?? [])
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1440
1437
|
this.schemaRef.current.schema = this.props.schema;
|
|
1441
1438
|
this.schemaRef.current.lint = this.props.lint;
|
|
1442
1439
|
}
|