@@ -379,23 +379,77 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
379
379
380
380
return await this . findExistingPgbsdindent ( workspace ) ;
381
381
}
382
-
382
+
383
+ private runPreIndent ( contents : string ) : string {
384
+ function replace ( regex : any , replacement : any ) {
385
+ contents = contents . replace ( regex , replacement )
386
+ }
387
+
388
+ // Convert // comments to /* */
389
+ replace ( / ^ ( [ \t ] * ) \/ \/ ( .* ) $ / gm, '$1/* $2 */' ) ;
390
+
391
+ // Adjust dash-protected block comments so indent won't change them
392
+ replace ( / \/ \* \+ - - - / gm, '/*---X_X' ) ;
393
+
394
+ // Prevent indenting of code in 'extern "C"' blocks
395
+ // we replace the braces with comments which we'll reverse later
396
+ replace ( / ( ^ # i f d e f [ \t ] + _ _ c p l u s p l u s .* \n e x t e r n [ \t ] + " C " [ \t ] * \n ) \{ [ \t ] * $ / gm,
397
+ '$1/\* Open extern "C" */' ) ;
398
+ replace ( / ( ^ # i f d e f [ \t ] + _ _ c p l u s p l u s .* \n ) \} [ \t ] * $ / gm,
399
+ '$1/\* Close extern "C" */' ) ;
400
+
401
+ // Protect wrapping in CATALOG()
402
+ replace ( / ^ ( C A T A L O G \( .* ) $ / gm, '/*$1*/' ) ;
403
+
404
+ return contents ;
405
+ }
406
+
407
+ private runPostIndent ( contents : string ) : string {
408
+ function replace ( regex : any , replacement : any ) {
409
+ contents = contents . replace ( regex , replacement ) ;
410
+ }
411
+
412
+ // Restore CATALOG lines
413
+ replace ( / ^ \/ \* ( C A T A L O G \( .* ) \* \/ $ / gm, '$1' ) ;
414
+
415
+ // put back braces for extern "C"
416
+ replace ( / ^ \/ \* O p e n e x t e r n " C " \* \/ / gm, '{' ) ;
417
+ replace ( / ^ \/ \* C l o s e e x t e r n " C " \* \/ $ / gm, '}' ) ;
418
+
419
+ // Undo change of dash-protected block comments
420
+ replace ( / \/ \* - - - X _ X / gm, '/* ---' ) ;
421
+
422
+ // Fix run-together comments to have a tab between them
423
+ replace ( / \* \/ ( \/ \* .* \* \/ ) $ / gm, '*/\t$1' ) ;
424
+
425
+ // Use a single space before '*' in function return types
426
+ replace ( / ^ ( [ A - Z a - z _ ] \S * ) [ \t ] + \* $ / gm, '$1 *' ) ;
427
+
428
+ return contents ;
429
+ }
430
+
383
431
private async runPgindentInternal ( document : vscode . TextDocument ,
384
432
pg_bsd_indent : vscode . Uri ) {
385
433
/*
386
434
* We use pg_bsd_indent directly instead of pgindent because:
387
435
* - different pgindent versions behaves differently
388
436
* - direct call to pg_bsd_indent is faster
437
+ * - pgindent creates temp files which are not removed if error
438
+ * happens - we can not track these files (main reason)
389
439
*/
440
+
390
441
let typedefs = await this . getTypedefs ( utils . joinPath ( pg_bsd_indent , '..' ) ) ;
442
+ const contents = this . runPreIndent ( document . getText ( ) ) ;
391
443
const { stdout} = await utils . execShell (
392
444
pg_bsd_indent . fsPath , [
393
445
...PgindentDocumentFormatterProvider . pg_bsd_indentDefaultFlags ,
394
446
`-U${ typedefs . fsPath } ` ] ,
395
- { stdin : document . getText ( ) } ) ;
447
+ { stdin : contents } ) ;
448
+ const result = this . runPostIndent ( stdout ) ;
449
+
396
450
/* On success cache pg_bsd_indent path */
397
451
this . savedPgbsdPath = pg_bsd_indent ;
398
- return stdout ;
452
+ return result ;
399
453
}
400
454
401
455
private async runPgindent ( document : vscode . TextDocument ,
0 commit comments