Skip to content

Commit c6dad55

Browse files
committed
feat: autodetect typedefs.list when formatting file in 'contrib' subdir
Extension can have it's own typedefs.list file (i.e. pg_hint_plan, orafce, pg_tde, etc...), but it's more convenient not to do anything if such file stored in default location. So now when formatting files inside 'contrib' subdirectory extension will try to detect 'typedefs.list' file inside this contrib and pass it to pgindent.
1 parent 668af89 commit c6dad55

File tree

2 files changed

+143
-9
lines changed

2 files changed

+143
-9
lines changed

src/constants.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3918,4 +3918,74 @@ export function getWellKnownFlagsMembers(pgversion: number): BitmaskMemberInfo[]
39183918
arrs.find(([ver]) => ver.satisfies(pgversion))?.[1]).filter(x => x !== undefined);
39193919
prevVersionedFlagMembers = [members, pgversion];
39203920
return members;
3921+
}
3922+
3923+
const contribs = new Set<string>([
3924+
'adminpack',
3925+
'amcheck',
3926+
'auth_delay',
3927+
'auto_explain',
3928+
'basebackup_to_shell',
3929+
'basic_archive',
3930+
'bloom',
3931+
'bool_plperl',
3932+
'btree_gin',
3933+
'btree_gist',
3934+
'chkpass',
3935+
'citext',
3936+
'cube',
3937+
'dblink',
3938+
'dict_int',
3939+
'dict_xsyn',
3940+
'earthdistance',
3941+
'file_fdw',
3942+
'fuzzystrmatch',
3943+
'hstore',
3944+
'hstore_plperl',
3945+
'hstore_plpython',
3946+
'intagg',
3947+
'intarray',
3948+
'isn',
3949+
'jsonb_plperl',
3950+
'jsonb_plpython',
3951+
'lo',
3952+
'ltree',
3953+
'ltree_plpython',
3954+
'oid2name',
3955+
'old_snapshot',
3956+
'pageinspect',
3957+
'passwordcheck',
3958+
'pg_buffercache',
3959+
'pgcrypto',
3960+
'pg_freespacemap',
3961+
'pg_logicalinspect',
3962+
'pg_overexplain',
3963+
'pg_prewarm',
3964+
'pgrowlocks',
3965+
'pg_standby',
3966+
'pg_stat_statements',
3967+
'pgstattuple',
3968+
'pg_surgery',
3969+
'pg_trgm',
3970+
'pg_visibility',
3971+
'pg_walinspect',
3972+
'postgres_fdw',
3973+
'seg',
3974+
'sepgsql',
3975+
'spi',
3976+
'sslinfo',
3977+
'start-scripts',
3978+
'tablefunc',
3979+
'tcn',
3980+
'test_decoding',
3981+
'tsearch2',
3982+
'tsm_system_rows',
3983+
'tsm_system_time',
3984+
'unaccent',
3985+
'uuid-ossp',
3986+
'vacuumlo',
3987+
'xml2',
3988+
]);
3989+
export function getWellKnownBuiltinContribs() {
3990+
return contribs;
39213991
}

src/formatter.ts

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22
import {languages} from 'vscode';
33
import * as utils from './utils';
44
import { Log as logger } from './logger';
5+
import { getWellKnownBuiltinContribs } from './constants';
56
import { Configuration, parseFormatterConfiguration, readConfigFile } from './extension';
67
import { PghhError } from './error';
78
import * 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+
2732
export 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 = /.*\/contrib\/([A-Za-z0-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

Comments
 (0)