-
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcac.ts
More file actions
105 lines (90 loc) · 3.27 KB
/
Copy pathcac.ts
File metadata and controls
105 lines (90 loc) · 3.27 KB
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
import * as zsh from './zsh';
import * as bash from './bash';
import * as fish from './fish';
import * as powershell from './powershell';
import type { CAC } from 'cac';
import { Completion } from './index';
import { noopHandler, TabFunction } from './shared';
const execPath = process.execPath;
const processArgs = process.argv.slice(1);
const quotedExecPath = quoteIfNeeded(execPath);
const quotedProcessArgs = processArgs.map(quoteIfNeeded);
const quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded);
const x = `${quotedExecPath} ${quotedProcessExecArgs.join(' ')} ${quotedProcessArgs[0]}`;
function quoteIfNeeded(path: string): string {
return path.includes(' ') ? `'${path}'` : path;
}
const tab: TabFunction<CAC> = async (instance, completionConfig) => {
const completion = new Completion();
// Add all commands and their options
for (const cmd of [instance.globalCommand, ...instance.commands]) {
if (cmd.name === 'complete') continue; // Skip completion command
// Get positional args info from command usage
const args = (cmd.rawName.match(/\[.*?\]|<.*?>/g) || []).map((arg) =>
arg.startsWith('[')
); // true if optional (wrapped in [])
const isRootCommand = cmd.name === '@@global@@';
const commandCompletionConfig = isRootCommand
? completionConfig
: completionConfig?.subCommands?.[cmd.name];
// Add command to completion
const commandName = completion.addCommand(
isRootCommand ? '' : cmd.name,
cmd.description || '',
args,
commandCompletionConfig?.handler ?? noopHandler
);
// Add command options
for (const option of [...instance.globalCommand.options, ...cmd.options]) {
// Extract short flag from the name if it exists (e.g., "-c, --config" -> "c")
const shortFlag = option.name.match(/^-([a-zA-Z]), --/)?.[1];
const argName = option.name.replace(/^-[a-zA-Z], --/, '');
completion.addOption(
commandName,
`--${argName}`, // Remove the short flag part if it exists
option.description || '',
commandCompletionConfig?.options?.[argName]?.handler ?? noopHandler,
shortFlag
);
}
}
instance.command('complete [shell]').action(async (shell, extra) => {
switch (shell) {
case 'zsh': {
const script = zsh.generate(instance.name, x);
console.log(script);
break;
}
case 'bash': {
const script = bash.generate(instance.name, x);
console.log(script);
break;
}
case 'fish': {
const script = fish.generate(instance.name, x);
console.log(script);
break;
}
case 'powershell': {
const script = powershell.generate(instance.name, x);
console.log(script);
break;
}
default: {
const args: string[] = extra['--'];
instance.showHelpOnExit = false;
// Parse current command context
instance.unsetMatchedCommand();
instance.parse([execPath, processArgs[0], ...args], {
run: false,
});
// const matchedCommand = instance.matchedCommand?.name || '';
// const potentialCommand = args.join(' ')
// console.log(potentialCommand)
return completion.parse(args);
}
}
});
return completion;
};
export default tab;