@clerc/plugin-completions 0.44.0 → 1.0.0-beta.2
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/index.d.ts +10 -5
- package/dist/index.js +126 -129
- package/package.json +11 -10
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Plugin } from "@clerc/core";
|
|
2
2
|
|
|
3
|
+
//#region src/index.d.ts
|
|
3
4
|
interface CompletionsPluginOptions {
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Whether to register the `completions install` and `completions uninstall` commands.
|
|
7
|
+
* @default true
|
|
8
|
+
*/
|
|
9
|
+
managementCommands?: boolean;
|
|
5
10
|
}
|
|
6
|
-
declare const completionsPlugin: (options?: CompletionsPluginOptions) =>
|
|
7
|
-
|
|
8
|
-
export { CompletionsPluginOptions, completionsPlugin };
|
|
11
|
+
declare const completionsPlugin: (options?: CompletionsPluginOptions) => Plugin;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { CompletionsPluginOptions, completionsPlugin };
|
package/dist/index.js
CHANGED
|
@@ -1,134 +1,131 @@
|
|
|
1
|
-
import { definePlugin } from
|
|
2
|
-
import {
|
|
1
|
+
import { definePlugin, resolveCommand } from "@clerc/core";
|
|
2
|
+
import tabtab, { getShellFromEnv } from "@pnpm/tabtab";
|
|
3
|
+
import { formatFlagName, toArray } from "@clerc/utils";
|
|
3
4
|
|
|
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
|
-
complete -F _${name} -o bashdefault -o default ${name}
|
|
33
|
-
`;
|
|
5
|
+
//#region src/complete.ts
|
|
6
|
+
function splitCommand(cmd) {
|
|
7
|
+
const args = [];
|
|
8
|
+
let current = "";
|
|
9
|
+
let quote = null;
|
|
10
|
+
let escape = false;
|
|
11
|
+
for (const char of cmd) {
|
|
12
|
+
if (escape) {
|
|
13
|
+
current += char;
|
|
14
|
+
escape = false;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (char === "\\") {
|
|
18
|
+
escape = true;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (quote) if (char === quote) quote = null;
|
|
22
|
+
else current += char;
|
|
23
|
+
else if (char === "\"" || char === "'") quote = char;
|
|
24
|
+
else if (/\s/.test(char)) {
|
|
25
|
+
if (current) {
|
|
26
|
+
args.push(current);
|
|
27
|
+
current = "";
|
|
28
|
+
}
|
|
29
|
+
} else current += char;
|
|
30
|
+
}
|
|
31
|
+
if (current) args.push(current);
|
|
32
|
+
return args;
|
|
34
33
|
}
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
const
|
|
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
|
-
$completions = @(switch ($command) {
|
|
78
|
-
'${name}' {
|
|
79
|
-
${Object.entries(commands).map(([_, command]) => getCompletionValue(command)).join("\n ")}
|
|
80
|
-
break
|
|
81
|
-
}
|
|
82
|
-
${Object.entries(commands).map(
|
|
83
|
-
([commandName, command]) => `'${name};${commandName.split(" ").join(";")}' {
|
|
84
|
-
${getCompletionFlag(command)}
|
|
85
|
-
break
|
|
86
|
-
}`
|
|
87
|
-
).join("\n ")}
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
$completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
|
|
91
|
-
Sort-Object -Property ListItemText
|
|
92
|
-
}`;
|
|
34
|
+
async function getCompletion(cli, env) {
|
|
35
|
+
const inputArgv = splitCommand(env.partial.slice(0, env.partial.length - env.lastPartial.length)).slice(1);
|
|
36
|
+
if (inputArgv.includes("--")) return [];
|
|
37
|
+
const [command, commandName] = resolveCommand(cli._commands, inputArgv);
|
|
38
|
+
if (env.lastPartial.startsWith("-")) {
|
|
39
|
+
const flags = command ? {
|
|
40
|
+
...cli._globalFlags,
|
|
41
|
+
...command.flags
|
|
42
|
+
} : cli._globalFlags;
|
|
43
|
+
const candidates$1 = [];
|
|
44
|
+
for (const [name, def] of Object.entries(flags)) {
|
|
45
|
+
candidates$1.push({
|
|
46
|
+
name: formatFlagName(name),
|
|
47
|
+
description: def.description
|
|
48
|
+
});
|
|
49
|
+
if (def.alias) {
|
|
50
|
+
const aliases = toArray(def.alias);
|
|
51
|
+
for (const alias of aliases) candidates$1.push({
|
|
52
|
+
name: formatFlagName(alias),
|
|
53
|
+
description: def.description
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return candidates$1;
|
|
58
|
+
}
|
|
59
|
+
const candidates = [];
|
|
60
|
+
let prefix = "";
|
|
61
|
+
if (commandName) {
|
|
62
|
+
const matchedParts = commandName.split(" ");
|
|
63
|
+
const remainingArgs = inputArgv.slice(matchedParts.length);
|
|
64
|
+
prefix = `${[command.name, ...remainingArgs].join(" ")} `;
|
|
65
|
+
} else prefix = inputArgv.length > 0 ? `${inputArgv.join(" ")} ` : "";
|
|
66
|
+
for (const c of cli._commands.values()) if (c.name.startsWith(prefix)) {
|
|
67
|
+
const nextWord = c.name.slice(prefix.length).split(" ")[0];
|
|
68
|
+
if (nextWord) candidates.push({
|
|
69
|
+
name: nextWord,
|
|
70
|
+
description: c.description
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const uniqueCandidates = /* @__PURE__ */ new Map();
|
|
74
|
+
for (const c of candidates) uniqueCandidates.set(c.name, c);
|
|
75
|
+
return [...uniqueCandidates.values()];
|
|
93
76
|
}
|
|
94
77
|
|
|
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
|
-
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/index.ts
|
|
80
|
+
const completionsPlugin = (options = {}) => definePlugin({ setup: (cli) => {
|
|
81
|
+
const { managementCommands = true } = options;
|
|
82
|
+
if (managementCommands) {
|
|
83
|
+
cli.command("completions install", "Install shell completions", {
|
|
84
|
+
flags: { shell: {
|
|
85
|
+
description: "Shell type",
|
|
86
|
+
type: String
|
|
87
|
+
} },
|
|
88
|
+
parameters: ["[shell]"]
|
|
89
|
+
}).on("completions install", async (ctx) => {
|
|
90
|
+
const shell = ctx.parameters.shell ?? ctx.flags.shell;
|
|
91
|
+
if (!shell) throw new Error("Please specify the shell type via the --shell flag or the [shell] parameter.");
|
|
92
|
+
if (!tabtab.SUPPORTED_SHELLS.includes(shell)) throw new Error(`Unsupported shell: ${shell}. Supported shells are: ${tabtab.SUPPORTED_SHELLS.join(", ")}.`);
|
|
93
|
+
await tabtab.install({
|
|
94
|
+
name: cli._name,
|
|
95
|
+
completer: cli._name,
|
|
96
|
+
shell
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
cli.command("completions uninstall", "Uninstall shell completions").on("completions uninstall", async () => {
|
|
100
|
+
await tabtab.uninstall({ name: cli._name });
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
cli.command("completions", "Generate completions script", {
|
|
104
|
+
flags: { shell: {
|
|
105
|
+
description: "Shell type",
|
|
106
|
+
type: String
|
|
107
|
+
} },
|
|
108
|
+
parameters: ["[shell]"]
|
|
109
|
+
}).on("completions", async (ctx) => {
|
|
110
|
+
const shell = ctx.parameters.shell ?? ctx.flags.shell;
|
|
111
|
+
if (!shell) throw new Error("Please specify the shell type via the --shell flag or the [shell] parameter.");
|
|
112
|
+
if (!tabtab.SUPPORTED_SHELLS.includes(shell)) throw new Error(`Unsupported shell: ${shell}. Supported shells are: ${tabtab.SUPPORTED_SHELLS.join(", ")}.`);
|
|
113
|
+
const script = await tabtab.getCompletionScript({
|
|
114
|
+
name: cli._name,
|
|
115
|
+
completer: cli._name,
|
|
116
|
+
shell
|
|
117
|
+
});
|
|
118
|
+
console.log(script);
|
|
119
|
+
});
|
|
120
|
+
cli.command("completion-server", "Handle completions", { help: { showInHelp: false } }).on("completion-server", async () => {
|
|
121
|
+
const env = tabtab.parseEnv(process.env);
|
|
122
|
+
if (!env.complete) return;
|
|
123
|
+
const shell = getShellFromEnv(process.env);
|
|
124
|
+
const filtered = (await getCompletion(cli, env)).filter((c) => c.name.startsWith(env.lastPartial));
|
|
125
|
+
tabtab.log(filtered, shell);
|
|
126
|
+
});
|
|
127
|
+
return cli;
|
|
128
|
+
} });
|
|
133
129
|
|
|
134
|
-
|
|
130
|
+
//#endregion
|
|
131
|
+
export { completionsPlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clerc/plugin-completions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
4
|
"author": "Ray <i@mk1.io> (https://github.com/so1ve)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Clerc plugin completions",
|
|
@@ -25,13 +25,10 @@
|
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"sideEffects": false,
|
|
27
27
|
"exports": {
|
|
28
|
-
".":
|
|
29
|
-
"types": "./dist/index.d.ts",
|
|
30
|
-
"import": "./dist/index.js"
|
|
31
|
-
}
|
|
28
|
+
".": "./dist/index.js"
|
|
32
29
|
},
|
|
33
|
-
"main": "dist/index.js",
|
|
34
|
-
"module": "dist/index.js",
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"module": "./dist/index.js",
|
|
35
32
|
"types": "dist/index.d.ts",
|
|
36
33
|
"typesVersions": {
|
|
37
34
|
"*": {
|
|
@@ -48,13 +45,17 @@
|
|
|
48
45
|
"access": "public"
|
|
49
46
|
},
|
|
50
47
|
"dependencies": {
|
|
51
|
-
"@
|
|
48
|
+
"@pnpm/tabtab": "^0.5.4",
|
|
49
|
+
"@clerc/utils": "1.0.0-beta.2"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@clerc/core": "1.0.0-beta.2"
|
|
52
53
|
},
|
|
53
54
|
"peerDependencies": {
|
|
54
55
|
"@clerc/core": "*"
|
|
55
56
|
},
|
|
56
57
|
"scripts": {
|
|
57
|
-
"build": "
|
|
58
|
-
"watch": "
|
|
58
|
+
"build": "tsdown",
|
|
59
|
+
"watch": "tsdown --watch"
|
|
59
60
|
}
|
|
60
61
|
}
|