@neo4j-cypher/react-codemirror 2.0.0-next.0 → 2.0.0-next.2

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.
@@ -1,6 +1,5 @@
1
1
  // src/index.ts
2
2
  import { CypherParser, parse } from "@neo4j-cypher/language-support";
3
- import * as ReactCodemirror from "@uiw/react-codemirror";
4
3
 
5
4
  // src/CypherEditor.tsx
6
5
  import {
@@ -15,6 +14,167 @@ import {
15
14
  } from "@codemirror/view";
16
15
  import { Component, createRef } from "react";
17
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
+
18
178
  // src/lang-cypher/lang-cypher.ts
19
179
  import {
20
180
  defineLanguageFacet,
@@ -267,9 +427,9 @@ import {
267
427
  crosshairCursor,
268
428
  drawSelection,
269
429
  dropCursor,
270
- EditorView,
430
+ EditorView as EditorView2,
271
431
  highlightSpecialChars,
272
- keymap,
432
+ keymap as keymap2,
273
433
  rectangularSelection
274
434
  } from "@codemirror/view";
275
435
  import { lintKeymap } from "@codemirror/lint";
@@ -397,7 +557,7 @@ var basicNeo4jSetup = () => {
397
557
  addToOptions: [
398
558
  {
399
559
  render(completion, state) {
400
- const isDarkTheme = state.facet(EditorView.darkTheme);
560
+ const isDarkTheme = state.facet(EditorView2.darkTheme);
401
561
  const icon = document.createElement("span");
402
562
  icon.innerHTML = getIconForType(completion.type, isDarkTheme);
403
563
  const svgElement = icon.children[0];
@@ -413,191 +573,10 @@ var basicNeo4jSetup = () => {
413
573
  extensions.push(rectangularSelection());
414
574
  extensions.push(crosshairCursor());
415
575
  extensions.push(highlightSelectionMatches());
416
- extensions.push(keymap.of(keymaps));
576
+ extensions.push(keymap2.of(keymaps));
417
577
  return extensions;
418
578
  };
419
579
 
420
- // src/repl-mode.ts
421
- import { StateEffect } from "@codemirror/state";
422
- import { keymap as keymap2 } from "@codemirror/view";
423
- import { StateField } from "@codemirror/state";
424
- var DRAFT_ENTRY_INDEX = -1;
425
- var historyInitialState = {
426
- history: [],
427
- index: DRAFT_ENTRY_INDEX,
428
- documentUpdate: null,
429
- draft: ""
430
- };
431
- var historyState = StateField.define({
432
- create() {
433
- return historyInitialState;
434
- },
435
- toJSON(value) {
436
- return JSON.stringify(value);
437
- },
438
- update(value, transaction) {
439
- for (const effect of transaction.effects) {
440
- if (effect.is(moveInHistory)) {
441
- if (value.history.length === 0) {
442
- return {
443
- ...value,
444
- documentUpdate: null
445
- };
446
- }
447
- const currentHistoryIndex = value.index;
448
- if (effect.value === "BACK") {
449
- const newHistoryIndex = currentHistoryIndex + 1;
450
- if (newHistoryIndex === value.history.length) {
451
- return {
452
- ...value,
453
- documentUpdate: null
454
- };
455
- }
456
- let draft = value.draft;
457
- if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
458
- draft = transaction.state.doc.toString();
459
- }
460
- return {
461
- ...value,
462
- draft,
463
- index: newHistoryIndex,
464
- documentUpdate: value.history[newHistoryIndex]
465
- };
466
- } else if (effect.value === "FORWARDS") {
467
- const newHistoryIndex = currentHistoryIndex - 1;
468
- if (currentHistoryIndex === DRAFT_ENTRY_INDEX) {
469
- return { ...value, documentUpdate: null };
470
- }
471
- if (newHistoryIndex === DRAFT_ENTRY_INDEX) {
472
- return {
473
- ...value,
474
- index: newHistoryIndex,
475
- documentUpdate: value.draft
476
- };
477
- } else {
478
- return {
479
- ...value,
480
- index: newHistoryIndex,
481
- documentUpdate: value.history[newHistoryIndex]
482
- };
483
- }
484
- }
485
- } else if (effect.is(pushToHistory)) {
486
- return {
487
- ...value,
488
- index: DRAFT_ENTRY_INDEX,
489
- history: [effect.value, ...value.history]
490
- };
491
- }
492
- }
493
- return value;
494
- }
495
- });
496
- var moveInHistory = StateEffect.define();
497
- var pushToHistory = StateEffect.define();
498
- function navigateHistory(view, direction) {
499
- view.dispatch(
500
- view.state.update({
501
- effects: moveInHistory.of(direction),
502
- selection: { anchor: view.state.doc.length }
503
- })
504
- );
505
- const updatedHistory = view.state.field(historyState, false);
506
- if (updatedHistory.documentUpdate !== null) {
507
- view.dispatch(
508
- view.state.update({
509
- changes: {
510
- from: 0,
511
- to: view.state.doc.length,
512
- insert: updatedHistory.documentUpdate
513
- }
514
- })
515
- );
516
- }
517
- }
518
- var replMode = ({
519
- onExecute,
520
- onNewHistoryEntry,
521
- initialHistory
522
- }) => {
523
- return [
524
- historyState.init(() => ({
525
- ...historyInitialState,
526
- history: initialHistory
527
- })),
528
- keymap2.of([
529
- {
530
- key: "Ctrl-Enter",
531
- mac: "Mod-Enter",
532
- preventDefault: true,
533
- run: (view) => {
534
- const doc = view.state.doc.toString();
535
- if (doc.trim() !== "") {
536
- onExecute?.(doc);
537
- onNewHistoryEntry?.(doc);
538
- view.dispatch({
539
- effects: pushToHistory.of(doc)
540
- });
541
- }
542
- return true;
543
- }
544
- },
545
- {
546
- key: "ArrowUp",
547
- preventDefault: true,
548
- run: (view) => {
549
- const { empty, head } = view.state.selection.main;
550
- if (!empty || head !== 0) {
551
- return false;
552
- }
553
- navigateHistory(view, "BACK");
554
- return true;
555
- }
556
- },
557
- {
558
- mac: "Cmd-ArrowUp",
559
- win: "Ctrl-ArrowUp",
560
- linux: "Ctrl-ArrowUp",
561
- preventDefault: true,
562
- run: (view) => {
563
- const { empty, head } = view.state.selection.main;
564
- if (!empty || head !== 0) {
565
- return false;
566
- }
567
- navigateHistory(view, "BACK");
568
- return true;
569
- }
570
- },
571
- {
572
- key: "ArrowDown",
573
- preventDefault: true,
574
- run: (view) => {
575
- const { empty, head } = view.state.selection.main;
576
- if (!empty || head !== view.state.doc.length) {
577
- return false;
578
- }
579
- navigateHistory(view, "FORWARDS");
580
- return true;
581
- }
582
- },
583
- {
584
- mac: "Cmd-ArrowDown",
585
- win: "Ctrl-ArrowDown",
586
- linux: "Ctrl-ArrowDown",
587
- preventDefault: true,
588
- run: (view) => {
589
- const { empty, head } = view.state.selection.main;
590
- if (!empty || head !== view.state.doc.length) {
591
- return false;
592
- }
593
- navigateHistory(view, "FORWARDS");
594
- return true;
595
- }
596
- }
597
- ])
598
- ];
599
- };
600
-
601
580
  // src/themes.ts
602
581
  import { light, mirage } from "ayu";
603
582
 
@@ -1283,6 +1262,20 @@ function getThemeExtension(theme, inheritBgColor) {
1283
1262
 
1284
1263
  // src/CypherEditor.tsx
1285
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
+ ] : [];
1286
1279
  var themeCompartment = new Compartment();
1287
1280
  var keyBindingCompartment = new Compartment();
1288
1281
  var ExternalEdit = Annotation.define();
@@ -1336,28 +1329,21 @@ var CypherEditor = class extends Component {
1336
1329
  overrideThemeBackgroundColor: false,
1337
1330
  lineWrap: false,
1338
1331
  extraKeybindings: [],
1339
- initialHistory: [],
1332
+ history: [],
1340
1333
  theme: "light"
1341
1334
  };
1342
1335
  componentDidMount() {
1343
1336
  const {
1344
1337
  theme,
1345
- onExecute,
1346
- initialHistory,
1347
- onNewHistoryEntry,
1348
1338
  extraKeybindings,
1349
1339
  lineWrap,
1350
1340
  overrideThemeBackgroundColor,
1351
1341
  schema,
1352
1342
  lint,
1353
- onChange
1343
+ onChange,
1344
+ onExecute
1354
1345
  } = this.props;
1355
1346
  this.schemaRef.current = { schema, lint };
1356
- const maybeReplMode = onExecute ? replMode({
1357
- onExecute,
1358
- initialHistory,
1359
- onNewHistoryEntry
1360
- }) : [];
1361
1347
  const themeExtension = getThemeExtension(
1362
1348
  theme,
1363
1349
  overrideThemeBackgroundColor
@@ -1376,12 +1362,14 @@ var CypherEditor = class extends Component {
1376
1362
  ] : [];
1377
1363
  this.editorState.current = EditorState2.create({
1378
1364
  extensions: [
1379
- maybeReplMode,
1365
+ keyBindingCompartment.of(
1366
+ keymap3.of([...executeKeybinding(onExecute), ...extraKeybindings])
1367
+ ),
1368
+ replMode(this.props),
1380
1369
  basicNeo4jSetup(),
1381
1370
  themeCompartment.of(themeExtension),
1382
1371
  changeListener,
1383
1372
  cypher(this.schemaRef.current),
1384
- keyBindingCompartment.of(keymap3.of(extraKeybindings)),
1385
1373
  lineWrap ? EditorView4.lineWrapping : [],
1386
1374
  lineNumbers({
1387
1375
  formatNumber: (a, state) => {
@@ -1431,13 +1419,21 @@ var CypherEditor = class extends Component {
1431
1419
  )
1432
1420
  });
1433
1421
  }
1434
- if (prevProps.extraKeybindings !== this.props.extraKeybindings) {
1422
+ if (prevProps.extraKeybindings !== this.props.extraKeybindings || prevProps.onExecute !== this.props.onExecute) {
1435
1423
  this.editorView.current.dispatch({
1436
1424
  effects: keyBindingCompartment.reconfigure(
1437
- keymap3.of(this.props.extraKeybindings)
1425
+ keymap3.of([
1426
+ ...executeKeybinding(this.props.onExecute),
1427
+ ...this.props.extraKeybindings
1428
+ ])
1438
1429
  )
1439
1430
  });
1440
1431
  }
1432
+ if (prevProps.history?.length !== this.props.history?.length) {
1433
+ this.editorView.current.dispatch({
1434
+ effects: replaceHistory.of(this.props.history ?? [])
1435
+ });
1436
+ }
1441
1437
  this.schemaRef.current.schema = this.props.schema;
1442
1438
  this.schemaRef.current.lint = this.props.lint;
1443
1439
  }
@@ -1459,7 +1455,6 @@ var CypherEditor = class extends Component {
1459
1455
  export {
1460
1456
  CypherEditor,
1461
1457
  CypherParser,
1462
- ReactCodemirror,
1463
1458
  cypher,
1464
1459
  darkThemeConstants,
1465
1460
  lightThemeConstants,