-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathindex.d.ts
1222 lines (1175 loc) · 54.1 KB
/
index.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* eslint-disable @typescript-eslint/ban-types */
declare namespace Fig {
/**
* Templates are generators prebuilt by Fig.
* @remarks
* Here are the three templates:
* - filepaths: show folders and filepaths. Allow autoexecute on filepaths
* - folders: show folders only. Allow autoexecute on folders
* - history: show suggestions for all items in history matching this pattern
* - help: show subcommands. Only includes the 'siblings' of the nearest 'parent' subcommand
*/
type TemplateStrings = "filepaths" | "folders" | "history" | "help";
/**
* A template which is a single TemplateString or an array of TemplateStrings
*
* @remarks
* Templates are generators prebuilt by Fig. Here are the three templates:
* - filepaths: show folders and filepaths. Allow autoexecute on filepaths
* - folders: show folders only. Allow autoexecute on folders
* - history: show suggestions for all items in history matching this pattern
* - help: show subcommands. Only includes the 'siblings' of the nearest 'parent' subcommand
*
* @example
* `cd` uses the "folders" template
* `ls` used ["filepaths", "folders"]. Why both? Because if I `ls` a directory, we want to enable a user to autoexecute on this directory. If we just did "filepaths" they couldn't autoexecute.
*
*/
type Template = TemplateStrings | TemplateStrings[];
type HistoryContext = {
currentWorkingDirectory: string;
time: number;
exitCode: number;
shell: string;
};
type TemplateSuggestionContext =
| { templateType: "filepaths" }
| { templateType: "folders" }
| { templateType: "help" }
| ({ templateType: "history" } & Partial<HistoryContext>);
type TemplateSuggestion = Modify<
Suggestion,
{ name?: string; context: TemplateSuggestionContext }
>;
/**
*
* The SpecLocation object defines well... the location of the completion spec we want to load.
* Specs can be "global" (ie hosted by Fig's cloud) or "local" (ie stored on your local machine)
*
* @remarks
* **The `SpecLocation` Object**
*
* The SpecLocation object defines well... the location of the completion spec we want to load.
* Specs can be "global" (ie hosted by Fig's cloud) or "local" (ie stored on your local machine).
*
* - Global `SpecLocation`:
* Load specs hosted in Fig's Cloud. Assume the current working directory is here: https://github.com/withfig/autocomplete/tree/master/src. Now set the value for the "name" prop to the relative location of your spec (without the .js file extension)
* ```js
* // e.g.
* { type: "global", name: "aws/s3" } // Loads up the aws s3 completion spec
* { type: "global", name: "python/http.server" } // Loads up the http.server completion spec
* ```
*
* - Local `SpecLocation`:
* Load specs saved on your local system / machine. Assume the current working directory is the user's current working directory.
* The `name` prop should take the name of the spec (without the .js file extension) e.g. my_cli_tool
* The `path` prop should take an absolute path OR a relative path (relative to the user's current working directory). The path should be to the directory that contains the `.fig` folder. Fig will then assume your spec is located in `.fig/autocomplete/build/`
* ```js
* // e.g.
* { type: "global", path: "node_modules/cowsay", name: "cowsay_cli" } // will look for `cwd/node_modules/cowsay/.fig/autocomplete/build/cowsay_cli.js`
* { type: "global", path: "~", name: "my_cli" } // will look for `~/.fig/autocomplete/build/my_cli.js`
* ```
* @irreplaceable
*/
type SpecLocation =
| { type: "local"; path?: string; name: string }
| { type: "global"; name: string };
/**
* Dynamically load up another completion spec at runtime.
*
* See [`loadSpec` property in Subcommand Object](https://fig.io/docs/reference/subcommand#loadspec).
*/
type LoadSpec =
| string
| Subcommand
| ((
token: string,
executeShellCommand: ExecuteShellCommandFunction
) => Promise<SpecLocation | SpecLocation[] | Subcommand>);
/**
* The type of a suggestion object.
* @remarks
* The type determines:
* - the default icon Fig uses (e.g. a file or folder searches for the system icon, a subcommand has a specific icon etc)
* - whether we allow users to auto-execute a command
*/
type SuggestionType =
| "folder"
| "file"
| "arg"
| "subcommand"
| "option"
| "special"
| "mixin"
| "shortcut";
/**
* A single object of type `T` or an array of objects of type `T`.
*/
type SingleOrArray<T> = T | T[];
/**
* An async function that returns the version of a given CLI tool.
* @remarks
* This is used in completion specs that want to version themselves the same way CLI tools are versioned. See fig.io/docs
*
* @param executeShellCommand -an async function that allows you to execute a shell command on the user's system and get the output as a string.
* @returns The version of a CLI tool
*
* @example
* `1.0.22`
*
* @example
* `v26`
*
*/
type GetVersionCommand = (executeShellCommand: ExecuteShellCommandFunction) => Promise<string>;
/**
* Context about a current shell session.
*/
type ShellContext = {
currentWorkingDirectory: string;
currentProcess: string;
sshPrefix: string;
};
type GeneratorContext = ShellContext & {
isDangerous?: boolean;
searchTerm: string;
};
/**
* A function which can have a `T` argument and a `R` result.
* @param param - A param of type `R`
* @returns Something of type `R`
*/
type Function<T = void, R = void> = (param: T) => R;
/**
* A utility type to modify a property type
* @irreplaceable
*/
type Modify<T, R> = Omit<T, keyof R> & R;
/**
* A `string` OR a `function` which can have a `T` argument and a `R` result.
* @param param - A param of type `R`
* @returns Something of type `R`
*/
type StringOrFunction<T = void, R = void> = string | Function<T, R>;
/**
* @excluded
* @irreplaceable
*/
type ArgDiff = Modify<Fig.Arg, { remove?: true }>;
/**
* @excluded
* @irreplaceable
*/
type OptionDiff = Modify<
Fig.Option,
{
args?: ArgDiff | ArgDiff[];
remove?: true;
}
>;
/**
* @excluded
* @irreplaceable
*/
type SubcommandDiff = Modify<
Fig.Subcommand,
{
subcommands?: SubcommandDiff[];
options?: OptionDiff[];
args?: ArgDiff | ArgDiff[];
remove?: true;
}
>;
/**
* @excluded
* @irreplaceable
*/
type SpecDiff = Omit<SubcommandDiff, "name" | "remove">;
/**
* @excluded
* @irreplaceable
*/
type VersionDiffMap = Record<string, SpecDiff>;
/**
* A spec object.
* Can be one of
* 1. A subcommand
* 2. A function that dynamically computes a subcommand
* 3. A function that returns the path to a versioned spec files (that exports a base subcommand and { versions: VersionDiffMap }
*/
type Spec =
| Subcommand
| ((version?: string) => Subcommand)
| ((
version?: string
) => {
versionedSpecPath: string;
version?: string;
});
/**
* An async function to execute a shell command
* @param commandToExecute - The shell command you want to execute
* @param cwd - The directory in which to execute the command
* @returns The output of the shell command as a string
*
* @remarks
* The `cwd` parameter will add a `cd [cwd] &&` before the command itself.
* @example
* `ExecuteShellCommandFunction("echo hello world")` will return `hello world`
*/
type ExecuteShellCommandFunction = (commandToExecute: string, cwd?: string) => Promise<string>;
type CacheMaxAge = {
strategy?: "max-age";
/**
* The time to live for the cache in milliseconds.
* @example
* 3600
*/
ttl: number;
};
type CacheStaleWhileRevalidate = {
strategy: "stale-while-revalidate";
/**
* The time to live for the cache in milliseconds.
* @example
* 3600
*/
ttl?: number;
};
type Cache = (CacheMaxAge | CacheStaleWhileRevalidate) & {
/**
* Whether the cache should be based on the directory the user was currently in or not.
* @defaultValue false
*/
cacheByDirectory?: boolean;
};
type TriggerOnChange = {
/** Trigger on any change to the token */
on: "change";
};
type TriggerOnThreshold = {
/** Trigger when the length of the token changes past a threshold */
on: "threshold";
length: number;
};
type TriggerOnMatch = {
/** Trigger when the index of a string changes */
on: "match";
string: string | string[];
};
type Trigger =
| string
| ((newToken: string, oldToken: string) => boolean)
| TriggerOnChange
| TriggerOnThreshold
| TriggerOnMatch;
/**
* The BaseSuggestion object is the root of the Suggestion, Subcommand, and Option objects.
* It is where key properties like description, icon, and displayName are found
* @excluded
*/
interface BaseSuggestion {
/**
* The string that is displayed in the UI for a given suggestion.
* @defaultValue the name prop
*
* @example
* The npm CLI has a subcommand called `install`. If we wanted
* to display some custom text like `Install an NPM package 📦` we would set
* `name: "install"` and `displayName: "Install an NPM package 📦"`
*/
displayName?: string;
/**
* The value that's inserted into the terminal when a user presses enter/tab or clicks on a menu item.
*
* @remarks
* You can use `\n` to insert a newline or `\b` to insert a backspace.
* You can also optionally specify {cursor} in the string and Fig will automatically place the cursor there after insert.
*
* @defaultValue The value of the name prop.
*
* @example
* For the `git commit` subcommand, the `-m` option has an insert value of `-m '{cursor}'`
*/
insertValue?: string;
/**
* When the suggestion is inserted, replace the command with this string
*
* @remarks
* You can use `\n` to insert a newline or `\b` to insert a backspace.
* You can also optionally specify {cursor} in the string and Fig will automatically place the cursor there after insert.
* Note that currently the entire edit buffer will be replaced. Eventually, only the root command will be replaced, preserving pipes and continuations.
*/
replaceValue?: string;
/**
* The text that gets rendered at the bottom of the autocomplete box (or the side if you hit ⌘i)
*
* @example
* "Your commit message"
*/
description?: string;
/**
* The icon that is rendered is based on the type.
*
* @remarks
* Icons can be a 1 character string, a URL, or Fig's [icon protocol](https://fig.io/docs/reference/suggestion/icon-api) (fig://) which lets you generate
* colorful and fun systems icons.
*
* @defaultValue related to the type of the object (e.g. `Suggestion`, `Subcommand`, `Option`, `Arg`)
*
* @example
* `A`
* @example
* `😊`
* @example
* `https://www.herokucdn.com/favicon.ico`
* @example
* `fig://icon?type=file`
*
*/
icon?: string;
/**
* Specifies whether the suggestion is "dangerous".
*
* @remarks
* If true, Fig will not enable its autoexecute functionality. Autoexecute means if a user selects a suggestion it will insert the text and run the command. We signal this by changing the icon to red.
* Setting `isDangerous` to `true` will make it harder for a user to accidentally run a dangerous command.
*
* @defaultValue false
*
* @example
* This is used in the `rm` spec. Why? Because we don't want users to accidentally delete their files so we make it just a little bit harder...
*/
isDangerous?: boolean;
/**
* The number used to rank suggestions in autocomplete. Number must be from 0-100. Higher priorities rank higher.
*
* @defaultValue 50
* @remarks
* Fig ranks suggestions by recency. To do this, we check if a suggestion has been selected before. If yes and the suggestions has:
* - a priority between 50-75, the priority will be replaced with 75, then we will add the timestamp of when that suggestion was selected as a decimal.
* - a priority outside of 50-75, the priority will be increased by the timestamp of when that suggestion was selected as a decimal.
* If it has not been selected before, Fig will keep the same priority as was set in the completion spec
* If it was not set in the spec, it will default to 50.
*
* @example
* Let's say a user has previously selected a suggestion at unix timestamp 1634087677:
* - If completion spec did not set a priority (Fig treats this as priority 50), its priority would change to 75 + 0.1634087677 = 75.1634087677;
* - If completion spec set a priority of 49 or less, its priority would change to 49 + 0.1634087677 = 49.1634087677;
* - If completion spec set a priority of 76 or more, its priority would change to 76 + 0.1634087677 = 76.1634087677;
* - If a user had never selected a suggestion, then its priority would just stay as is (or if not set, default to 50).
*
* @example
* If you want your suggestions to always be:
* - at the top order, rank them 76 or above.
* - at the bottom, rank them 49 or below
*/
priority?: number;
/**
* Specifies whether a suggestion should be hidden from results.
* @remarks
* Fig will only show it if the user exactly types the name.
* @defaultValue false
* @example
* The "-" suggestion is hidden in the `cd` spec. You will only see it if you type exactly `cd -`
*/
hidden?: boolean;
/**
*
* Specifies whether a suggestion is deprecated.
* @remarks
* It is possible to specify a suggestion to replace the deprecated one.
* - The `description` of the deprecated object (e.g `deprecated: { description: 'The --no-ansi option has been deprecated in v2' }`) is used to provide infos about the deprecation.
* - `deprecated: true` and `deprecated: { }` behave the same and will just display the suggestion as deprecated.
* @example
* ```js
* deprecated: { insertValue: '--ansi never', description: 'The --no-ansi option has been deprecated in v2' }
* ```
*/
deprecated?: boolean | Omit<BaseSuggestion, "deprecated">;
}
/**
* Each item in Fig's autocomplete popup window is a Suggestion object. It is probably the most important object in Fig.
* Subcommand and Option objects compile down to Suggestion objects. Generators return Suggestion objects.
* The main things you can customize in your suggestion object is the text that's displayed, the icon, and what's inserted after being selected. In saying that, most of these have very sane defaults.
*/
interface Suggestion extends BaseSuggestion {
/**
* The string Fig uses when filtering over a list of suggestions to check for a match.
* @remarks
* When a a user is typing in the terminal, the query term (the token they are currently typing) filters over all suggestions in a list by checking if the queryTerm matches the prefix of the name.
* The `displayName` prop also defaults to the value of name.
*
* The `name` props of suggestion, subcommand, option, and arg objects are all different. It's important to read them all carefully.
*
* @example
* If a user types git `c`, any Suggestion objects with a name prop that has a value starting with "c" will match.
*
*/
name?: SingleOrArray<string>;
/**
* The type of a suggestion object.
* @remarks
* The type determines
* - the default icon Fig uses (e.g. a file or folder searches for the system icon, a subcommand has a specific icon etc)
* - whether we allow users to auto-execute a command
*/
type?: SuggestionType;
}
/**
* The subcommand object represent the tree structure of a completion spec. We sometimes also call it the skeleton.
*
* A subcommand can nest options, arguments, and more subcommands (it's recursive)
*/
interface Subcommand extends BaseSuggestion {
/**
* The name of the subcommand. Should exactly match the name defined by the CLI tool.
*
* @remarks
* If a subcommand has multiple aliases, they should be included as an array.
*
* Note that Fig's autocomplete engine requires this `name` to match the text typed by the user in the shell.
*
* To customize the title that is displayed to the user, use `displayName`.
*
*
* @example
* For `git checkout`, the subcommand `checkout` would have `name: "checkout"`
* @example
* For `npm install`, the subcommand `install` would have `name: ["install", "i"]` as these two values both represent the same subcommand.
*/
name: SingleOrArray<string>;
/**
* An array of `Subcommand` objects representing all the subcommands that exist beneath the current command.
* *
* To support large CLI tools, `Subcommands` can be nested recursively.
*
* @example
* A CLI tool like `aws` is composed of many top-level subcommands (`s3`, `ec2`, `eks`...), each of which include child subcommands of their own.
*/
subcommands?: Subcommand[];
/**
* Specifies whether the command requires a subcommand. This is false by default.
*
* A space will always be inserted after this command if `requiresSubcommand` is true.
* If the property is omitted, a space will be inserted if there is at least one required argument.
*/
requiresSubcommand?: boolean;
/**
* An array of `Option` objects representing the options that are available on this subcommand.
*
* @example
* A command like `git commit` accepts various flags and options, such as `--message` and `--all`. These `Option` objects would be included in the `options` field.
*/
options?: Option[];
/**
* An array of `Arg` objects representing the various parameters or "arguments" that can be passed to this subcommand.
*
*/
args?: SingleOrArray<Arg>;
/**
* This option allows to enforce the suggestion filtering strategy for a specific subcommand.
* @remarks
* Users always want to have the most accurate results at the top of the suggestions list.
* For example we can enable fuzzy search on a subcommand that always requires fuzzy search to show the best suggestions.
* This property is also useful when subcommands or options have a prefix (e.g. the npm package scope) because enabling fuzzy search users can omit that part (see the second example below)
* @example
* yarn workspace [name] with fuzzy search is way more useful since we can omit the npm package scope
* @example
* fig settings <setting name> uses fuzzy search to prevent having to add the `autocomplete.` prefix to each searched setting
* ```typescript
* const figSpec: Fig.Spec {
* name: "fig",
* subcommands: [
* {
* name: "settings",
* filterStrategy: "fuzzy",
* subcommands: [
* {
* name: "autocomplete.theme", // if a user writes `fig settings theme` it gets the correct suggestions
* },
* // ... other settings
* ]
* },
* // ... other fig subcommands
* ]
* }
* ```
*/
filterStrategy?: "fuzzy" | "prefix" | "default";
/**
* A list of Suggestion objects that are appended to the suggestions shown beneath a subcommand.
*
* @remarks
* You can use this field to suggest common workflows.
*
*/
additionalSuggestions?: (string | Suggestion)[];
/**
* Dynamically load another completion spec at runtime.
*
* @param tokens - a tokenized array of the text the user has typed in the shell.
* @param executeShellCommand - an async function that can execute a shell command on behalf of the user. The output is a string.
* @returns A `SpecLocation` object or an array of `SpecLocation` objects.
*
* @remarks
* `loadSpec` can be invoked as string (recommended) or a function (advanced).
*
* The API tells the autocomplete engine where to look for a completion spec. If you pass a string, the engine will attempt to locate a matching spec that is hosted by Fig.
*
* @example
* Suppose you have an internal CLI tool that wraps `kubectl`. Instead of copying the `kubectl` completion spec, you can include the spec at runtime.
* ```typescript
* {
* name: "kube",
* description: "a wrapper around kubectl"
* loadSpec: "kubectl"
* }
* ```
* @example
* In the `aws` completion spec, `loadSpec` is used to optimize performance. The completion spec is split into multiple files, each of which can be loaded separately.
* ```typescript
* {
* name: "s3",
* loadSpec: "aws/s3"
* }
* ```
*/
loadSpec?: LoadSpec;
/**
* Dynamically *generate* a `Subcommand` object a runtime. The generated `Subcommand` is merged with the current subcommand.
*
* @remarks
* This API is often used by CLI tools where the structure of the CLI tool is not *static*. For instance, if the tool can be extended by plugins or otherwise shows different subcommands or options depending on the environment.
*
* @param tokens - a tokenized array of the text the user has typed in the shell.
* @param executeShellCommand - an async function that can execute a shell command on behalf of the user. The output is a string.
* @returns a `Fig.Spec` object
*
* @example
* The `python` spec uses `generateSpec` to include the`django-admin` spec if `django manage.py` exists.
* ```typescript
* generateSpec: async (tokens, executeShellCommand) => {
* // Load the contents of manage.py
* const managePyContents = await executeShellCommand("cat manage.py");
* // Heuristic to determine if project uses django
* if (managePyContents.contains("django")) {
* return {
* name: "python",
* subcommands: [{ name: "manage.py", loadSpec: "django-admin" }],
* };
* }
* },
* ```
*/
generateSpec?: (
tokens: string[],
executeShellCommand: ExecuteShellCommandFunction
) => Promise<Spec>;
/**
* Configure how the autocomplete engine will map the raw tokens to a given completion spec.
*
* @param flagsArePosixNoncompliant - Indicates that flags with one hyphen may have *more* than one character. Enabling this directive, turns off support for option chaining.
* @param optionsMustPrecedeArguments - Options will not be suggested after any argument of the Subcommand has been typed.
* @param optionArgSeparators - Indicate that options which take arguments will require one of the specified separators between the 'verbose' option name and the argument.
*
* @example
* The `-work` option from the `go` spec is parsed as a single flag when `parserDirectives.flagsArePosixNoncompliant` is set to true. Normally, this would be chained and parsed as `-w -o -r -k` if `flagsArePosixNoncompliant` is not set to true.
*/
parserDirectives?: {
flagsArePosixNoncompliant?: boolean;
optionsMustPrecedeArguments?: boolean;
optionArgSeparators?: SingleOrArray<string>;
};
}
/**
* The option object represent CLI options (sometimes called flags).
*
* A option can have an argument. An option can NOT have subcommands or other option
*/
interface Option extends BaseSuggestion {
/**
* The exact name of the subcommand as defined in the CLI tool.
*
* @remarks
* Fig's parser relies on your option name being exactly what the user would type. (e.g. if the user types `git "-m"`, you must have `name: "-m"` and not something like `name: "your message"` or even with an `=` sign like`name: "-m="`)
*
* If you want to customize what the text the popup says, use `displayName`.
*
* The name prop in an Option object compiles down to the name prop in a Suggestion object
*
* Final note: the name prop can be a string (most common) or an array of strings
*
*
* @example
* For `git commit -m` in the, message option nested beneath `commit` would have `name: ["-m", "--message"]`
* @example
* For `ls -l` the `-l` option would have `name: "-l"`
*/
name: SingleOrArray<string>;
/**
* An array of arg objects or a single arg object
*
* @remarks
* If a subcommand takes an argument, please at least include an empty Arg Object. (e.g. `{ }`). Why? If you don't, Fig will assume the subcommand does not take an argument. When the user types their argument
* If the argument is optional, signal this by saying `isOptional: true`.
*
* @example
* `npm run` takes one mandatory argument. This can be represented by `args: { }`
* @example
* `git push` takes two optional arguments. This can be represented by: `args: [{ isOptional: true }, { isOptional: true }]`
* @example
* `git clone` takes one mandatory argument and one optional argument. This can be represented by: `args: [{ }, { isOptional: true }]`
*/
args?: SingleOrArray<Arg>;
/**
*
* Signals whether an option is persistent, meaning that it will still be available
* as an option for all child subcommands.
*
* @remarks
* As of now there is no way to disable this
* persistence for certain children. Also see
* https://github.com/spf13/cobra/blob/master/user_guide.md#persistent-flags.
*
* @defaultValue false
*
* @example
* Say the `git` spec had an option at the top level with `{ name: "--help", isPersistent: true }`.
* Then the spec would recognize both `git --help` and `git commit --help`
* as a valid as we are passing the `--help` option to all `git` subcommands.
*
*/
isPersistent?: boolean;
/**
* Signals whether an option is required.
*
* @defaultValue false (option is NOT required)
* @example
* The `-m` option of `git commit` is required
*
*/
isRequired?: boolean;
/**
*
* Signals whether an equals sign is required to pass an argument to an option (e.g. `git commit --message="msg"`)
* @defaultValue false (does NOT require an equal)
*
* @example
* When `requiresEqual: true` the user MUST do `--opt=value` and cannot do `--opt value`
*
* @deprecated use `requiresSeparator` instead
*
*/
requiresEquals?: boolean;
/**
*
* Signals whether one of the separators specified in parserDirectives is required to pass an argument to an option (e.g. `git commit --message[separator]"msg"`)
* If set to true this will automatically insert an equal after the option name.
* If set to a separator (string) this will automatically insert the separator specified after the option name.
* @defaultValue false (does NOT require a separator)
*
* @example
* When `requiresSeparator: true` the user MUST do `--opt=value` and cannot do `--opt value`
* @example
* When `requiresSeparator: ':'` the user MUST do `--opt:value` and cannot do `--opt value`
*/
requiresSeparator?: boolean | string;
/**
*
* Signals whether an option can be passed multiple times.
*
* @defaultValue false (option is NOT repeatable)
*
* @remarks
* Passing `isRepeatable: true` will allow an option to be passed any number
* of times, while passing `isRepeatable: 2` will allow it to be passed
* twice, etc. Passing `isRepeatable: false` is the same as passing
* `isRepeatable: 1`.
*
* If you explicitly specify the isRepeatable option in a spec, this
* constraint will be enforced at the parser level, meaning after the option
* (say `-o`) has been passed the maximum number of times, Fig's parser will
* not recognize `-o` as an option if the user types it again.
*
* @example
* In `npm install` doesn't specify `isRepeatable` for `{ name: ["-D", "--save-dev"] }`.
* When the user types `npm install -D`, Fig will no longer suggest `-D`.
* If the user types `npm install -D -D`. Fig will still parse the second
* `-D` as an option.
*
* Suppose `npm install` explicitly specified `{ name: ["-D", "--save-dev"], isRepeatable: false }`.
* Now if the user types `npm install -D -D`, Fig will instead parse the second
* `-D` as the argument to the `install` subcommand instead of as an option.
*
* @example
* SSH has `{ name: "-v", isRepeatable: 3 }`. When the user types `ssh -vv`, Fig
* will still suggest `-v`, when the user types `ssh -vvv` Fig will stop
* suggesting `-v` as an option. Finally if the user types `ssh -vvvv` Fig's
* parser will recognize that this is not a valid string of chained options
* and will treat this as an argument to `ssh`.
*
*/
isRepeatable?: boolean | number;
/**
*
* Signals whether an option is mutually exclusive with other options (ie if the user has this option, Fig should not show the options specified).
* @defaultValue false
*
* @remarks
* Options that are mutually exclusive with flags the user has already passed will not be shown in the suggestions list.
*
* @example
* You might see `[-a | --interactive | --patch]` in a man page. This means each of these options are mutually exclusive on each other.
* If we were defining the exclusive prop of the "-a" option, then we would have `exclusive: ["--interactive", "--patch"]`
*
*/
exclusiveOn?: string[];
/**
*
*
* Signals whether an option depends on other options (ie if the user has this option, Fig should only show these options until they are all inserted).
*
* @defaultValue false
*
* @remarks
* If the user has an unmet dependency for a flag they've already typed, this dependency will have boosted priority in the suggestion list.
*
* @example
* In a tool like firebase, we may want to delete a specific extension. The command might be `firebase delete --project ABC --extension 123` This would mean we delete the 123 extension from the ABC project.
* In this case, `--extension` dependsOn `--project`
*
*/
dependsOn?: string[];
}
/**
* The arg object represent CLI arguments (sometimes called positional arguments).
*
* An argument is different to a subcommand object and option object. It does not compile down to a suggestion object. Rather, it represents custom user input. If you want to generate suggestions for this custom user input, you should use the generator prop nested beneath an Arg object
*/
interface Arg {
/**
* The name of an argument. This is different to the `name` prop for subcommands, options, and suggestion objects so please read carefully.
* This `name` prop signals a normal, human readable string. It usually signals to the user the type of argument they are inserting if there are no available suggestions.
* Unlike subcommands and options, Fig does NOT use this value for parsing. Therefore, it can be whatever you want.
*
* @example
* The name prop for the `git commit -m <msg>` arg object is "msg". But you could also make it "message" or "your message". It is only used for description purposes (you see it when you type the message), not for parsing!
*/
name?: string;
/**
* The text that gets rendered at the bottom of the autocomplete box a) when the user is inputting an argument and there are no suggestions and b) for all generated suggestions for an argument
* Keep it short and direct!
*
* @example
* "Your commit message"
*/
description?: string;
/**
* Specifies whether the suggestions generated for this argument are "dangerous".
*
* @remarks
* If true, Fig will not enable its autoexecute functionality. Autoexecute means if a user selects a suggestion it will insert the text and run the command. We signal this by changing the icon to red.
* Turning on isDangerous will make it harder for a user to accidentally run a dangerous command.
*
* @defaultValue false
*
* @example
* This is used for all arguments in the `rm` spec.
*/
isDangerous?: boolean;
/**
* A list of Suggestion objects that are shown when a user is typing an argument.
*
* @remarks
* These suggestions are static meaning you know them beforehand and they are not generated at runtime. If you want to generate suggestions at runtime, use a generator
*
* @example
* For `git reset <branch or commit>`, a two common arguments to pass are "head" and "head^". Therefore, the spec suggests both of these by using the suggestion prop
*/
suggestions?: (string | Suggestion)[];
/**
* A template which is a single TemplateString or an array of TemplateStrings
*
* @remarks
* Templates are generators prebuilt by Fig. Here are the three templates:
* - filepaths: show folders and filepaths. Allow autoexecute on filepaths
* - folders: show folders only. Allow autoexecute on folders
* - history: show suggestions for all items in history matching this pattern
* - help: show subcommands. Only includes the 'siblings' of the nearest 'parent' subcommand
*
* @example
* `cd` uses the "folders" template
* @example
* `ls` used ["filepaths", "folders"]. Why both? Because if I `ls` a directory, we want to enable a user to autoexecute on this directory. If we just did "filepaths" they couldn't autoexecute.
*
*/
template?: Template;
/**
*
* Generators let you dynamically generate suggestions for arguments by running shell commands on a user's device.
*
* This takes a single generator or an array of generators
*/
generators?: SingleOrArray<Generator>;
/**
* This option allows to enforce the suggestion filtering strategy for a specific argument suggestions.
* @remarks
* Users always want to have the most accurate results at the top of the suggestions list.
* For example we can enable fuzzy search on an argument that always requires fuzzy search to show the best suggestions.
* This property is also useful when argument suggestions have a prefix (e.g. the npm package scope) because enabling fuzzy search users can omit that part (see the second example below)
* @example
* npm uninstall [packages...] uses fuzzy search to allow searching for installed packages ignoring the package scope
* ```typescript
* const figSpec: Fig.Spec {
* name: "npm",
* subcommands: [
* {
* args: {
* name: "packages",
* filterStrategy: "fuzzy", // search in suggestions provided by the generator (in this case) using fuzzy search
* generators: generateNpmDeps,
* isVariadic: true,
* },
* },
* // ... other npm commands
* ],
* }
* ```
*/
filterStrategy?: "fuzzy" | "prefix" | "default";
/**
* Provide a suggestion at the top of the list with the current token that is being typed by the user.
*/
suggestCurrentToken?: boolean;
/**
* Specifies that the argument is variadic and therefore repeats infinitely.
*
* @remarks
* Man pages represent variadic arguments with an ellipsis e.g. `git add <pathspec...>`
*
* @example
* `echo` takes a variadic argument (`echo hello world ...`)
* @example
* `git add` also takes a variadic argument
*/
isVariadic?: boolean;
/**
* Specifies whether options can interrupt variadic arguments. There is
* slightly different behavior when this is used on an option argument and
* on a subcommand argument:
*
* - When an option breaks a *variadic subcommand argument*, after the option
* and any arguments are parsed, the parser will continue parsing variadic
* arguments to the subcommand
* - When an option breaks a *variadic option argument*, after the breaking
* option and any arguments are parsed, the original variadic options
* arguments will be terminated. See the second examples below for details.
*
*
* @defaultValue true
*
* @example
* When true for git add's argument:
* `git add file1 -v file2` will interpret `-v` as an option NOT an
* argument, and will continue interpreting file2 as a variadic argument to
* add after
*
* @example
* When true for -T's argument, where -T is a variadic list of tags:
* `cmd -T tag1 tag2 -p project tag3` will interpret `-p` as an option, but
* will then terminate the list of tags. So tag3 is not parsed as an
* argument to `-T`, but rather as a subcommand argument to `cmd` if `cmd`
* takes any arguments.
*
* @example
* When false:
* `echo hello -n world` will treat -n as an argument NOT an option.
* However, in `echo -n hello world` it will treat -n as an option as
* variadic arguments haven't started yet
*
*/
optionsCanBreakVariadicArg?: boolean;
/**
* `true` if an argument is optional (ie the CLI spec says it is not mandatory to include an argument, but you can if you want to).
*
* @remarks
* NOTE: It is important you include this for our parsing. If you don't, Fig will assume the argument is mandatory. When we assume an argument is mandatory, we force the user to input the argument and hide all other suggestions.
*
* @example
* `git push [remote] [branch]` takes two optional args.
*/
isOptional?: boolean;
/**
* Syntactic sugar over the `loadSpec` prop.
*
* @remarks
* Specifies that the argument is an entirely new command which Fig should start completing on from scratch.
*
* @example
* `time` and `builtin` have only one argument and this argument has the `isCommand` property. If I type `time git`, Fig will load up the git completion spec because the isCommand property is set.
*/
isCommand?: boolean;
/**
* The same as the `isCommand` prop, except Fig will look for a completion spec in the `.fig/autocomplete/build` folder in the user's current working directory.
*
* @remarks
* See our docs for more on building completion specs for local scripts [Fig for Teams](https://fig.io/docs/)
* @example
* `python` take one argument which is a `.py` file. If I have a `main.py` file on my desktop and my current working directory is my desktop, if I type `python main.py[space]` Fig will look for a completion spec in `~/Desktop/.fig/autocomplete/build/main.py.js`
*/
isScript?: boolean;
/**
* The same as the `isCommand` prop, except you specify a string to prepend to what the user inputs and fig will load the completion spec accordingly.
* @remarks
* If isModule: "python/", Fig would load up the `python/USER_INPUT.js` completion spec from the `~/.fig/autocomplete` folder.
* @example
* For `python -m`, the user can input a specific module such as http.server. Each module is effectively a mini CLI tool that should have its own completions. Therefore the argument object for -m has `isModule: "python/"`. Whatever the modules user inputs, Fig will look under the `~/.fig/autocomplete/python/` directory for completion spec.
*
* @deprecated use `loadSpec` instead
*/
isModule?: string;
/**
* This will debounce every keystroke event for this particular arg.
* @remarks
* If there are no keystroke events after 100ms, Fig will execute all the generators in this arg and return the suggestions.
*
* @example
* `npm install` and `pip install` send debounced network requests after inactive typing from users.
*/
debounce?: boolean;
/**
* The default value for an optional argument.
*
* @remarks
* Note: This is currently not used anywhere in Fig's autocomplete popup, but will be soon.
*
*/
default?: string;
/**
* See [`loadSpec` in Subcommand Object](https://fig.io/docs/reference/subcommand#loadspec).
*
* @remarks
* There is a very high chance you want to use one of the following:
* 1. `isCommand` (See [Arg Object](https://fig.io/docs/reference/arg#iscommand))
* 2. `isScript` (See [Arg Object](https://fig.io/docs/reference/arg#isscript))
*