@neo4j-cypher/react-codemirror 2.0.0-next.4 → 2.0.0-next.5
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 +11 -0
- package/dist/{types/CypherEditor.d.ts → CypherEditor.d.ts} +10 -1
- package/dist/CypherEditor.js +206 -0
- package/dist/CypherEditor.js.map +1 -0
- package/dist/e2e_tests/auto-completion.spec.js +129 -0
- package/dist/e2e_tests/auto-completion.spec.js.map +1 -0
- package/dist/e2e_tests/e2e-utils.js +52 -0
- package/dist/e2e_tests/e2e-utils.js.map +1 -0
- package/dist/e2e_tests/extra-keybindings.spec.js +44 -0
- package/dist/e2e_tests/extra-keybindings.spec.js.map +1 -0
- package/dist/e2e_tests/history-navigation.spec.js +136 -0
- package/dist/e2e_tests/history-navigation.spec.js.map +1 -0
- package/dist/e2e_tests/performance-test.spec.d.ts +6 -0
- package/dist/e2e_tests/performance-test.spec.js +96 -0
- package/dist/e2e_tests/performance-test.spec.js.map +1 -0
- package/dist/e2e_tests/sanity-checks.spec.js +65 -0
- package/dist/e2e_tests/sanity-checks.spec.js.map +1 -0
- package/dist/e2e_tests/signature-help.spec.js +151 -0
- package/dist/e2e_tests/signature-help.spec.js.map +1 -0
- package/dist/e2e_tests/syntax-highlighting.spec.js +91 -0
- package/dist/e2e_tests/syntax-highlighting.spec.js.map +1 -0
- package/dist/e2e_tests/syntax-validation.spec.js +79 -0
- package/dist/e2e_tests/syntax-validation.spec.js.map +1 -0
- package/dist/history-navigation.js +163 -0
- package/dist/history-navigation.js.map +1 -0
- package/dist/{types/icons.d.ts → icons.d.ts} +1 -1
- package/dist/icons.js +62 -0
- package/dist/icons.js.map +1 -0
- package/dist/{types/index.d.ts → index.d.ts} +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lang-cypher/autocomplete.js +56 -0
- package/dist/lang-cypher/autocomplete.js.map +1 -0
- package/dist/{types/lang-cypher → lang-cypher}/constants.d.ts +9 -0
- package/dist/lang-cypher/constants.js +65 -0
- package/dist/lang-cypher/constants.js.map +1 -0
- package/dist/lang-cypher/contants.test.js +102 -0
- package/dist/lang-cypher/contants.test.js.map +1 -0
- package/dist/lang-cypher/create-cypher-theme.js +144 -0
- package/dist/lang-cypher/create-cypher-theme.js.map +1 -0
- package/dist/{types/lang-cypher → lang-cypher}/lang-cypher.d.ts +3 -1
- package/dist/lang-cypher/lang-cypher.js +24 -0
- package/dist/lang-cypher/lang-cypher.js.map +1 -0
- package/dist/lang-cypher/lint-worker.d.ts +8 -0
- package/dist/lang-cypher/lint-worker.js +4 -0
- package/dist/lang-cypher/lint-worker.js.map +1 -0
- package/dist/lang-cypher/parser-adapter.d.ts +19 -0
- package/dist/lang-cypher/parser-adapter.js +113 -0
- package/dist/lang-cypher/parser-adapter.js.map +1 -0
- package/dist/lang-cypher/signature-help.d.ts +4 -0
- package/dist/lang-cypher/signature-help.js +77 -0
- package/dist/lang-cypher/signature-help.js.map +1 -0
- package/dist/{types/lang-cypher → lang-cypher}/syntax-validation.d.ts +2 -0
- package/dist/lang-cypher/syntax-validation.js +68 -0
- package/dist/lang-cypher/syntax-validation.js.map +1 -0
- package/dist/lang-cypher/theme-icons.js +22 -0
- package/dist/lang-cypher/theme-icons.js.map +1 -0
- package/dist/ndl-tokens-copy.js +380 -0
- package/dist/ndl-tokens-copy.js.map +1 -0
- package/dist/ndl-tokens-copy.test.js +11 -0
- package/dist/ndl-tokens-copy.test.js.map +1 -0
- package/dist/neo4j-setup.js +86 -0
- package/dist/neo4j-setup.js.map +1 -0
- package/dist/themes.js +114 -0
- package/dist/themes.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +15 -18
- package/src/CypherEditor.tsx +31 -5
- package/src/e2e_tests/performance-test.spec.tsx +100 -13
- package/src/e2e_tests/sanity-checks.spec.tsx +8 -3
- package/src/e2e_tests/signature-help.spec.tsx +312 -0
- package/src/icons.ts +3 -0
- package/src/index.ts +1 -1
- package/src/lang-cypher/autocomplete.ts +6 -1
- package/src/lang-cypher/constants.ts +23 -0
- package/src/lang-cypher/create-cypher-theme.ts +4 -0
- package/src/lang-cypher/lang-cypher.ts +16 -7
- package/src/lang-cypher/lint-worker.ts +14 -0
- package/src/lang-cypher/parser-adapter.ts +145 -0
- package/src/lang-cypher/signature-help.ts +102 -0
- package/src/lang-cypher/syntax-validation.ts +70 -4
- package/src/themes.ts +2 -0
- package/dist/cjs/index.cjs +0 -1441
- package/dist/cjs/index.cjs.map +0 -7
- package/dist/esm/index.mjs +0 -1464
- package/dist/esm/index.mjs.map +0 -7
- package/dist/types/e2e_tests/mock-data.d.ts +0 -3779
- package/dist/types/lang-cypher/ParserAdapter.d.ts +0 -14
- package/dist/types/tsconfig.tsbuildinfo +0 -1
- package/src/e2e_tests/mock-data.ts +0 -4310
- package/src/lang-cypher/ParserAdapter.ts +0 -92
- /package/dist/{types/e2e_tests → e2e_tests}/auto-completion.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/e2e-utils.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/extra-keybindings.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/history-navigation.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/sanity-checks.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests/performance-test.spec.d.ts → e2e_tests/signature-help.spec.d.ts} +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/syntax-highlighting.spec.d.ts +0 -0
- /package/dist/{types/e2e_tests → e2e_tests}/syntax-validation.spec.d.ts +0 -0
- /package/dist/{types/history-navigation.d.ts → history-navigation.d.ts} +0 -0
- /package/dist/{types/lang-cypher → lang-cypher}/autocomplete.d.ts +0 -0
- /package/dist/{types/lang-cypher → lang-cypher}/contants.test.d.ts +0 -0
- /package/dist/{types/lang-cypher → lang-cypher}/create-cypher-theme.d.ts +0 -0
- /package/dist/{types/lang-cypher → lang-cypher}/theme-icons.d.ts +0 -0
- /package/dist/{types/ndl-tokens-copy.d.ts → ndl-tokens-copy.d.ts} +0 -0
- /package/dist/{types/ndl-tokens-copy.test.d.ts → ndl-tokens-copy.test.d.ts} +0 -0
- /package/dist/{types/neo4j-setup.d.ts → neo4j-setup.d.ts} +0 -0
- /package/dist/{types/themes.d.ts → themes.d.ts} +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { EditorState, StateField } from '@codemirror/state';
|
|
2
|
+
import { showTooltip, Tooltip } from '@codemirror/view';
|
|
3
|
+
import { signatureHelp } from '@neo4j-cypher/language-support';
|
|
4
|
+
import { CypherConfig } from './lang-cypher';
|
|
5
|
+
|
|
6
|
+
function getTriggerCharacter(query: string, caretPosition: number) {
|
|
7
|
+
let i = caretPosition - 1;
|
|
8
|
+
let triggerCharacter = query.at(i);
|
|
9
|
+
|
|
10
|
+
// Discard all space characters. Note that a space can be more than just a ' '
|
|
11
|
+
while (/\s/.test(triggerCharacter) && i > 0) {
|
|
12
|
+
i -= 1;
|
|
13
|
+
triggerCharacter = query.at(i);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return triggerCharacter;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getSignatureHelpTooltip(
|
|
20
|
+
state: EditorState,
|
|
21
|
+
config: CypherConfig,
|
|
22
|
+
): Tooltip[] {
|
|
23
|
+
let result: Tooltip[] = [];
|
|
24
|
+
const schema = config.schema;
|
|
25
|
+
const ranges = state.selection.ranges;
|
|
26
|
+
const range = ranges.at(0);
|
|
27
|
+
|
|
28
|
+
if (schema && ranges.length === 1 && range.from === range.to) {
|
|
29
|
+
const caretPosition = range.from;
|
|
30
|
+
const query = state.doc.toString();
|
|
31
|
+
|
|
32
|
+
const triggerCharacter = getTriggerCharacter(query, caretPosition);
|
|
33
|
+
|
|
34
|
+
if (triggerCharacter === '(' || triggerCharacter === ',') {
|
|
35
|
+
const signatureHelpInfo = signatureHelp(query, schema, caretPosition);
|
|
36
|
+
const activeSignature = signatureHelpInfo.activeSignature;
|
|
37
|
+
const signatures = signatureHelpInfo.signatures;
|
|
38
|
+
const activeParameter = signatureHelpInfo.activeParameter;
|
|
39
|
+
|
|
40
|
+
if (
|
|
41
|
+
activeSignature !== undefined &&
|
|
42
|
+
activeSignature >= 0 &&
|
|
43
|
+
activeSignature < signatures.length &&
|
|
44
|
+
signatures[activeSignature].documentation !== undefined
|
|
45
|
+
) {
|
|
46
|
+
const signature = signatures[activeSignature];
|
|
47
|
+
const parameters = signature.parameters;
|
|
48
|
+
let doc = signature.documentation.toString();
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
activeParameter >= 0 &&
|
|
52
|
+
activeParameter <
|
|
53
|
+
(signatures[activeSignature].parameters?.length ?? 0)
|
|
54
|
+
) {
|
|
55
|
+
doc =
|
|
56
|
+
parameters[activeParameter].documentation.toString() + '\n\n' + doc;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
result = [
|
|
60
|
+
{
|
|
61
|
+
pos: caretPosition,
|
|
62
|
+
above: true,
|
|
63
|
+
strictSide: true,
|
|
64
|
+
arrow: true,
|
|
65
|
+
create: () => {
|
|
66
|
+
const div = document.createElement('div');
|
|
67
|
+
const methodName = document.createElement('div');
|
|
68
|
+
const argPlusDescription = document.createElement('div');
|
|
69
|
+
const separator = document.createElement('hr');
|
|
70
|
+
const lineBreak = document.createElement('br');
|
|
71
|
+
|
|
72
|
+
div.append(
|
|
73
|
+
...[methodName, separator, lineBreak, argPlusDescription],
|
|
74
|
+
);
|
|
75
|
+
div.className = 'cm-tooltip-signature-help';
|
|
76
|
+
|
|
77
|
+
methodName.innerText = signature.label;
|
|
78
|
+
argPlusDescription.innerText = doc;
|
|
79
|
+
|
|
80
|
+
return { dom: div };
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function signatureHelpTooltip(config: CypherConfig) {
|
|
92
|
+
return StateField.define<readonly Tooltip[]>({
|
|
93
|
+
create: (state) => getSignatureHelpTooltip(state, config),
|
|
94
|
+
|
|
95
|
+
update(tooltips, tr) {
|
|
96
|
+
if (!tr.docChanged && !tr.selection) return tooltips;
|
|
97
|
+
return getSignatureHelpTooltip(tr.state, config);
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
provide: (f) => showTooltip.computeN([f], (state) => state.field(f)),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
import { linter } from '@codemirror/lint';
|
|
1
|
+
import { Diagnostic, linter } from '@codemirror/lint';
|
|
2
2
|
import { Extension } from '@codemirror/state';
|
|
3
|
-
import { validateSyntax } from '@neo4j-cypher/language-support';
|
|
3
|
+
import { parserWrapper, validateSyntax } from '@neo4j-cypher/language-support';
|
|
4
4
|
import { DiagnosticSeverity } from 'vscode-languageserver-types';
|
|
5
|
+
import workerpool from 'workerpool';
|
|
5
6
|
import type { CypherConfig } from './lang-cypher';
|
|
7
|
+
import type { LinterTask, LintWorker } from './lint-worker';
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
10
|
+
// @ts-ignore ignore: https://v3.vitejs.dev/guide/features.html#import-with-query-suffixes
|
|
11
|
+
import WorkerURL from './lint-worker?url&worker';
|
|
12
|
+
|
|
13
|
+
const pool = workerpool.pool(WorkerURL as string, {
|
|
14
|
+
minWorkers: 2,
|
|
15
|
+
workerOpts: { type: 'module' },
|
|
16
|
+
workerTerminateTimeout: 2000,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
let lastSemanticJob: LinterTask | undefined;
|
|
6
20
|
|
|
7
21
|
export const cypherLinter: (config: CypherConfig) => Extension = (config) =>
|
|
8
22
|
linter((view) => {
|
|
@@ -10,8 +24,11 @@ export const cypherLinter: (config: CypherConfig) => Extension = (config) =>
|
|
|
10
24
|
return [];
|
|
11
25
|
}
|
|
12
26
|
|
|
13
|
-
|
|
14
|
-
|
|
27
|
+
const query = view.state.doc.toString();
|
|
28
|
+
const syntaxErrors = validateSyntax(query, config.schema ?? {});
|
|
29
|
+
|
|
30
|
+
return syntaxErrors.map(
|
|
31
|
+
(diagnostic): Diagnostic => ({
|
|
15
32
|
from: diagnostic.offsets.start,
|
|
16
33
|
to: diagnostic.offsets.end,
|
|
17
34
|
severity:
|
|
@@ -22,3 +39,52 @@ export const cypherLinter: (config: CypherConfig) => Extension = (config) =>
|
|
|
22
39
|
}),
|
|
23
40
|
);
|
|
24
41
|
});
|
|
42
|
+
|
|
43
|
+
export const semanticAnalysisLinter: (config: CypherConfig) => Extension = (
|
|
44
|
+
config,
|
|
45
|
+
) =>
|
|
46
|
+
linter(async (view) => {
|
|
47
|
+
if (!config.lint) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const query = view.state.doc.toString();
|
|
52
|
+
if (query.length === 0) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// we want to avoid the ANTLR4 reparse in the worker thread, this should hit our main thread cache
|
|
57
|
+
const parse = parserWrapper.parse(query);
|
|
58
|
+
if (parse.diagnostics.length !== 0) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
if (lastSemanticJob !== undefined && !lastSemanticJob.resolved) {
|
|
64
|
+
void lastSemanticJob.cancel();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const proxyWorker = (await pool.proxy()) as unknown as LintWorker;
|
|
68
|
+
lastSemanticJob = proxyWorker.validateSemantics(query);
|
|
69
|
+
const result = await lastSemanticJob;
|
|
70
|
+
|
|
71
|
+
return result.map((diag) => {
|
|
72
|
+
return {
|
|
73
|
+
from: diag.offsets.start,
|
|
74
|
+
to: diag.offsets.end,
|
|
75
|
+
severity:
|
|
76
|
+
diag.severity === DiagnosticSeverity.Error ? 'error' : 'warning',
|
|
77
|
+
message: diag.message,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
} catch (err) {
|
|
81
|
+
if (!(err instanceof workerpool.Promise.CancellationError)) {
|
|
82
|
+
console.error(String(err) + ' ' + query);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return [];
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
export const cleanupWorkers = () => {
|
|
89
|
+
void pool.terminate();
|
|
90
|
+
};
|
package/src/themes.ts
CHANGED
|
@@ -60,6 +60,7 @@ export const lightThemeConstants: ThemeOptions = {
|
|
|
60
60
|
paramDollar: light.syntax.regexp.hex(),
|
|
61
61
|
paramValue: light.syntax.regexp.hex(),
|
|
62
62
|
namespace: light.syntax.special.hex(),
|
|
63
|
+
consoleCommand: light.editor.fg.hex(),
|
|
63
64
|
},
|
|
64
65
|
};
|
|
65
66
|
|
|
@@ -101,6 +102,7 @@ export const darkThemeConstants: ThemeOptions = {
|
|
|
101
102
|
paramDollar: mirage.syntax.regexp.hex(),
|
|
102
103
|
paramValue: mirage.syntax.regexp.hex(),
|
|
103
104
|
namespace: mirage.syntax.special.hex(),
|
|
105
|
+
consoleCommand: mirage.editor.fg.hex(),
|
|
104
106
|
},
|
|
105
107
|
};
|
|
106
108
|
|