@neo4j-cypher/react-codemirror 2.0.0-next.12 → 2.0.0-next.14
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 +15 -0
- package/dist/e2e_tests/autoCompletion.spec.js +13 -7
- package/dist/e2e_tests/autoCompletion.spec.js.map +1 -1
- package/dist/e2e_tests/signatureHelp.spec.js +11 -8
- package/dist/e2e_tests/signatureHelp.spec.js.map +1 -1
- package/dist/lang-cypher/autocomplete.js +43 -57
- package/dist/lang-cypher/autocomplete.js.map +1 -1
- package/dist/lang-cypher/createCypherTheme.js +3 -0
- package/dist/lang-cypher/createCypherTheme.js.map +1 -1
- package/dist/lang-cypher/langCypher.d.ts +0 -1
- package/dist/lang-cypher/langCypher.js.map +1 -1
- package/dist/lang-cypher/signatureHelp.js +22 -7
- package/dist/lang-cypher/signatureHelp.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/e2e_tests/autoCompletion.spec.tsx +22 -13
- package/src/e2e_tests/signatureHelp.spec.tsx +12 -8
- package/src/lang-cypher/autocomplete.ts +44 -59
- package/src/lang-cypher/createCypherTheme.ts +3 -0
- package/src/lang-cypher/langCypher.ts +0 -1
- package/src/lang-cypher/signatureHelp.ts +27 -9
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
1
2
|
import { testData } from '@neo4j-cypher/language-support';
|
|
2
3
|
import { expect, test } from '@playwright/experimental-ct-react';
|
|
3
4
|
import { Locator } from 'playwright/test';
|
|
@@ -10,6 +11,8 @@ type TooltipExpectations = {
|
|
|
10
11
|
excludes?: string[];
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
const importCsvProc = testData.mockSchema.procedures['apoc.import.csv'];
|
|
15
|
+
|
|
13
16
|
function testTooltip(tooltip: Locator, expectations: TooltipExpectations) {
|
|
14
17
|
const includes = expectations.includes ?? [];
|
|
15
18
|
const excludes = expectations.excludes ?? [];
|
|
@@ -83,8 +86,9 @@ test('Signature help shows the description for the first argument', async ({
|
|
|
83
86
|
|
|
84
87
|
await testTooltip(tooltip, {
|
|
85
88
|
includes: [
|
|
86
|
-
'
|
|
87
|
-
|
|
89
|
+
testData.mockSchema.procedures['apoc.import.csv'].argumentDescription[0]
|
|
90
|
+
.description,
|
|
91
|
+
testData.mockSchema.procedures['apoc.import.csv'].description,
|
|
88
92
|
],
|
|
89
93
|
});
|
|
90
94
|
});
|
|
@@ -103,8 +107,8 @@ test('Signature help shows the description for the first argument when the curso
|
|
|
103
107
|
|
|
104
108
|
await testTooltip(tooltip, {
|
|
105
109
|
includes: [
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
importCsvProc.argumentDescription[0].description,
|
|
111
|
+
importCsvProc.description,
|
|
108
112
|
],
|
|
109
113
|
});
|
|
110
114
|
});
|
|
@@ -127,8 +131,8 @@ test('Signature help shows the description for the second argument', async ({
|
|
|
127
131
|
|
|
128
132
|
await testTooltip(tooltip, {
|
|
129
133
|
includes: [
|
|
130
|
-
|
|
131
|
-
|
|
134
|
+
importCsvProc.argumentDescription[1].description,
|
|
135
|
+
importCsvProc.description,
|
|
132
136
|
],
|
|
133
137
|
});
|
|
134
138
|
});
|
|
@@ -147,8 +151,8 @@ test('Signature help shows the description for the second argument when the curs
|
|
|
147
151
|
|
|
148
152
|
await testTooltip(tooltip, {
|
|
149
153
|
includes: [
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
importCsvProc.argumentDescription[1].description,
|
|
155
|
+
importCsvProc.description,
|
|
152
156
|
],
|
|
153
157
|
});
|
|
154
158
|
});
|
|
@@ -77,73 +77,56 @@ export const cypherAutocomplete: (config: CypherConfig) => CompletionSource =
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
const options = autocomplete(
|
|
80
|
-
|
|
80
|
+
// TODO This is a temporary hack because completions are not working well
|
|
81
|
+
documentText.slice(0, context.pos),
|
|
81
82
|
config.schema ?? {},
|
|
82
83
|
context.pos,
|
|
83
84
|
context.explicit,
|
|
84
85
|
);
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const newDiv = document.createElement('div');
|
|
87
|
+
return {
|
|
88
|
+
from: context.matchBefore(/(\w|\$)*$/).from,
|
|
89
|
+
options: options.map((o) => {
|
|
90
|
+
let maybeInfo = {};
|
|
91
|
+
let emptyInfo = true;
|
|
92
|
+
const newDiv = document.createElement('div');
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
94
|
+
if (o.signature) {
|
|
95
|
+
const header = document.createElement('p');
|
|
96
|
+
header.setAttribute('class', 'cm-completionInfo-signature');
|
|
97
|
+
header.textContent = o.signature;
|
|
98
|
+
if (header.textContent.length > 0) {
|
|
99
|
+
emptyInfo = false;
|
|
100
|
+
newDiv.appendChild(header);
|
|
102
101
|
}
|
|
102
|
+
}
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
104
|
+
if (o.documentation) {
|
|
105
|
+
const paragraph = document.createElement('p');
|
|
106
|
+
paragraph.textContent = getDocString(o.documentation);
|
|
107
|
+
if (paragraph.textContent.length > 0) {
|
|
108
|
+
emptyInfo = false;
|
|
109
|
+
newDiv.appendChild(paragraph);
|
|
111
110
|
}
|
|
111
|
+
}
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
const deprecated =
|
|
119
|
-
o.tags?.find((tag) => tag === CompletionItemTag.Deprecated) ??
|
|
120
|
-
false;
|
|
121
|
-
// The negative boost moves the deprecation down the list
|
|
122
|
-
// so we offer the user the completions that are
|
|
123
|
-
// deprecated the last
|
|
124
|
-
const maybeDeprecated = deprecated
|
|
125
|
-
? { boost: -99, deprecated: true }
|
|
126
|
-
: {};
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
label: o.label,
|
|
130
|
-
type: completionKindToCodemirrorIcon(o.kind),
|
|
131
|
-
apply:
|
|
132
|
-
o.kind === CompletionItemKind.Snippet
|
|
133
|
-
? // codemirror requires an empty snippet space to be able to tab out of the completion
|
|
134
|
-
snippet((o.insertText ?? o.label) + '${}')
|
|
135
|
-
: undefined,
|
|
136
|
-
detail: o.detail,
|
|
137
|
-
...maybeDeprecated,
|
|
138
|
-
...maybeInfo,
|
|
113
|
+
if (!emptyInfo) {
|
|
114
|
+
maybeInfo = {
|
|
115
|
+
info: () => Promise.resolve(newDiv),
|
|
139
116
|
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
117
|
+
}
|
|
118
|
+
const deprecated =
|
|
119
|
+
o.tags?.find((tag) => tag === CompletionItemTag.Deprecated) ?? false;
|
|
120
|
+
// The negative boost moves the deprecation down the list
|
|
121
|
+
// so we offer the user the completions that are
|
|
122
|
+
// deprecated the last
|
|
123
|
+
const maybeDeprecated = deprecated
|
|
124
|
+
? { boost: -99, deprecated: true }
|
|
125
|
+
: {};
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
label: o.insertText ? o.insertText : o.label,
|
|
129
|
+
displayLabel: o.label,
|
|
147
130
|
type: completionKindToCodemirrorIcon(o.kind),
|
|
148
131
|
apply:
|
|
149
132
|
o.kind === CompletionItemKind.Snippet
|
|
@@ -151,7 +134,9 @@ export const cypherAutocomplete: (config: CypherConfig) => CompletionSource =
|
|
|
151
134
|
snippet((o.insertText ?? o.label) + '${}')
|
|
152
135
|
: undefined,
|
|
153
136
|
detail: o.detail,
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
137
|
+
...maybeDeprecated,
|
|
138
|
+
...maybeInfo,
|
|
139
|
+
};
|
|
140
|
+
}),
|
|
141
|
+
};
|
|
157
142
|
};
|
|
@@ -121,6 +121,9 @@ export const createCypherTheme = ({
|
|
|
121
121
|
'& .cm-signature-help-panel-name': {
|
|
122
122
|
padding: '5px',
|
|
123
123
|
},
|
|
124
|
+
'& .cm-signature-help-panel-arg-description': {
|
|
125
|
+
padding: '5px',
|
|
126
|
+
},
|
|
124
127
|
'& .cm-signature-help-panel-description': {
|
|
125
128
|
padding: '5px',
|
|
126
129
|
},
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { EditorState, StateField } from '@codemirror/state';
|
|
2
2
|
import { showTooltip, Tooltip } from '@codemirror/view';
|
|
3
3
|
import { signatureHelp } from '@neo4j-cypher/language-support';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
MarkupContent,
|
|
6
|
+
SignatureInformation,
|
|
7
|
+
} from 'vscode-languageserver-types';
|
|
5
8
|
import { CypherConfig } from './langCypher';
|
|
6
9
|
import { getDocString } from './utils';
|
|
7
10
|
|
|
@@ -38,24 +41,32 @@ const createSignatureHelpElement =
|
|
|
38
41
|
|
|
39
42
|
const signatureLabel = document.createElement('div');
|
|
40
43
|
signatureLabel.className = 'cm-signature-help-panel-name';
|
|
41
|
-
|
|
44
|
+
const methodName = signature.label.slice(0, signature.label.indexOf('('));
|
|
45
|
+
const returnType = signature.label.slice(signature.label.indexOf(')') + 1);
|
|
46
|
+
signatureLabel.appendChild(document.createTextNode(`${methodName}(`));
|
|
47
|
+
let currentParamDescription: string | undefined = undefined;
|
|
42
48
|
|
|
43
49
|
parameters.forEach((param, index) => {
|
|
44
|
-
if (typeof param.
|
|
50
|
+
if (typeof param.label === 'string') {
|
|
45
51
|
const span = document.createElement('span');
|
|
46
|
-
span.appendChild(document.createTextNode(param.
|
|
52
|
+
span.appendChild(document.createTextNode(param.label));
|
|
47
53
|
if (index !== parameters.length - 1) {
|
|
48
54
|
span.appendChild(document.createTextNode(', '));
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
if (index === activeParameter) {
|
|
52
58
|
span.className = 'cm-signature-help-panel-current-argument';
|
|
59
|
+
const paramDoc = param.documentation;
|
|
60
|
+
currentParamDescription = MarkupContent.is(paramDoc)
|
|
61
|
+
? paramDoc.value
|
|
62
|
+
: paramDoc;
|
|
53
63
|
}
|
|
54
64
|
signatureLabel.appendChild(span);
|
|
55
65
|
}
|
|
56
66
|
});
|
|
57
67
|
|
|
58
68
|
signatureLabel.appendChild(document.createTextNode(')'));
|
|
69
|
+
signatureLabel.appendChild(document.createTextNode(returnType));
|
|
59
70
|
|
|
60
71
|
contents.appendChild(signatureLabel);
|
|
61
72
|
|
|
@@ -64,11 +75,18 @@ const createSignatureHelpElement =
|
|
|
64
75
|
|
|
65
76
|
contents.appendChild(separator);
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
if (currentParamDescription !== undefined) {
|
|
79
|
+
const argDescription = document.createElement('div');
|
|
80
|
+
argDescription.className = 'cm-signature-help-panel-arg-description';
|
|
81
|
+
argDescription.appendChild(
|
|
82
|
+
document.createTextNode(currentParamDescription),
|
|
83
|
+
);
|
|
84
|
+
contents.appendChild(argDescription);
|
|
85
|
+
}
|
|
86
|
+
const methodDescription = document.createElement('div');
|
|
87
|
+
methodDescription.className = 'cm-signature-help-panel-description';
|
|
88
|
+
methodDescription.appendChild(document.createTextNode(doc));
|
|
89
|
+
contents.appendChild(methodDescription);
|
|
72
90
|
|
|
73
91
|
return { dom };
|
|
74
92
|
};
|