@@ -21,9 +21,22 @@ class LineDiffGroup {
2121 /* Small trick to make all lines end with new line */
2222 diff . lines . push ( '' ) ;
2323 edits . push ( vscode . TextEdit . insert ( document . lineAt ( diff . num ) . range . start ,
24- diff . lines . join ( '\n' ) ) ) ;
24+ diff . lines . join ( '\n' ) ) ) ;
25+ try {
26+ continue ;
27+ } catch ( err : any ) {
28+ if ( ! ( document . lineCount < diff . num && diff . lines [ 0 ] . startsWith ( '/**INDENT' ) ) )
29+ throw err ;
30+ }
31+
32+ /*
33+ * pg_bsd_indent complains if there is no new line
34+ * at the end of file, so we add it ourselves
35+ */
36+ const lastLine = document . lineAt ( document . lineCount - 1 ) ;
37+ const lastPos = document . lineAt ( document . lineCount - 1 ) . range . start ;
38+ edits . push ( vscode . TextEdit . insert ( lastPos , `${ lastLine . text } \n` ) ) ;
2539 } else {
26-
2740 /*
2841 * document.lineAt().range returns range of line
2942 * NOT including new line, so just passing it
@@ -269,6 +282,7 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
269282 ] ;
270283
271284 private savedPgbsdPath ?: vscode . Uri ;
285+ private savedProcessedTypedef ?: vscode . Uri ;
272286 constructor ( private logger : utils . ILogger ) { }
273287
274288 private async findExistingPgbsdindent ( workspace : vscode . WorkspaceFolder ) {
@@ -365,6 +379,45 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
365379 }
366380 }
367381
382+ private async getProcessedTypedefs ( pg_bsd_indent : vscode . Uri ) {
383+ const processedTypedef = utils . joinPath ( vscode . Uri . file ( os . tmpdir ( ) ) ,
384+ 'pg-hacker-helper.typedefs.list' ) ;
385+
386+ if ( this . savedProcessedTypedef ) {
387+ if ( await utils . fileExists ( this . savedProcessedTypedef ) )
388+ return this . savedProcessedTypedef ;
389+
390+ this . savedProcessedTypedef = undefined ;
391+ } else if ( await utils . fileExists ( processedTypedef ) ) {
392+ /* After restart be */
393+ this . savedProcessedTypedef = processedTypedef ;
394+ return processedTypedef ;
395+ }
396+
397+ /*
398+ * Add and remove some entries from `typedefs.list` file
399+ * downloaded from buildfarm
400+ */
401+ const rawTypedef = await this . getTypedefs ( pg_bsd_indent ) ;
402+ const contents = await utils . readFile ( rawTypedef ) ;
403+ const entries = new Set ( contents . split ( '\n' ) ) ;
404+
405+ [
406+ 'ANY' , 'FD_SET' , 'U' , 'abs' , 'allocfunc' , 'boolean' , 'date' ,
407+ 'digit' , 'ilist' , 'interval' , 'iterator' , 'other' , 'pointer' ,
408+ 'printfunc' , 'reference' , 'string' , 'timestamp' , 'type' , 'wrap'
409+ ] . forEach ( e => entries . delete ( e ) ) ;
410+
411+ entries . add ( 'bool' ) ;
412+ entries . delete ( '' ) ;
413+ const arr = Array . from ( entries . values ( ) ) ;
414+ arr . sort ( ) ;
415+
416+ await utils . writeFile ( processedTypedef , arr . join ( '\n' ) ) ;
417+ this . savedProcessedTypedef = processedTypedef ;
418+ return processedTypedef ;
419+ }
420+
368421 private async getPgbsdindent ( workspace : vscode . WorkspaceFolder ) {
369422 if ( this . savedPgbsdPath ) {
370423 return this . savedPgbsdPath ;
@@ -394,9 +447,9 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
394447 // Prevent indenting of code in 'extern "C"' blocks
395448 // we replace the braces with comments which we'll reverse later
396449 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" */' ) ;
450+ '$1/* Open extern "C" */' ) ;
398451 replace ( / ( ^ # i f d e f [ \t ] + _ _ c p l u s p l u s .* \n ) \} [ \t ] * $ / gm,
399- '$1/\ * Close extern "C" */' ) ;
452+ '$1/* Close extern "C" */' ) ;
400453
401454 // Protect wrapping in CATALOG()
402455 replace ( / ^ ( C A T A L O G \( .* ) $ / gm, '/*$1*/' ) ;
@@ -438,18 +491,27 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
438491 * happens - we can not track these files (main reason)
439492 */
440493
441- let typedefs = await this . getTypedefs ( utils . joinPath ( pg_bsd_indent , '..' ) ) ;
442- const contents = this . runPreIndent ( document . getText ( ) ) ;
443- const { stdout} = await utils . execShell (
494+ let typedefs = await this . getProcessedTypedefs ( pg_bsd_indent ) ;
495+ const preProcessed = this . runPreIndent ( document . getText ( ) ) ;
496+ const { stdout : processed } = await utils . execShell (
444497 pg_bsd_indent . fsPath , [
445498 ...PgindentDocumentFormatterProvider . pg_bsd_indentDefaultFlags ,
446499 `-U${ typedefs . fsPath } ` ] ,
447- { stdin : contents } ) ;
448- const result = this . runPostIndent ( stdout ) ;
500+ {
501+ stdin : preProcessed ,
502+ /*
503+ * pg_bsd_indent returns non-zero code if it encountered some
504+ * errors, but for us they are not important. i.e. no newline
505+ * at end of file causes to return code 1
506+ */
507+ throwOnError : false ,
508+ } ) ;
509+ const postProcessed = this . runPostIndent ( processed ) ;
510+ // const result = stdout;
449511
450512 /* On success cache pg_bsd_indent path */
451513 this . savedPgbsdPath = pg_bsd_indent ;
452- return result ;
514+ return postProcessed ;
453515 }
454516
455517 private async runPgindent ( document : vscode . TextDocument ,
@@ -490,7 +552,7 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
490552
491553 private async getTypedefs ( pg_bsd_indent : vscode . Uri ) {
492554 try {
493- const typedefsFile = utils . joinPath ( pg_bsd_indent , 'typedefs.list' ) ;
555+ const typedefsFile = utils . joinPath ( pg_bsd_indent , '..' , ' typedefs.list') ;
494556 if ( await utils . fileExists ( typedefsFile ) ) {
495557 return typedefsFile ;
496558 }
0 commit comments