Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/terminal-suggest/src/fig/fig-autocomplete-shared/specMetadata.ts
3520 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Subcommand, convertSubcommand, Initializer } from './convert';
7
import { makeArray, SpecLocationSource } from './utils';
8
9
type FigLoadSpecFn = Fig.LoadSpec extends infer U ? (U extends Function ? U : never) : never;
10
export type LoadSpec<ArgT = ArgMeta, OptionT = OptionMeta, SubcommandT = SubcommandMeta> =
11
| Fig.SpecLocation[]
12
| Subcommand<ArgT, OptionT, SubcommandT>
13
| ((
14
...args: Parameters<FigLoadSpecFn>
15
) => Promise<Fig.SpecLocation[] | Subcommand<ArgT, OptionT, SubcommandT>>);
16
17
export type OptionMeta = Omit<Fig.Option, 'args' | 'name'>;
18
export type ArgMeta = Omit<Fig.Arg, 'template' | 'generators' | 'loadSpec'> & {
19
generators: Fig.Generator[];
20
loadSpec?: LoadSpec<ArgMeta, OptionMeta, SubcommandMeta>;
21
};
22
23
type SubcommandMetaExcludes =
24
| 'subcommands'
25
| 'options'
26
| 'loadSpec'
27
| 'persistentOptions'
28
| 'args'
29
| 'name';
30
export type SubcommandMeta = Omit<Fig.Subcommand, SubcommandMetaExcludes> & {
31
loadSpec?: LoadSpec<ArgMeta, OptionMeta, SubcommandMeta>;
32
};
33
34
export function convertLoadSpec<ArgT, OptionT, SubcommandT>(
35
loadSpec: Fig.LoadSpec,
36
initialize: Initializer<ArgT, OptionT, SubcommandT>
37
): LoadSpec<ArgT, OptionT, SubcommandT> {
38
if (typeof loadSpec === 'string') {
39
return [{ name: loadSpec, type: SpecLocationSource.GLOBAL }];
40
}
41
42
if (typeof loadSpec === 'function') {
43
return (...args) =>
44
loadSpec(...args).then((result) => {
45
if (Array.isArray(result)) {
46
return result;
47
}
48
if ('type' in result) {
49
return [result];
50
}
51
return convertSubcommand(result, initialize);
52
});
53
}
54
55
return convertSubcommand(loadSpec, initialize);
56
}
57
58
function initializeOptionMeta(option: Fig.Option): OptionMeta {
59
return option;
60
}
61
62
// Default initialization functions:
63
function initializeArgMeta(arg: Fig.Arg): ArgMeta {
64
const { template, ...rest } = arg;
65
const generators = template ? [{ template }] : makeArray(arg.generators ?? []);
66
return {
67
...rest,
68
loadSpec: arg.loadSpec
69
? convertLoadSpec(arg.loadSpec, {
70
option: initializeOptionMeta,
71
subcommand: initializeSubcommandMeta,
72
arg: initializeArgMeta,
73
})
74
: undefined,
75
generators: generators.map((generator) => {
76
let { trigger, getQueryTerm } = generator;
77
if (generator.template) {
78
const templates = makeArray(generator.template);
79
if (templates.includes('folders') || templates.includes('filepaths')) {
80
trigger = trigger ?? '/';
81
getQueryTerm = getQueryTerm ?? '/';
82
}
83
}
84
return { ...generator, trigger, getQueryTerm };
85
}),
86
};
87
}
88
89
function initializeSubcommandMeta(subcommand: Fig.Subcommand): SubcommandMeta {
90
return {
91
...subcommand,
92
loadSpec: subcommand.loadSpec
93
? convertLoadSpec(subcommand.loadSpec, {
94
subcommand: initializeSubcommandMeta,
95
option: initializeOptionMeta,
96
arg: initializeArgMeta,
97
})
98
: undefined,
99
};
100
}
101
102
export const initializeDefault: Initializer<ArgMeta, OptionMeta, SubcommandMeta> = {
103
subcommand: initializeSubcommandMeta,
104
option: initializeOptionMeta,
105
arg: initializeArgMeta,
106
};
107
108