politty 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/completion/index.cjs +4 -3
- package/dist/completion/index.cjs.map +1 -1
- package/dist/completion/index.d.cts +2 -2
- package/dist/completion/index.d.cts.map +1 -1
- package/dist/completion/index.d.ts +2 -2
- package/dist/completion/index.d.ts.map +1 -1
- package/dist/completion/index.js +3 -3
- package/dist/completion/index.js.map +1 -1
- package/dist/docs/index.cjs +203 -199
- package/dist/docs/index.cjs.map +1 -1
- package/dist/docs/index.d.cts +17 -9
- package/dist/docs/index.d.cts.map +1 -1
- package/dist/docs/index.d.ts +17 -9
- package/dist/docs/index.d.ts.map +1 -1
- package/dist/docs/index.js +200 -197
- package/dist/docs/index.js.map +1 -1
- package/dist/{extractor-JfoYSoMk.js → extractor-DO-FDKkW.js} +397 -295
- package/dist/extractor-DO-FDKkW.js.map +1 -0
- package/dist/{extractor-CqfDnGKd.cjs → extractor-cjruDqQ2.cjs} +404 -296
- package/dist/extractor-cjruDqQ2.cjs.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/{runner-9dLE13Dv.cjs → runner-0yr2HFay.cjs} +2 -2
- package/dist/{runner-9dLE13Dv.cjs.map → runner-0yr2HFay.cjs.map} +1 -1
- package/dist/{runner-LJRI4haB.js → runner-BoZpJtIR.js} +2 -2
- package/dist/{runner-LJRI4haB.js.map → runner-BoZpJtIR.js.map} +1 -1
- package/dist/schema-extractor-CHiBRT39.d.ts.map +1 -1
- package/dist/{schema-extractor-CP3ar0Wi.js → schema-extractor-DAkmmrOy.js} +5 -1
- package/dist/schema-extractor-DAkmmrOy.js.map +1 -0
- package/dist/schema-extractor-DyfK21m_.d.cts.map +1 -1
- package/dist/{schema-extractor-Cv7ipqLS.cjs → schema-extractor-Mk1MHBkQ.cjs} +5 -1
- package/dist/schema-extractor-Mk1MHBkQ.cjs.map +1 -0
- package/dist/{extractor-DsJ6hYqQ.d.cts → value-completion-resolver-0xf8_07p.d.cts} +56 -11
- package/dist/value-completion-resolver-0xf8_07p.d.cts.map +1 -0
- package/dist/{extractor-CCi4rjSI.d.ts → value-completion-resolver-CUKbibx-.d.ts} +56 -11
- package/dist/value-completion-resolver-CUKbibx-.d.ts.map +1 -0
- package/package.json +7 -6
- package/dist/extractor-CCi4rjSI.d.ts.map +0 -1
- package/dist/extractor-CqfDnGKd.cjs.map +0 -1
- package/dist/extractor-DsJ6hYqQ.d.cts.map +0 -1
- package/dist/extractor-JfoYSoMk.js.map +0 -1
- package/dist/schema-extractor-CP3ar0Wi.js.map +0 -1
- package/dist/schema-extractor-Cv7ipqLS.cjs.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const require_subcommand_router = require('./subcommand-router-4d1Xbp8B.cjs');
|
|
2
|
-
const require_schema_extractor = require('./schema-extractor-
|
|
2
|
+
const require_schema_extractor = require('./schema-extractor-Mk1MHBkQ.cjs');
|
|
3
3
|
let zod = require("zod");
|
|
4
|
+
let node_child_process = require("node:child_process");
|
|
4
5
|
|
|
5
6
|
//#region src/core/command.ts
|
|
6
7
|
function defineCommand(config) {
|
|
@@ -22,7 +23,12 @@ function defineCommand(config) {
|
|
|
22
23
|
/**
|
|
23
24
|
* Generate bash completion script for a command
|
|
24
25
|
*
|
|
25
|
-
* Generates a
|
|
26
|
+
* Generates a minimal script that delegates all logic to the CLI's __complete command.
|
|
27
|
+
* The shell script only handles:
|
|
28
|
+
* - Getting current command line tokens
|
|
29
|
+
* - Calling __complete with --shell bash
|
|
30
|
+
* - Setting COMPREPLY from the output
|
|
31
|
+
* - Falling back to native file/directory completion when directed
|
|
26
32
|
*/
|
|
27
33
|
function generateBashCompletion(_command, options) {
|
|
28
34
|
const programName = options.programName;
|
|
@@ -31,99 +37,126 @@ function generateBashCompletion(_command, options) {
|
|
|
31
37
|
# Generated by politty
|
|
32
38
|
|
|
33
39
|
_${programName}_completions() {
|
|
34
|
-
|
|
35
|
-
local
|
|
36
|
-
local completion_prefix=""
|
|
37
|
-
local completion_cur="$cur"
|
|
40
|
+
COMPREPLY=()
|
|
41
|
+
local IFS=$'\\n'
|
|
38
42
|
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
# Rejoin words split by '=' in COMP_WORDBREAKS (e.g. --opt=value)
|
|
44
|
+
local -a _words=()
|
|
45
|
+
local _i=1
|
|
46
|
+
while (( _i <= COMP_CWORD )); do
|
|
47
|
+
if [[ "\${COMP_WORDS[_i]}" == "=" && \${#_words[@]} -gt 0 ]]; then
|
|
48
|
+
_words[\${#_words[@]}-1]+="=\${COMP_WORDS[_i+1]:-}"
|
|
49
|
+
(( _i += 2 ))
|
|
50
|
+
else
|
|
51
|
+
_words+=("\${COMP_WORDS[_i]}")
|
|
52
|
+
(( _i++ ))
|
|
53
|
+
fi
|
|
54
|
+
done
|
|
55
|
+
|
|
56
|
+
local lines prev_opts="$-"
|
|
57
|
+
set -f
|
|
58
|
+
lines=($(${programName} __complete --shell bash -- "\${_words[@]}" 2>/dev/null))
|
|
59
|
+
[[ "$prev_opts" != *f* ]] && set +f
|
|
44
60
|
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# Backward compatibility for CLIs exposing only completion
|
|
49
|
-
output=$(${programName} completion __complete -- "\${args[@]}" 2>/dev/null)
|
|
61
|
+
local count=\${#lines[@]}
|
|
62
|
+
if (( count == 0 )); then
|
|
63
|
+
return 0
|
|
50
64
|
fi
|
|
51
65
|
|
|
52
|
-
local
|
|
66
|
+
local last="\${lines[count-1]}"
|
|
53
67
|
local directive=0
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
while IFS=$'\\t' read -r name desc; do
|
|
59
|
-
if [[ "$name" == :* ]]; then
|
|
60
|
-
directive="\${name:1}"
|
|
61
|
-
elif [[ "$name" == __command:* ]]; then
|
|
62
|
-
command_completion="\${name#__command:}"
|
|
63
|
-
elif [[ "$name" == __extensions:* ]]; then
|
|
64
|
-
file_extensions="\${name#__extensions:}"
|
|
65
|
-
elif [[ -n "$name" ]]; then
|
|
66
|
-
candidates+=("$name")
|
|
67
|
-
fi
|
|
68
|
-
done <<< "$output"
|
|
69
|
-
|
|
70
|
-
# Execute shellCommand completion if requested by __complete
|
|
71
|
-
if [[ -n "$command_completion" ]]; then
|
|
72
|
-
while IFS= read -r command_candidate; do
|
|
73
|
-
if [[ -n "$command_candidate" ]]; then
|
|
74
|
-
candidates+=("$command_candidate")
|
|
75
|
-
fi
|
|
76
|
-
done < <(eval "$command_completion" 2>/dev/null)
|
|
68
|
+
if [[ "$last" == :* ]]; then
|
|
69
|
+
directive="\${last:1}"
|
|
70
|
+
unset 'lines[count-1]'
|
|
71
|
+
(( count-- ))
|
|
77
72
|
fi
|
|
78
73
|
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
if ((
|
|
82
|
-
|
|
74
|
+
# Parse @ext: metadata (extension filter for native file completion)
|
|
75
|
+
local extensions=""
|
|
76
|
+
if (( count > 0 )); then
|
|
77
|
+
local maybe_ext="\${lines[count-1]}"
|
|
78
|
+
if [[ "$maybe_ext" == @ext:* ]]; then
|
|
79
|
+
extensions="\${maybe_ext:5}"
|
|
80
|
+
unset 'lines[count-1]'
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
local -a extension_list=()
|
|
87
|
-
local file_candidate ext
|
|
84
|
+
local cur=""
|
|
85
|
+
(( \${#_words[@]} > 0 )) && cur="\${_words[\${#_words[@]}-1]}"
|
|
88
86
|
|
|
89
|
-
|
|
87
|
+
# Strip --opt= prefix for native file/directory completion
|
|
88
|
+
local inline_prefix=""
|
|
89
|
+
if [[ "$cur" == --*=* ]]; then
|
|
90
|
+
inline_prefix="\${cur%%=*}="
|
|
91
|
+
cur="\${cur#*=}"
|
|
92
|
+
fi
|
|
90
93
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
# 16 = FileCompletion: delegate entirely to native file completion
|
|
95
|
+
if (( directive & 16 )); then
|
|
96
|
+
local -a entries=($(compgen -f -- "$cur"))
|
|
97
|
+
if [[ -n "$inline_prefix" ]]; then
|
|
98
|
+
local i
|
|
99
|
+
for (( i=0; i<\${#entries[@]}; i++ )); do
|
|
100
|
+
entries[$i]="\${inline_prefix}\${entries[$i]}"
|
|
101
|
+
done
|
|
102
|
+
fi
|
|
103
|
+
COMPREPLY=("\${entries[@]}")
|
|
104
|
+
compopt -o filenames
|
|
105
|
+
return 0
|
|
106
|
+
fi
|
|
96
107
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
108
|
+
# Extension-filtered file completion: keep matching files + directories
|
|
109
|
+
if [[ -n "$extensions" ]]; then
|
|
110
|
+
local -a all_entries=($(compgen -f -- "$cur"))
|
|
111
|
+
local IFS=','
|
|
112
|
+
local -a ext_arr=($extensions)
|
|
113
|
+
IFS=$'\\n'
|
|
114
|
+
for f in "\${all_entries[@]}"; do
|
|
115
|
+
if [[ -d "$f" ]]; then
|
|
116
|
+
COMPREPLY+=("\${inline_prefix}$f")
|
|
117
|
+
else
|
|
118
|
+
for ext in "\${ext_arr[@]}"; do
|
|
119
|
+
if [[ "$f" == *".$ext" ]]; then
|
|
120
|
+
COMPREPLY+=("\${inline_prefix}$f")
|
|
100
121
|
break
|
|
101
122
|
fi
|
|
102
123
|
done
|
|
103
|
-
|
|
124
|
+
fi
|
|
125
|
+
done
|
|
126
|
+
compopt -o filenames
|
|
127
|
+
compopt +o default 2>/dev/null
|
|
128
|
+
return 0
|
|
129
|
+
fi
|
|
104
130
|
|
|
105
|
-
|
|
131
|
+
# Start with JS candidates
|
|
132
|
+
if (( \${#lines[@]} > 0 )); then
|
|
133
|
+
COMPREPLY=("\${lines[@]}")
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# 32 = DirectoryCompletion: merge native directory matches
|
|
137
|
+
if (( directive & 32 )); then
|
|
138
|
+
local -a dirs=($(compgen -d -- "$cur"))
|
|
139
|
+
if [[ -n "$inline_prefix" ]]; then
|
|
140
|
+
local i
|
|
141
|
+
for (( i=0; i<\${#dirs[@]}; i++ )); do
|
|
142
|
+
dirs[$i]="\${inline_prefix}\${dirs[$i]}"
|
|
143
|
+
done
|
|
106
144
|
fi
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
elif [[ \${#candidates[@]} -gt 0 ]]; then
|
|
110
|
-
COMPREPLY=($(compgen -W "\${candidates[*]}" -- "$completion_cur"))
|
|
145
|
+
COMPREPLY+=("\${dirs[@]}")
|
|
146
|
+
compopt -o filenames
|
|
111
147
|
fi
|
|
112
148
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
prefixed+=("$completion_prefix$candidate")
|
|
118
|
-
done
|
|
119
|
-
COMPREPLY=("\${prefixed[@]}")
|
|
149
|
+
# 2 = NoFileCompletion, 32 = DirectoryCompletion:
|
|
150
|
+
# suppress -o default file fallback when completions are restricted
|
|
151
|
+
if (( directive & 2 )) || (( directive & 32 )); then
|
|
152
|
+
compopt +o default 2>/dev/null
|
|
120
153
|
fi
|
|
121
154
|
|
|
122
155
|
return 0
|
|
123
156
|
}
|
|
124
157
|
|
|
125
158
|
# Register the completion function
|
|
126
|
-
complete -F _${programName}_completions ${programName}
|
|
159
|
+
complete -o default -F _${programName}_completions ${programName}
|
|
127
160
|
`,
|
|
128
161
|
shell: "bash",
|
|
129
162
|
installInstructions: `# To enable completions, add the following to your ~/.bashrc:
|
|
@@ -142,6 +175,9 @@ source ~/.bashrc`
|
|
|
142
175
|
//#endregion
|
|
143
176
|
//#region src/completion/dynamic/candidate-generator.ts
|
|
144
177
|
/**
|
|
178
|
+
* Generate completion candidates based on context
|
|
179
|
+
*/
|
|
180
|
+
/**
|
|
145
181
|
* Completion directive flags (bitwise)
|
|
146
182
|
*/
|
|
147
183
|
const CompletionDirective = {
|
|
@@ -171,14 +207,61 @@ function generateCandidates(context) {
|
|
|
171
207
|
};
|
|
172
208
|
}
|
|
173
209
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Execute a shell command and return results as candidates
|
|
212
|
+
*/
|
|
213
|
+
function executeShellCommand(command) {
|
|
214
|
+
try {
|
|
215
|
+
return (0, node_child_process.execSync)(command, {
|
|
216
|
+
encoding: "utf-8",
|
|
217
|
+
timeout: 5e3
|
|
218
|
+
}).split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => ({
|
|
219
|
+
value: line,
|
|
220
|
+
type: "value"
|
|
221
|
+
}));
|
|
222
|
+
} catch {
|
|
223
|
+
return [];
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Resolve value completion, executing shell commands and file lookups in JS
|
|
228
|
+
*/
|
|
229
|
+
function resolveValueCandidates(vc, candidates, _currentWord, description) {
|
|
230
|
+
let directive = CompletionDirective.FilterPrefix;
|
|
231
|
+
let fileExtensions;
|
|
232
|
+
switch (vc.type) {
|
|
233
|
+
case "choices":
|
|
234
|
+
if (vc.choices) for (const choice of vc.choices) candidates.push({
|
|
235
|
+
value: choice,
|
|
236
|
+
description,
|
|
237
|
+
type: "value"
|
|
238
|
+
});
|
|
239
|
+
directive |= CompletionDirective.NoFileCompletion;
|
|
240
|
+
break;
|
|
241
|
+
case "file":
|
|
242
|
+
if (vc.extensions && vc.extensions.length > 0) {
|
|
243
|
+
fileExtensions = Array.from(new Set(vc.extensions.map((ext) => ext.trim().replace(/^\./, "")).filter((ext) => ext.length > 0)));
|
|
244
|
+
if (fileExtensions.length === 0) {
|
|
245
|
+
fileExtensions = void 0;
|
|
246
|
+
directive |= CompletionDirective.FileCompletion;
|
|
247
|
+
}
|
|
248
|
+
} else directive |= CompletionDirective.FileCompletion;
|
|
249
|
+
break;
|
|
250
|
+
case "directory":
|
|
251
|
+
directive |= CompletionDirective.DirectoryCompletion;
|
|
252
|
+
break;
|
|
253
|
+
case "command":
|
|
254
|
+
if (vc.shellCommand) candidates.push(...executeShellCommand(vc.shellCommand));
|
|
255
|
+
directive |= CompletionDirective.NoFileCompletion;
|
|
256
|
+
break;
|
|
257
|
+
case "none":
|
|
258
|
+
directive |= CompletionDirective.NoFileCompletion;
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
directive,
|
|
263
|
+
fileExtensions
|
|
264
|
+
};
|
|
182
265
|
}
|
|
183
266
|
/**
|
|
184
267
|
* Generate subcommand candidates
|
|
@@ -237,43 +320,20 @@ function generateOptionNameCandidates(context) {
|
|
|
237
320
|
*/
|
|
238
321
|
function generateOptionValueCandidates(context) {
|
|
239
322
|
const candidates = [];
|
|
240
|
-
let directive = CompletionDirective.FilterPrefix;
|
|
241
323
|
if (!context.targetOption) return {
|
|
242
324
|
candidates,
|
|
243
|
-
directive
|
|
325
|
+
directive: CompletionDirective.FilterPrefix
|
|
244
326
|
};
|
|
245
327
|
const vc = context.targetOption.valueCompletion;
|
|
246
328
|
if (!vc) return {
|
|
247
329
|
candidates,
|
|
248
|
-
directive
|
|
330
|
+
directive: CompletionDirective.FilterPrefix
|
|
249
331
|
};
|
|
250
|
-
|
|
251
|
-
case "choices":
|
|
252
|
-
if (vc.choices) for (const choice of vc.choices) candidates.push({
|
|
253
|
-
value: choice,
|
|
254
|
-
type: "value"
|
|
255
|
-
});
|
|
256
|
-
break;
|
|
257
|
-
case "file":
|
|
258
|
-
directive |= CompletionDirective.FileCompletion;
|
|
259
|
-
addFileExtensionMetadata(candidates, vc.extensions);
|
|
260
|
-
break;
|
|
261
|
-
case "directory":
|
|
262
|
-
directive |= CompletionDirective.DirectoryCompletion;
|
|
263
|
-
break;
|
|
264
|
-
case "command":
|
|
265
|
-
if (vc.shellCommand) candidates.push({
|
|
266
|
-
value: `__command:${vc.shellCommand}`,
|
|
267
|
-
type: "value"
|
|
268
|
-
});
|
|
269
|
-
break;
|
|
270
|
-
case "none":
|
|
271
|
-
directive |= CompletionDirective.NoFileCompletion;
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
332
|
+
const { directive, fileExtensions } = resolveValueCandidates(vc, candidates, context.currentWord);
|
|
274
333
|
return {
|
|
275
334
|
candidates,
|
|
276
|
-
directive
|
|
335
|
+
directive,
|
|
336
|
+
fileExtensions
|
|
277
337
|
};
|
|
278
338
|
}
|
|
279
339
|
/**
|
|
@@ -281,71 +341,36 @@ function generateOptionValueCandidates(context) {
|
|
|
281
341
|
*/
|
|
282
342
|
function generatePositionalCandidates(context) {
|
|
283
343
|
const candidates = [];
|
|
284
|
-
let directive = CompletionDirective.FilterPrefix;
|
|
285
344
|
const positionalIndex = context.positionalIndex ?? 0;
|
|
286
|
-
const positional = context.positionals[positionalIndex];
|
|
345
|
+
const positional = context.positionals[positionalIndex] ?? (context.positionals.at(-1)?.variadic ? context.positionals.at(-1) : void 0);
|
|
287
346
|
if (!positional) return {
|
|
288
347
|
candidates,
|
|
289
|
-
directive
|
|
348
|
+
directive: CompletionDirective.FilterPrefix
|
|
290
349
|
};
|
|
291
350
|
const vc = positional.valueCompletion;
|
|
292
351
|
if (!vc) return {
|
|
293
352
|
candidates,
|
|
294
|
-
directive
|
|
353
|
+
directive: CompletionDirective.FilterPrefix
|
|
295
354
|
};
|
|
296
|
-
|
|
297
|
-
case "choices":
|
|
298
|
-
if (vc.choices) for (const choice of vc.choices) candidates.push({
|
|
299
|
-
value: choice,
|
|
300
|
-
description: positional.description,
|
|
301
|
-
type: "value"
|
|
302
|
-
});
|
|
303
|
-
break;
|
|
304
|
-
case "file":
|
|
305
|
-
directive |= CompletionDirective.FileCompletion;
|
|
306
|
-
addFileExtensionMetadata(candidates, vc.extensions);
|
|
307
|
-
break;
|
|
308
|
-
case "directory":
|
|
309
|
-
directive |= CompletionDirective.DirectoryCompletion;
|
|
310
|
-
break;
|
|
311
|
-
case "command":
|
|
312
|
-
if (vc.shellCommand) candidates.push({
|
|
313
|
-
value: `__command:${vc.shellCommand}`,
|
|
314
|
-
type: "value"
|
|
315
|
-
});
|
|
316
|
-
break;
|
|
317
|
-
case "none":
|
|
318
|
-
directive |= CompletionDirective.NoFileCompletion;
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
355
|
+
const { directive, fileExtensions } = resolveValueCandidates(vc, candidates, context.currentWord, positional.description);
|
|
321
356
|
return {
|
|
322
357
|
candidates,
|
|
323
|
-
directive
|
|
358
|
+
directive,
|
|
359
|
+
fileExtensions
|
|
324
360
|
};
|
|
325
361
|
}
|
|
326
|
-
/**
|
|
327
|
-
* Format candidates as shell completion output
|
|
328
|
-
*
|
|
329
|
-
* Format: value\tdescription (tab-separated)
|
|
330
|
-
* Last line: :directive_code
|
|
331
|
-
*/
|
|
332
|
-
function formatOutput(result) {
|
|
333
|
-
const lines = [];
|
|
334
|
-
for (const candidate of result.candidates) if (candidate.description) lines.push(`${candidate.value}\t${candidate.description}`);
|
|
335
|
-
else lines.push(candidate.value);
|
|
336
|
-
lines.push(`:${result.directive}`);
|
|
337
|
-
return lines.join("\n");
|
|
338
|
-
}
|
|
339
362
|
|
|
340
363
|
//#endregion
|
|
341
|
-
//#region src/completion/
|
|
342
|
-
/**
|
|
343
|
-
* Parse completion context from partial command line
|
|
344
|
-
*/
|
|
364
|
+
//#region src/completion/value-completion-resolver.ts
|
|
345
365
|
/**
|
|
346
366
|
* Resolve value completion from field metadata
|
|
367
|
+
*
|
|
368
|
+
* Priority:
|
|
369
|
+
* 1. Explicit custom completion (choices or shellCommand)
|
|
370
|
+
* 2. Explicit completion type (file, directory, none)
|
|
371
|
+
* 3. Auto-detected enum values from schema
|
|
347
372
|
*/
|
|
348
|
-
function resolveValueCompletion
|
|
373
|
+
function resolveValueCompletion(field) {
|
|
349
374
|
const meta = field.completion;
|
|
350
375
|
if (meta?.custom) {
|
|
351
376
|
if (meta.custom.choices && meta.custom.choices.length > 0) return {
|
|
@@ -370,6 +395,12 @@ function resolveValueCompletion$1(field) {
|
|
|
370
395
|
choices: field.enumValues
|
|
371
396
|
};
|
|
372
397
|
}
|
|
398
|
+
|
|
399
|
+
//#endregion
|
|
400
|
+
//#region src/completion/dynamic/context-parser.ts
|
|
401
|
+
/**
|
|
402
|
+
* Parse completion context from partial command line
|
|
403
|
+
*/
|
|
373
404
|
/**
|
|
374
405
|
* Extract options from a command
|
|
375
406
|
*/
|
|
@@ -383,7 +414,7 @@ function extractOptions$1(command) {
|
|
|
383
414
|
takesValue: field.type !== "boolean",
|
|
384
415
|
valueType: field.type,
|
|
385
416
|
required: field.required,
|
|
386
|
-
valueCompletion: resolveValueCompletion
|
|
417
|
+
valueCompletion: resolveValueCompletion(field)
|
|
387
418
|
}));
|
|
388
419
|
}
|
|
389
420
|
/**
|
|
@@ -397,7 +428,8 @@ function extractPositionalsForContext(command) {
|
|
|
397
428
|
position: index,
|
|
398
429
|
description: field.description,
|
|
399
430
|
required: field.required,
|
|
400
|
-
|
|
431
|
+
variadic: field.type === "array",
|
|
432
|
+
valueCompletion: resolveValueCompletion(field)
|
|
401
433
|
}));
|
|
402
434
|
}
|
|
403
435
|
/**
|
|
@@ -506,7 +538,11 @@ function parseCompletionContext(argv, rootCommand) {
|
|
|
506
538
|
if (opt && opt.takesValue) {
|
|
507
539
|
completionType = "option-value";
|
|
508
540
|
targetOption = opt;
|
|
509
|
-
} else
|
|
541
|
+
} else if (currentWord.startsWith("-")) completionType = "option-name";
|
|
542
|
+
else {
|
|
543
|
+
completionType = determineDefaultCompletionType(currentWord, subcommands, positionals, positionalCount);
|
|
544
|
+
if (completionType === "positional") positionalIndex = positionalCount;
|
|
545
|
+
}
|
|
510
546
|
} else if (!afterDoubleDash && currentWord.startsWith("--") && hasInlineValue(currentWord)) {
|
|
511
547
|
const optName = parseOptionName(currentWord);
|
|
512
548
|
const opt = findOption(options, optName);
|
|
@@ -516,7 +552,7 @@ function parseCompletionContext(argv, rootCommand) {
|
|
|
516
552
|
} else completionType = "option-name";
|
|
517
553
|
} else if (!afterDoubleDash && currentWord.startsWith("-")) completionType = "option-name";
|
|
518
554
|
else {
|
|
519
|
-
completionType = determineDefaultCompletionType(currentWord, subcommands, positionals, positionalCount);
|
|
555
|
+
completionType = determineDefaultCompletionType(currentWord, subcommands, positionals, positionalCount, afterDoubleDash);
|
|
520
556
|
if (completionType === "positional") positionalIndex = positionalCount;
|
|
521
557
|
}
|
|
522
558
|
return {
|
|
@@ -537,15 +573,99 @@ function parseCompletionContext(argv, rootCommand) {
|
|
|
537
573
|
/**
|
|
538
574
|
* Determine default completion type when not completing an option
|
|
539
575
|
*/
|
|
540
|
-
function determineDefaultCompletionType(currentWord, subcommands, positionals, positionalCount) {
|
|
576
|
+
function determineDefaultCompletionType(currentWord, subcommands, positionals, positionalCount, afterDoubleDash) {
|
|
577
|
+
if (afterDoubleDash) return "positional";
|
|
541
578
|
if (subcommands.length > 0) {
|
|
542
579
|
if (subcommands.filter((s) => s.startsWith(currentWord)).length > 0 || currentWord === "") return "subcommand";
|
|
543
580
|
}
|
|
544
581
|
if (positionalCount < positionals.length) return "positional";
|
|
545
|
-
if (positionals.length > 0) return "positional";
|
|
582
|
+
if (positionals.length > 0 && positionals[positionals.length - 1].variadic) return "positional";
|
|
546
583
|
return "subcommand";
|
|
547
584
|
}
|
|
548
585
|
|
|
586
|
+
//#endregion
|
|
587
|
+
//#region src/completion/dynamic/shell-formatter.ts
|
|
588
|
+
/**
|
|
589
|
+
* Format completion candidates for the specified shell
|
|
590
|
+
*
|
|
591
|
+
* @returns Shell-ready output string (lines separated by newline, last line is :directive)
|
|
592
|
+
*/
|
|
593
|
+
function formatForShell(result, options) {
|
|
594
|
+
switch (options.shell) {
|
|
595
|
+
case "bash": return formatForBash(result, options);
|
|
596
|
+
case "zsh": return formatForZsh(result, options);
|
|
597
|
+
case "fish": return formatForFish(result, options);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Check if the FilterPrefix directive is set
|
|
602
|
+
*/
|
|
603
|
+
function shouldFilterPrefix(directive) {
|
|
604
|
+
return (directive & CompletionDirective.FilterPrefix) !== 0;
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Filter candidates by prefix
|
|
608
|
+
*/
|
|
609
|
+
function filterByPrefix(candidates, prefix) {
|
|
610
|
+
if (!prefix) return candidates;
|
|
611
|
+
return candidates.filter((c) => c.value.startsWith(prefix));
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Append extension metadata and directive to output lines
|
|
615
|
+
*/
|
|
616
|
+
function appendMetadata(lines, result) {
|
|
617
|
+
if (result.fileExtensions && result.fileExtensions.length > 0) lines.push(`@ext:${result.fileExtensions.join(",")}`);
|
|
618
|
+
lines.push(`:${result.directive}`);
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Format for bash
|
|
622
|
+
*
|
|
623
|
+
* - Pre-filters candidates by currentWord prefix (replaces compgen -W)
|
|
624
|
+
* - Handles --opt=value inline values by prepending prefix
|
|
625
|
+
* - Outputs plain values only (no descriptions - bash COMPREPLY doesn't support them)
|
|
626
|
+
* - Last line: :directive
|
|
627
|
+
*/
|
|
628
|
+
function formatForBash(result, options) {
|
|
629
|
+
let { candidates } = result;
|
|
630
|
+
if (shouldFilterPrefix(result.directive)) candidates = filterByPrefix(candidates, options.currentWord);
|
|
631
|
+
const lines = candidates.map((c) => {
|
|
632
|
+
if (options.inlinePrefix) return `${options.inlinePrefix}${c.value}`;
|
|
633
|
+
return c.value;
|
|
634
|
+
});
|
|
635
|
+
appendMetadata(lines, result);
|
|
636
|
+
return lines.join("\n");
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Format for zsh
|
|
640
|
+
*
|
|
641
|
+
* - Outputs value:description pairs for _describe
|
|
642
|
+
* - Colons in values/descriptions are escaped with backslash
|
|
643
|
+
* - Last line: :directive
|
|
644
|
+
*/
|
|
645
|
+
function formatForZsh(result, _options) {
|
|
646
|
+
const lines = result.candidates.map((c) => {
|
|
647
|
+
const escapedValue = c.value.replace(/:/g, "\\:");
|
|
648
|
+
if (c.description) return `${escapedValue}:${c.description.replace(/:/g, "\\:")}`;
|
|
649
|
+
return escapedValue;
|
|
650
|
+
});
|
|
651
|
+
appendMetadata(lines, result);
|
|
652
|
+
return lines.join("\n");
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Format for fish
|
|
656
|
+
*
|
|
657
|
+
* - Outputs value\tdescription pairs
|
|
658
|
+
* - Last line: :directive
|
|
659
|
+
*/
|
|
660
|
+
function formatForFish(result, _options) {
|
|
661
|
+
const lines = result.candidates.map((c) => {
|
|
662
|
+
if (c.description) return `${c.value}\t${c.description}`;
|
|
663
|
+
return c.value;
|
|
664
|
+
});
|
|
665
|
+
appendMetadata(lines, result);
|
|
666
|
+
return lines.join("\n");
|
|
667
|
+
}
|
|
668
|
+
|
|
549
669
|
//#endregion
|
|
550
670
|
//#region src/completion/dynamic/complete-command.ts
|
|
551
671
|
/**
|
|
@@ -554,24 +674,35 @@ function determineDefaultCompletionType(currentWord, subcommands, positionals, p
|
|
|
554
674
|
* This creates a hidden `__complete` command that outputs completion candidates
|
|
555
675
|
* for shell scripts to consume. Usage:
|
|
556
676
|
*
|
|
557
|
-
* mycli __complete -- build --fo
|
|
558
|
-
* mycli __complete -- plugin add
|
|
677
|
+
* mycli __complete --shell bash -- build --fo
|
|
678
|
+
* mycli __complete --shell zsh -- plugin add
|
|
559
679
|
*
|
|
560
|
-
* Output format:
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
* :
|
|
680
|
+
* Output format depends on the target shell:
|
|
681
|
+
* bash: plain values (pre-filtered by prefix), last line :directive
|
|
682
|
+
* zsh: value:description pairs, last line :directive
|
|
683
|
+
* fish: value\tdescription pairs, last line :directive
|
|
684
|
+
*/
|
|
685
|
+
/**
|
|
686
|
+
* Detect inline option-value prefix (e.g., "--format=" from "--format=json")
|
|
564
687
|
*/
|
|
688
|
+
function detectInlinePrefix(currentWord) {
|
|
689
|
+
if (currentWord.startsWith("--") && currentWord.includes("=")) return currentWord.slice(0, currentWord.indexOf("=") + 1);
|
|
690
|
+
}
|
|
565
691
|
/**
|
|
566
692
|
* Schema for the __complete command
|
|
567
|
-
*
|
|
568
|
-
* Arguments after -- are collected as the completion arguments
|
|
569
693
|
*/
|
|
570
|
-
const completeArgsSchema = zod.z.object({
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
694
|
+
const completeArgsSchema = zod.z.object({
|
|
695
|
+
shell: require_schema_extractor.arg(zod.z.enum([
|
|
696
|
+
"bash",
|
|
697
|
+
"zsh",
|
|
698
|
+
"fish"
|
|
699
|
+
]), { description: "Target shell for output formatting" }),
|
|
700
|
+
args: require_schema_extractor.arg(zod.z.array(zod.z.string()).default([]), {
|
|
701
|
+
positional: true,
|
|
702
|
+
description: "Arguments to complete",
|
|
703
|
+
variadic: true
|
|
704
|
+
})
|
|
705
|
+
});
|
|
575
706
|
/**
|
|
576
707
|
* Create the dynamic completion command
|
|
577
708
|
*
|
|
@@ -584,8 +715,15 @@ function createDynamicCompleteCommand(rootCommand, _programName) {
|
|
|
584
715
|
name: "__complete",
|
|
585
716
|
args: completeArgsSchema,
|
|
586
717
|
run(args) {
|
|
587
|
-
const
|
|
588
|
-
|
|
718
|
+
const context = parseCompletionContext(args.args, rootCommand);
|
|
719
|
+
const result = generateCandidates(context);
|
|
720
|
+
const inlinePrefix = detectInlinePrefix(context.currentWord);
|
|
721
|
+
const output = formatForShell(result, {
|
|
722
|
+
shell: args.shell,
|
|
723
|
+
currentWord: inlinePrefix ? context.currentWord.slice(inlinePrefix.length) : context.currentWord,
|
|
724
|
+
inlinePrefix
|
|
725
|
+
});
|
|
726
|
+
console.log(output);
|
|
589
727
|
}
|
|
590
728
|
});
|
|
591
729
|
}
|
|
@@ -601,81 +739,75 @@ function hasCompleteCommand(command) {
|
|
|
601
739
|
/**
|
|
602
740
|
* Generate fish completion script for a command
|
|
603
741
|
*
|
|
604
|
-
* Generates a
|
|
742
|
+
* Generates a minimal script that delegates all logic to the CLI's __complete command.
|
|
743
|
+
* The shell script only handles:
|
|
744
|
+
* - Getting current command line tokens
|
|
745
|
+
* - Calling __complete with --shell fish
|
|
746
|
+
* - Echoing output as completions
|
|
747
|
+
* - Falling back to native file/directory completion when directed
|
|
605
748
|
*/
|
|
606
749
|
function generateFishCompletion(_command, options) {
|
|
607
750
|
const programName = options.programName;
|
|
608
751
|
return {
|
|
609
752
|
script: `# Fish completion for ${programName}
|
|
610
753
|
# Generated by politty
|
|
611
|
-
# This script calls the CLI to generate completions dynamically
|
|
612
754
|
|
|
613
755
|
function __fish_${programName}_complete
|
|
614
|
-
# Get current command line arguments
|
|
615
756
|
set -l args (commandline -opc)
|
|
616
|
-
# Remove the program name
|
|
617
757
|
set -e args[1]
|
|
618
|
-
|
|
619
|
-
# Call the CLI to get completions
|
|
620
758
|
set -l directive 0
|
|
621
|
-
set -l
|
|
622
|
-
|
|
759
|
+
set -l extensions ""
|
|
760
|
+
|
|
761
|
+
# commandline -opc excludes the current token; always include it
|
|
762
|
+
set -l ct (commandline -ct)
|
|
763
|
+
if test (count $ct) -eq 0
|
|
764
|
+
set -a args ""
|
|
765
|
+
else
|
|
766
|
+
set -a args $ct
|
|
767
|
+
end
|
|
623
768
|
|
|
624
|
-
for line in (${programName} __complete -- $args 2>/dev/null)
|
|
769
|
+
for line in (${programName} __complete --shell fish -- $args 2>/dev/null)
|
|
625
770
|
if string match -q ':*' -- $line
|
|
626
|
-
# Parse directive
|
|
627
771
|
set directive (string sub -s 2 -- $line)
|
|
628
|
-
else if string match -q '
|
|
629
|
-
|
|
630
|
-
set command_completion (string sub -s 11 -- $line)
|
|
631
|
-
else if string match -q '__extensions:*' -- $line
|
|
632
|
-
# Parse optional file extension metadata
|
|
633
|
-
set file_extensions (string sub -s 14 -- $line)
|
|
772
|
+
else if string match -q '@ext:*' -- $line
|
|
773
|
+
set extensions (string sub -s 6 -- $line)
|
|
634
774
|
else if test -n "$line"
|
|
635
|
-
|
|
636
|
-
set -l parts (string split \\t -- $line)
|
|
637
|
-
if test (count $parts) -ge 2
|
|
638
|
-
echo $parts[1]\\t$parts[2]
|
|
639
|
-
else
|
|
640
|
-
echo $parts[1]
|
|
641
|
-
end
|
|
775
|
+
echo $line
|
|
642
776
|
end
|
|
643
777
|
end
|
|
644
778
|
|
|
645
|
-
#
|
|
646
|
-
if test
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
779
|
+
# 16 = FileCompletion: delegate entirely to native file completion
|
|
780
|
+
if test (math "bitand($directive, 16)") -ne 0
|
|
781
|
+
__fish_complete_path
|
|
782
|
+
return
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
# Extension-filtered file completion: keep matching files + directories
|
|
786
|
+
if test -n "$extensions"
|
|
787
|
+
set -l cur (commandline -ct)
|
|
788
|
+
test (count $cur) -eq 0; and set cur ""
|
|
789
|
+
__fish_complete_directories "$cur"
|
|
790
|
+
for ext in (string split "," -- $extensions)
|
|
791
|
+
for f in "$cur"*.$ext
|
|
792
|
+
if test -f "$f"
|
|
793
|
+
echo $f
|
|
794
|
+
end
|
|
650
795
|
end
|
|
651
796
|
end
|
|
797
|
+
return
|
|
652
798
|
end
|
|
653
799
|
|
|
654
|
-
#
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
echo "__directive:file"
|
|
658
|
-
else if test (math "$directive & 32") -ne 0
|
|
659
|
-
echo "__directive:directory"
|
|
800
|
+
# 32 = DirectoryCompletion: add native directory matches
|
|
801
|
+
if test (math "bitand($directive, 32)") -ne 0
|
|
802
|
+
__fish_complete_directories
|
|
660
803
|
end
|
|
661
804
|
end
|
|
662
805
|
|
|
663
806
|
# Clear existing completions
|
|
664
807
|
complete -e -c ${programName}
|
|
665
808
|
|
|
666
|
-
#
|
|
667
|
-
complete -c ${programName} -f -a '(
|
|
668
|
-
set -l completions (__fish_${programName}_complete)
|
|
669
|
-
for c in $completions
|
|
670
|
-
if string match -q "__directive:file" -- $c
|
|
671
|
-
__fish_complete_path
|
|
672
|
-
else if string match -q "__directive:directory" -- $c
|
|
673
|
-
__fish_complete_directories
|
|
674
|
-
else
|
|
675
|
-
echo $c
|
|
676
|
-
end
|
|
677
|
-
end
|
|
678
|
-
)'
|
|
809
|
+
# Register completion
|
|
810
|
+
complete -c ${programName} -f -a '(__fish_${programName}_complete)'
|
|
679
811
|
`,
|
|
680
812
|
shell: "fish",
|
|
681
813
|
installInstructions: `# To enable completions, run one of the following:
|
|
@@ -697,7 +829,12 @@ source ~/.config/fish/completions/${programName}.fish`
|
|
|
697
829
|
/**
|
|
698
830
|
* Generate zsh completion script for a command
|
|
699
831
|
*
|
|
700
|
-
* Generates a
|
|
832
|
+
* Generates a minimal script that delegates all logic to the CLI's __complete command.
|
|
833
|
+
* The shell script only handles:
|
|
834
|
+
* - Getting current command line tokens
|
|
835
|
+
* - Calling __complete with --shell zsh
|
|
836
|
+
* - Passing output directly to _describe
|
|
837
|
+
* - Falling back to native file/directory completion when directed
|
|
701
838
|
*/
|
|
702
839
|
function generateZshCompletion(_command, options) {
|
|
703
840
|
const programName = options.programName;
|
|
@@ -709,57 +846,55 @@ function generateZshCompletion(_command, options) {
|
|
|
709
846
|
|
|
710
847
|
_${programName}() {
|
|
711
848
|
local -a candidates
|
|
712
|
-
local
|
|
713
|
-
local
|
|
714
|
-
local
|
|
849
|
+
local line directive=0
|
|
850
|
+
local -a args=("\${words[@]:1}")
|
|
851
|
+
local -a output=("\${(@f)$(${programName} __complete --shell zsh -- "\${args[@]}" 2>/dev/null)}")
|
|
715
852
|
|
|
716
|
-
|
|
717
|
-
local -a args
|
|
718
|
-
args=("\${words[@]:1}")
|
|
719
|
-
|
|
720
|
-
# Call the CLI to get completions
|
|
721
|
-
output=("\${(@f)$(${programName} __complete -- "\${args[@]}" 2>/dev/null)}")
|
|
722
|
-
|
|
723
|
-
# Parse output
|
|
853
|
+
local extensions=""
|
|
724
854
|
for line in "\${output[@]}"; do
|
|
725
855
|
if [[ "$line" == :* ]]; then
|
|
726
856
|
directive="\${line:1}"
|
|
727
|
-
elif [[ "$line" ==
|
|
728
|
-
|
|
729
|
-
elif [[ "$line" == __extensions:* ]]; then
|
|
730
|
-
file_extensions="\${line#__extensions:}"
|
|
857
|
+
elif [[ "$line" == @ext:* ]]; then
|
|
858
|
+
extensions="\${line:5}"
|
|
731
859
|
elif [[ -n "$line" ]]; then
|
|
732
|
-
|
|
733
|
-
local desc="\${line#*$'\\t'}"
|
|
734
|
-
if [[ "$name" == "$desc" ]]; then
|
|
735
|
-
candidates+=("$name")
|
|
736
|
-
else
|
|
737
|
-
candidates+=("$name:$desc")
|
|
738
|
-
fi
|
|
860
|
+
candidates+=("$line")
|
|
739
861
|
fi
|
|
740
862
|
done
|
|
741
863
|
|
|
742
|
-
#
|
|
743
|
-
if
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
864
|
+
# 16 = FileCompletion: delegate entirely to native file completion
|
|
865
|
+
if (( directive & 16 )); then
|
|
866
|
+
_files
|
|
867
|
+
return 0
|
|
868
|
+
fi
|
|
869
|
+
|
|
870
|
+
# Extension-filtered file completion: call _files -g per extension
|
|
871
|
+
if [[ -n "$extensions" ]]; then
|
|
872
|
+
local ext
|
|
873
|
+
for ext in \${(s:,:)extensions}; do
|
|
874
|
+
_files -g "*.$ext"
|
|
749
875
|
done
|
|
876
|
+
return 0
|
|
750
877
|
fi
|
|
751
878
|
|
|
752
|
-
#
|
|
753
|
-
# 16 = FileCompletion, 32 = DirectoryCompletion
|
|
754
|
-
if (( directive & 16 )); then
|
|
755
|
-
_files
|
|
756
|
-
elif (( directive & 32 )); then
|
|
757
|
-
_files -/
|
|
758
|
-
elif (( \${#candidates[@]} > 0 )); then
|
|
879
|
+
if (( \${#candidates[@]} > 0 )); then
|
|
759
880
|
_describe 'completions' candidates
|
|
760
881
|
fi
|
|
882
|
+
|
|
883
|
+
# 32 = DirectoryCompletion: add native directory matches
|
|
884
|
+
if (( directive & 32 )); then
|
|
885
|
+
_files -/
|
|
886
|
+
fi
|
|
887
|
+
|
|
888
|
+
# 2 = NoFileCompletion, 32 = DirectoryCompletion:
|
|
889
|
+
# prevent fallback to default completers (e.g. file completion)
|
|
890
|
+
if (( directive & 2 )) || (( directive & 32 )); then
|
|
891
|
+
return 0
|
|
892
|
+
fi
|
|
761
893
|
}
|
|
762
894
|
|
|
895
|
+
# Prevent _files -g from falling back to showing all files when no pattern matches
|
|
896
|
+
zstyle ':completion:*:*:${programName}:*' file-patterns '%p:globbed-files *(-/):directories'
|
|
897
|
+
|
|
763
898
|
compdef _${programName} ${programName}
|
|
764
899
|
`,
|
|
765
900
|
shell: "zsh",
|
|
@@ -786,39 +921,6 @@ source ~/.zshrc`
|
|
|
786
921
|
* Extract completion data from commands
|
|
787
922
|
*/
|
|
788
923
|
/**
|
|
789
|
-
* Resolve value completion from field metadata
|
|
790
|
-
*
|
|
791
|
-
* Priority:
|
|
792
|
-
* 1. Explicit custom completion (choices or shellCommand)
|
|
793
|
-
* 2. Explicit completion type (file, directory, none)
|
|
794
|
-
* 3. Auto-detected enum values from schema
|
|
795
|
-
*/
|
|
796
|
-
function resolveValueCompletion(field) {
|
|
797
|
-
const meta = field.completion;
|
|
798
|
-
if (meta?.custom) {
|
|
799
|
-
if (meta.custom.choices && meta.custom.choices.length > 0) return {
|
|
800
|
-
type: "choices",
|
|
801
|
-
choices: meta.custom.choices
|
|
802
|
-
};
|
|
803
|
-
if (meta.custom.shellCommand) return {
|
|
804
|
-
type: "command",
|
|
805
|
-
shellCommand: meta.custom.shellCommand
|
|
806
|
-
};
|
|
807
|
-
}
|
|
808
|
-
if (meta?.type) {
|
|
809
|
-
if (meta.type === "file") return meta.extensions ? {
|
|
810
|
-
type: "file",
|
|
811
|
-
extensions: meta.extensions
|
|
812
|
-
} : { type: "file" };
|
|
813
|
-
if (meta.type === "directory") return { type: "directory" };
|
|
814
|
-
if (meta.type === "none") return { type: "none" };
|
|
815
|
-
}
|
|
816
|
-
if (field.enumValues && field.enumValues.length > 0) return {
|
|
817
|
-
type: "choices",
|
|
818
|
-
choices: field.enumValues
|
|
819
|
-
};
|
|
820
|
-
}
|
|
821
|
-
/**
|
|
822
924
|
* Convert a resolved field to a completable option
|
|
823
925
|
*/
|
|
824
926
|
function fieldToOption(field) {
|
|
@@ -925,10 +1027,10 @@ Object.defineProperty(exports, 'extractPositionals', {
|
|
|
925
1027
|
return extractPositionals;
|
|
926
1028
|
}
|
|
927
1029
|
});
|
|
928
|
-
Object.defineProperty(exports, '
|
|
1030
|
+
Object.defineProperty(exports, 'formatForShell', {
|
|
929
1031
|
enumerable: true,
|
|
930
1032
|
get: function () {
|
|
931
|
-
return
|
|
1033
|
+
return formatForShell;
|
|
932
1034
|
}
|
|
933
1035
|
});
|
|
934
1036
|
Object.defineProperty(exports, 'generateBashCompletion', {
|
|
@@ -967,4 +1069,10 @@ Object.defineProperty(exports, 'parseCompletionContext', {
|
|
|
967
1069
|
return parseCompletionContext;
|
|
968
1070
|
}
|
|
969
1071
|
});
|
|
970
|
-
|
|
1072
|
+
Object.defineProperty(exports, 'resolveValueCompletion', {
|
|
1073
|
+
enumerable: true,
|
|
1074
|
+
get: function () {
|
|
1075
|
+
return resolveValueCompletion;
|
|
1076
|
+
}
|
|
1077
|
+
});
|
|
1078
|
+
//# sourceMappingURL=extractor-cjruDqQ2.cjs.map
|