@@ -16,8 +16,8 @@ interface PawnFunction {
16
16
let pawnFuncCollection : Map < string , PawnFunction > = new Map ( ) ;
17
17
let pawnWords : Map < string , CompletionItem [ ] > = new Map ( ) ;
18
18
19
- let commentRegex = RegExp ( / ^ \/ \* / gm) ;
20
- let commentEndRegex = RegExp ( / ^ \* \/ / gm) ;
19
+ let commentRegex = RegExp ( / \/ \* / gm) ;
20
+ let commentEndRegex = RegExp ( / \* \/ / gm) ;
21
21
22
22
export const resetAutocompletes = ( ) => {
23
23
pawnFuncCollection . clear ( ) ;
@@ -27,13 +27,13 @@ export const parseDefine = (textDocument: TextDocument) => {
27
27
const regexDefine = / ^ ( \s * ) # d e f i n e \s + ( [ ^ \s ( ) ] { 1 , } ) \s + ( [ ^ \s ] { 1 , } ) $ / gm;
28
28
const content = textDocument . getText ( ) ;
29
29
const splitContent = content . split ( '\n' ) ;
30
- let excempt = false ;
30
+ let excempt = 0 ;
31
31
splitContent . forEach ( ( cont : string , index : number ) => {
32
32
if ( commentRegex . test ( cont ) ) {
33
- excempt = true ;
33
+ excempt ++ ;
34
34
} else if ( commentEndRegex . test ( cont ) ) {
35
- excempt = false ;
36
- } else if ( ! excempt ) {
35
+ excempt -- ;
36
+ } else if ( excempt === 0 ) {
37
37
var m ;
38
38
do {
39
39
m = regexDefine . exec ( cont ) ;
@@ -69,13 +69,13 @@ export const parsefuncsDefines = (textDocument: TextDocument) => {
69
69
const regex = / ^ ( \s * ) # d e f i n e \s + ( [ \S ] { 1 , } ) \( ( .* ?) \) / gm;
70
70
const content = textDocument . getText ( ) ;
71
71
const splitContent = content . split ( '\n' ) ;
72
- let excempt = false ;
72
+ let excempt = 0 ;
73
73
splitContent . forEach ( ( cont : string , index : number ) => {
74
74
if ( commentRegex . test ( cont ) ) {
75
- excempt = true ;
75
+ excempt ++ ;
76
76
} else if ( commentEndRegex . test ( cont ) ) {
77
- excempt = false ;
78
- } else if ( ! excempt ) {
77
+ excempt -- ;
78
+ } else if ( excempt === 0 ) {
79
79
var m ;
80
80
do {
81
81
m = regex . exec ( cont ) ;
@@ -149,31 +149,33 @@ export const parsefuncsDefines = (textDocument: TextDocument) => {
149
149
} ;
150
150
151
151
export const parseCustomSnip = ( textDocument : TextDocument ) => {
152
- const regexDefine = / ^ ( \s * ) \/ \/ # d e f i n e s n i p \s + ( [ ^ \s ] { 1 , } ) \s + ( .* ?) $ / gm;
152
+ const regexDefine = / ^ \/ \/ # s n i p p e t \s ( [ ^ \s ] { 1 , } ) \s ( [ ^ \s ] .{ 1 , } ) $ / gm;
153
+ const regexFunction = / ^ \/ \/ # f u n c t i o n \s ( [ \S ] { 1 , } ) \( ( .* ?) \) / gm;
153
154
const content = textDocument . getText ( ) ;
154
155
const splitContent = content . split ( '\n' ) ;
155
- let excempt = false ;
156
+
157
+ let excempt = 0 ;
156
158
splitContent . forEach ( ( cont : string , index : number ) => {
157
159
if ( commentRegex . test ( cont ) ) {
158
- excempt = true ;
160
+ excempt ++ ;
159
161
} else if ( commentEndRegex . test ( cont ) ) {
160
- excempt = false ;
161
- } else if ( ! excempt ) {
162
- var m ;
162
+ excempt -- ;
163
+ } else if ( excempt === 0 ) {
164
+ let fisrtReg ;
163
165
do {
164
- m = regexDefine . exec ( cont ) ;
165
- if ( m ) {
166
- let func = m [ 2 ] ;
167
- let args = m [ 3 ] ;
166
+ fisrtReg = regexDefine . exec ( cont ) ;
167
+ if ( fisrtReg ) {
168
+ let func = fisrtReg [ 1 ] ;
169
+ let args = fisrtReg [ 2 ] ;
168
170
const newSnip : CompletionItem = {
169
171
label : func ,
170
- kind : CompletionItemKind . Text ,
172
+ kind : CompletionItemKind . Function ,
171
173
insertText : args ,
172
174
documentation : `${ func } ${ args } `
173
175
} ;
174
176
const newDef : Definition = Location . create ( textDocument . uri , {
175
- start : { line : index , character : m . input . indexOf ( func ) } ,
176
- end : { line : index , character : m . input . indexOf ( func ) + func . length }
177
+ start : { line : index , character : fisrtReg . input . indexOf ( func ) } ,
178
+ end : { line : index , character : fisrtReg . input . indexOf ( func ) + func . length }
177
179
178
180
} ) ;
179
181
const pwnFun : PawnFunction = {
@@ -182,12 +184,70 @@ export const parseCustomSnip = (textDocument: TextDocument) => {
182
184
definition : newDef ,
183
185
type : 'customsnip'
184
186
} ;
185
- const findSnip = pawnFuncCollection . get ( func ) ;
186
- if ( findSnip === undefined ) {
187
- pawnFuncCollection . set ( func , pwnFun ) ;
187
+ pawnFuncCollection . set ( func , pwnFun ) ;
188
+ }
189
+ } while ( fisrtReg ) ;
190
+ var m ;
191
+ do {
192
+ m = regexFunction . exec ( cont ) ;
193
+ if ( m ) {
194
+ let func = m [ 1 ] ;
195
+ let args = m [ 2 ] ;
196
+ let doc : string = '' ;
197
+ let endDoc = - 1 ;
198
+ if ( splitContent [ index - 1 ] !== undefined ) endDoc = splitContent [ index - 1 ] . indexOf ( '*/' ) ;
199
+ if ( endDoc !== - 1 ) {
200
+ let startDoc = - 1 ;
201
+ let inNum = index ;
202
+ while ( inNum >= 0 ) {
203
+ inNum -- ;
204
+ if ( splitContent [ inNum ] === undefined ) continue ;
205
+ startDoc = splitContent [ inNum ] . indexOf ( '/*' ) ;
206
+ if ( startDoc !== - 1 ) {
207
+ if ( inNum === index ) {
208
+ doc = splitContent [ index ] ;
209
+ } else if ( inNum < index ) {
210
+ while ( inNum < index ) {
211
+ doc += splitContent [ inNum ] + '\n\n' ;
212
+ inNum ++ ;
213
+
214
+ }
215
+ }
216
+ break ;
217
+ }
218
+ }
219
+ }
220
+ doc = doc . replace ( '/*' , '' ) . replace ( '*/' , '' ) . trim ( ) ;
221
+ const newSnip : CompletionItem = {
222
+ label : func + '(' + args + ')' ,
223
+ kind : CompletionItemKind . Function ,
224
+ insertText : func + '(' + args + ')' ,
225
+ documentation : doc ,
226
+ } ;
227
+ const newDef : Definition = Location . create ( textDocument . uri , {
228
+ start : { line : index , character : m . input . indexOf ( func ) } ,
229
+ end : { line : index , character : m . input . indexOf ( func ) + func . length }
230
+
231
+ } ) ;
232
+ let params : ParameterInformation [ ] = [ ] ;
233
+ if ( args . trim ( ) . length > 0 ) {
234
+ params = args . split ( ',' ) . map ( ( value ) => ( { label : value . trim ( ) } ) ) ;
188
235
} else {
189
- if ( findSnip . type === 'macrofunction' || findSnip . type === 'macrodefine' ) pawnFuncCollection . set ( func , pwnFun ) ;
236
+ params = [ ] ;
237
+ }
238
+ const pwnFun : PawnFunction = {
239
+ textDocument : textDocument ,
240
+ definition : newDef ,
241
+ completion : newSnip ,
242
+ params,
243
+ type : 'customsnip'
244
+ } ;
245
+ const indexPos = func . indexOf ( ':' ) ;
246
+ if ( indexPos !== - 1 ) {
247
+ const resOut = / : ( .* ) / gm. exec ( func ) ;
248
+ if ( resOut ) func = resOut [ 1 ] ;
190
249
}
250
+ pawnFuncCollection . set ( func , pwnFun ) ;
191
251
}
192
252
} while ( m ) ;
193
253
}
@@ -198,13 +258,13 @@ export const parsefuncs = (textDocument: TextDocument) => {
198
258
const regex = / ^ ( \s * ) ( p u b l i c | s t o c k | f u n c t i o n | f u n c ) \s + ( [ \S ] { 1 , } ) \( ( .* ?) \) / gm;
199
259
const content = textDocument . getText ( ) ;
200
260
const splitContent = content . split ( '\n' ) ;
201
- let excempt = false ;
261
+ let excempt = 0 ;
202
262
splitContent . forEach ( ( cont : string , index : number ) => {
203
263
if ( commentRegex . test ( cont ) ) {
204
- excempt = true ;
264
+ excempt ++ ;
205
265
} else if ( commentEndRegex . test ( cont ) ) {
206
- excempt = false ;
207
- } else if ( ! excempt ) {
266
+ excempt -- ;
267
+ } else if ( excempt === 0 ) {
208
268
var m ;
209
269
do {
210
270
m = regex . exec ( cont ) ;
@@ -281,13 +341,13 @@ export const parsefuncsNonPrefix = (textDocument: TextDocument) => {
281
341
const regex = / ^ ( [ \S ] { 1 , } ) \( ( .* ?) \) / gm;
282
342
const content = textDocument . getText ( ) ;
283
343
const splitContent = content . split ( '\n' ) ;
284
- let excempt = false ;
344
+ let excempt = 0 ;
285
345
splitContent . forEach ( ( cont : string , index : number ) => {
286
346
if ( commentRegex . test ( cont ) ) {
287
- excempt = true ;
347
+ excempt ++ ;
288
348
} else if ( commentEndRegex . test ( cont ) ) {
289
- excempt = false ;
290
- } else if ( ! excempt ) {
349
+ excempt -- ;
350
+ } else if ( excempt === 0 ) {
291
351
var m ;
292
352
do {
293
353
m = regex . exec ( cont ) ;
@@ -364,13 +424,13 @@ export const parseNatives = (textDocument: TextDocument) => {
364
424
const regex = / ^ ( \s * ) ( n a t i v e ) \s ( [ \S ] { 1 , } ) \( ( .* ?) \) / gm;
365
425
const content = textDocument . getText ( ) ;
366
426
const splitContent = content . split ( '\n' ) ;
367
- let excempt = false ;
427
+ let excempt = 0 ;
368
428
splitContent . forEach ( ( cont : string , index : number ) => {
369
429
if ( commentRegex . test ( cont ) ) {
370
- excempt = true ;
430
+ excempt ++ ;
371
431
} else if ( commentEndRegex . test ( cont ) ) {
372
- excempt = false ;
373
- } else if ( ! excempt ) {
432
+ excempt -- ;
433
+ } else if ( excempt === 0 ) {
374
434
var m ;
375
435
do {
376
436
m = regex . exec ( cont ) ;
@@ -435,7 +495,7 @@ export const parseNatives = (textDocument: TextDocument) => {
435
495
if ( findSnip === undefined ) {
436
496
pawnFuncCollection . set ( func , pwnFun ) ;
437
497
} else {
438
- pawnFuncCollection . set ( func , pwnFun ) ;
498
+ if ( findSnip . type !== 'customsnip' ) pawnFuncCollection . set ( func , pwnFun ) ;
439
499
}
440
500
}
441
501
} while ( m ) ;
@@ -449,13 +509,13 @@ export const parseWords = (textDocument: TextDocument) => {
449
509
const splitContent = content . split ( '\n' ) ;
450
510
const words : string [ ] = [ ] ;
451
511
const wordCompletion : CompletionItem [ ] = [ ] ;
452
- let excempt = false ;
512
+ let excempt = 0 ;
453
513
splitContent . forEach ( ( cont : string , index : number ) => {
454
514
if ( commentRegex . test ( cont ) ) {
455
- excempt = true ;
515
+ excempt ++ ;
456
516
} else if ( commentEndRegex . test ( cont ) ) {
457
- excempt = false ;
458
- } else if ( ! excempt ) {
517
+ excempt -- ;
518
+ } else if ( excempt === 0 && ! RegExp ( / ^ \/ \/ / gm ) . test ( cont . trim ( ) ) ) {
459
519
var m ;
460
520
do {
461
521
m = regex . exec ( cont ) ;
@@ -511,11 +571,13 @@ const isParseAllowed = async (textDocument: TextDocument) => {
511
571
return true ;
512
572
} ;
513
573
514
- export const parseSnippets = async ( textDocument : TextDocument ) => {
574
+ export const parseSnippets = async ( textDocument : TextDocument , reset : boolean = true ) => {
515
575
const ext = path . extname ( textDocument . uri ) ;
516
576
if ( ext !== ".pwn" && ext !== ".inc" ) return false ;
517
- pawnFuncCollection . forEach ( ( value : PawnFunction , key : string ) => { if ( value . textDocument . uri === textDocument . uri ) pawnFuncCollection . delete ( key ) ; } ) ;
518
- pawnWords . delete ( textDocument . uri ) ;
577
+ if ( reset ) {
578
+ pawnFuncCollection . forEach ( ( value : PawnFunction , key : string ) => { if ( value . textDocument . uri === textDocument . uri ) pawnFuncCollection . delete ( key ) ; } ) ;
579
+ pawnWords . delete ( textDocument . uri ) ;
580
+ }
519
581
if ( ! await isParseAllowed ( textDocument ) ) return ;
520
582
521
583
const allowDefine = ( await connection . workspace . getConfiguration ( { section : 'pawn.language.allowDefine' } ) ) as true | false | null ;
0 commit comments