@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22import { languages } from 'vscode' ;
33import * as utils from './utils' ;
44import { Log as logger } from './logger' ;
5+ import { getWellKnownBuiltinContribs } from './constants' ;
56import { Configuration , parseFormatterConfiguration , readConfigFile } from './extension' ;
67import { PghhError } from './error' ;
78import * as path from 'path' ;
@@ -24,6 +25,10 @@ function findSuitableWorkspace(document: vscode.TextDocument) {
2425 return vscode . workspace . workspaceFolders [ 0 ] ;
2526}
2627
28+ function isBuiltinContrib ( name : string ) {
29+ return getWellKnownBuiltinContribs ( ) . has ( name ) ;
30+ }
31+
2732export interface PgindentConfiguration {
2833 typedefs ?: string [ ] ;
2934}
@@ -230,8 +235,8 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
230235 { cwd : pgBsdIndentDir . fsPath } ) ;
231236 return pgBsdIndent ;
232237 }
233-
234- private async getCustomTypedefs ( workspace : vscode . WorkspaceFolder ) {
238+
239+ private async getTypedefsFromConfiguration ( workspace : vscode . WorkspaceFolder ) {
235240 const configObj = await readConfigFile ( workspace ) ;
236241 if ( ! configObj ) {
237242 return [ ] ;
@@ -261,12 +266,69 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
261266 continue ;
262267 }
263268
264- typedefs . push ( `--typedefs= ${ typedefFile . fsPath } ` ) ;
269+ typedefs . push ( typedefFile . fsPath ) ;
265270 }
266271
267272 return typedefs ;
268273 }
269274
275+ private async enrichTypedefsWithContrib ( document : vscode . Uri ,
276+ typedefs : string [ ] ) {
277+ /*
278+ * If we are running inside 'contrib', then it can
279+ * have it's own 'typedefs.list' file which is not
280+ * added to configuration file - add it.
281+ */
282+
283+ /* Fast check we inside contrib directory */
284+ const contribIndex = document . path . indexOf ( '/contrib/' ) ;
285+ if ( contribIndex === - 1 ) {
286+ return ;
287+ }
288+
289+ const r = / .* \/ c o n t r i b \/ ( [ A - Z a - z 0 - 9 _ ] + ) \/ / . exec ( document . path ) ;
290+ if ( ! r ) {
291+ return ;
292+ }
293+
294+ const contribName = r [ 1 ] ;
295+ if ( ! contribName ) {
296+ return ;
297+ }
298+
299+ if ( isBuiltinContrib ( contribName ) ) {
300+ /* Builtin contribs do not have typedefs.list files */
301+ return ;
302+ }
303+
304+ const contribDir = r [ 0 ] ;
305+ if ( ! contribDir ) {
306+ return ;
307+ }
308+
309+ /* If we have 'typedefs.list' in contrib, then it may already exist in typedefs */
310+ if ( typedefs . find ( t => t . startsWith ( contribDir ) ) ) {
311+ return ;
312+ }
313+
314+ /* Add typedef to list of used */
315+ const contribTypedef = vscode . Uri . file ( `${ contribDir } typedefs.list` ) ;
316+ if ( await utils . fileExists ( contribTypedef ) ) {
317+ typedefs . push ( contribTypedef . fsPath ) ;
318+ }
319+ }
320+
321+ private async getCustomTypedefs ( document : vscode . Uri ,
322+ workspace : vscode . WorkspaceFolder ) {
323+ /* Get user provided typedefs */
324+ const configTypedefs = await this . getTypedefsFromConfiguration ( workspace ) ;
325+
326+ /* Add potentially missing typedefs from current contrib directory */
327+ await this . enrichTypedefsWithContrib ( document , configTypedefs ) ;
328+
329+ return configTypedefs . map ( f => `--typedefs=${ f } ` ) ;
330+ }
331+
270332 private async getPgBsdIndent ( workspace : vscode . WorkspaceFolder , pgindent : vscode . Uri ) {
271333 if ( this . savedPgbsdPath ) {
272334 if ( await utils . fileExists ( this . savedPgbsdPath ) ) {
@@ -302,11 +364,12 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
302364 return pgindentPath ;
303365 }
304366
305- private async runPgindentInternal ( document : vscode . Uri ,
367+ private async runPgindentInternal ( originalDocument : vscode . Uri ,
368+ document : vscode . Uri ,
306369 pg_bsd_indent : vscode . Uri ,
307370 pgindent : vscode . Uri ,
308371 workspace : vscode . WorkspaceFolder ) {
309- const typedefs = await this . getCustomTypedefs ( workspace ) ;
372+ const typedefs = await this . getCustomTypedefs ( originalDocument , workspace ) ;
310373
311374 /* Work in pgindent dir, so it can find default typedefs.list */
312375 const cwd = path . resolve ( pgindent . fsPath , '..' ) ;
@@ -372,13 +435,14 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
372435 return content ;
373436 }
374437
375- private async runPgindentRebuildBsd ( document : vscode . Uri ,
438+ private async runPgindentRebuildBsd ( originalDocument : vscode . Uri ,
439+ document : vscode . Uri ,
376440 pgBsdIndent : vscode . Uri ,
377441 pgindent : vscode . Uri ,
378442 workspace : vscode . WorkspaceFolder ) {
379443 try {
380444 return await this . runPgindentInternal (
381- document , pgBsdIndent , pgindent , workspace ) ;
445+ originalDocument , document , pgBsdIndent , pgindent , workspace ) ;
382446 } catch ( err ) {
383447 if ( await utils . fileExists ( pgBsdIndent ) ) {
384448 throw err ;
@@ -389,7 +453,7 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
389453 this . savedPgbsdPath = undefined ;
390454 pgBsdIndent = await this . findPgBsdIndentOrBuild ( workspace , pgindent ) ;
391455 return await this . runPgindentInternal (
392- document , pgBsdIndent , pgindent , workspace ) ;
456+ originalDocument , document , pgBsdIndent , pgindent , workspace ) ;
393457 }
394458
395459 private async runPgindent ( document : vscode . TextDocument ,
@@ -400,7 +464,7 @@ class PgindentDocumentFormatterProvider implements vscode.DocumentFormattingEdit
400464 const tempDocument = await utils . createTempFile ( 'pghh-{}.c' , content ) ;
401465 try {
402466 return await this . runPgindentRebuildBsd (
403- tempDocument , pg_bsd_indent , pgindent , workspace ) ;
467+ document . uri , tempDocument , pg_bsd_indent , pgindent , workspace ) ;
404468 } finally {
405469 await utils . deleteFile ( tempDocument ) ;
406470 }
0 commit comments