@@ -6,18 +6,22 @@ import {
6
6
CompletionItemKind ,
7
7
} from 'vscode-languageserver-types' ;
8
8
import { DbSchema } from '../dbSchema' ;
9
- import CypherLexer from '../generated-parser/CypherLexer ' ;
9
+ import CypherLexer from '../generated-parser/CypherCmdLexer ' ;
10
10
import CypherParser , {
11
11
Expression2Context ,
12
- } from '../generated-parser/CypherParser ' ;
12
+ } from '../generated-parser/CypherCmdParser ' ;
13
13
import { rulesDefiningVariables } from '../helpers' ;
14
14
import {
15
15
CypherTokenType ,
16
16
lexerKeywords ,
17
17
lexerSymbols ,
18
18
tokenNames ,
19
19
} from '../lexerSymbols' ;
20
- import { EnrichedParsingResult , ParsingResult } from '../parserWrapper' ;
20
+ import {
21
+ consoleCommandEnabled ,
22
+ EnrichedParsingResult ,
23
+ ParsingResult ,
24
+ } from '../parserWrapper' ;
21
25
22
26
const uniq = < T > ( arr : T [ ] ) => Array . from ( new Set ( arr ) ) ;
23
27
@@ -125,17 +129,27 @@ const namespacedCompletion = (
125
129
}
126
130
} ;
127
131
128
- function getTokenCandidates (
132
+ function getTokenCompletions (
129
133
candidates : CandidatesCollection ,
130
134
ignoredTokens : Set < number > ,
131
- ) {
135
+ ) : CompletionItem [ ] {
132
136
const tokenEntries = candidates . tokens . entries ( ) ;
133
137
134
- const tokenCandidates = Array . from ( tokenEntries ) . flatMap ( ( value ) => {
138
+ const completions = Array . from ( tokenEntries ) . flatMap ( ( value ) => {
135
139
const [ tokenNumber , followUpList ] = value ;
136
140
137
141
if ( ! ignoredTokens . has ( tokenNumber ) ) {
138
- const firstToken = tokenNames [ tokenNumber ] ;
142
+ const isConsoleCommand =
143
+ lexerSymbols [ tokenNumber ] === CypherTokenType . consoleCommand ;
144
+
145
+ const kind = isConsoleCommand
146
+ ? CompletionItemKind . Event
147
+ : CompletionItemKind . Keyword ;
148
+
149
+ const firstToken = isConsoleCommand
150
+ ? tokenNames [ tokenNumber ] . toLowerCase ( )
151
+ : tokenNames [ tokenNumber ] ;
152
+
139
153
const followUpIndexes = followUpList . indexes ;
140
154
const firstIgnoredToken = followUpIndexes . findIndex ( ( t ) =>
141
155
ignoredTokens . has ( t ) ,
@@ -151,21 +165,28 @@ function getTokenCandidates(
151
165
if ( firstToken === undefined ) {
152
166
return [ ] ;
153
167
} else if ( followUpString === '' ) {
154
- return [ firstToken ] ;
168
+ return [ { label : firstToken , kind } ] ;
155
169
} else {
156
- const followUp = firstToken + ' ' + followUpString ;
170
+ const followUp =
171
+ firstToken +
172
+ ' ' +
173
+ ( isConsoleCommand ? followUpString . toLowerCase ( ) : followUpString ) ;
174
+
157
175
if ( followUpList . optional ) {
158
- return [ firstToken , followUp ] ;
176
+ return [
177
+ { label : firstToken , kind } ,
178
+ { label : followUp , kind } ,
179
+ ] ;
159
180
}
160
181
161
- return [ followUp ] ;
182
+ return [ { label : followUp , kind } ] ;
162
183
}
163
184
} else {
164
185
return [ ] ;
165
186
}
166
187
} ) ;
167
188
168
- return tokenCandidates ;
189
+ return completions ;
169
190
}
170
191
171
192
const parameterCompletions = (
@@ -306,6 +327,15 @@ export function completionCoreCompletion(
306
327
CypherParser . RULE_propertyKeyName ,
307
328
CypherParser . RULE_variable ,
308
329
330
+ // Either enable the helper rules for lexer clashes,
331
+ // or collect all console commands like below with symbolicNameString
332
+ ...( consoleCommandEnabled ( )
333
+ ? [
334
+ CypherParser . RULE_useCompletionRule ,
335
+ CypherParser . RULE_listCompletionRule ,
336
+ ]
337
+ : [ CypherParser . RULE_consoleCommand ] ) ,
338
+
309
339
// Because of the overlap of keywords and identifiers in cypher
310
340
// We will suggest keywords when users type identifiers as well
311
341
// To avoid this we want custom completion for identifiers
@@ -317,7 +347,11 @@ export function completionCoreCompletion(
317
347
// Keep only keywords as suggestions
318
348
const ignoredTokens = new Set < number > (
319
349
Object . entries ( lexerSymbols )
320
- . filter ( ( [ , type ] ) => type !== CypherTokenType . keyword )
350
+ . filter (
351
+ ( [ , type ] ) =>
352
+ type !== CypherTokenType . keyword &&
353
+ type !== CypherTokenType . consoleCommand ,
354
+ )
321
355
. map ( ( [ token ] ) => Number ( token ) ) ,
322
356
) ;
323
357
@@ -427,17 +461,24 @@ export function completionCoreCompletion(
427
461
] ;
428
462
}
429
463
}
464
+
465
+ // These are simple tokens that get completed as the wrong kind, due to a lexer conflict
466
+ if ( ruleNumber === CypherParser . RULE_useCompletionRule ) {
467
+ return [ { label : 'use' , kind : CompletionItemKind . Event } ] ;
468
+ }
469
+
470
+ if ( ruleNumber === CypherParser . RULE_listCompletionRule ) {
471
+ return [ { label : 'list' , kind : CompletionItemKind . Event } ] ;
472
+ }
473
+
430
474
return [ ] ;
431
475
} ,
432
476
) ;
433
477
434
- const tokenCandidates = getTokenCandidates ( candidates , ignoredTokens ) ;
435
- const tokenCompletions : CompletionItem [ ] = tokenCandidates . map ( ( t ) => ( {
436
- label : t ,
437
- kind : CompletionItemKind . Keyword ,
438
- } ) ) ;
439
-
440
- return [ ...ruleCompletions , ...tokenCompletions ] ;
478
+ return [
479
+ ...ruleCompletions ,
480
+ ...getTokenCompletions ( candidates , ignoredTokens ) ,
481
+ ] ;
441
482
}
442
483
443
484
type CompletionHelperArgs = {
0 commit comments