@clerc/plugin-completions 0.2.0 → 0.3.0

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.cjs CHANGED
@@ -3,133 +3,86 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var clerc = require('clerc');
6
- var pc = require('picocolors');
7
6
 
8
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
+ const gracefulFlag = (n) => n.length === 1 ? `-${n}` : `--${n}`;
9
8
 
10
- var pc__default = /*#__PURE__*/_interopDefaultLegacy(pc);
9
+ const getCompletionValue = (command) => `[CompletionResult]::new('${command.name}', '${command.name}', [CompletionResultType]::ParameterValue, '${command.description}')`;
10
+ const getCompletionFlag = (command) => {
11
+ return Object.entries(command.flags || {}).map(([flagName, flag]) => {
12
+ let gen = [`[CompletionResult]::new('${gracefulFlag(flagName)}', '${flagName}', [CompletionResultType]::ParameterName, '${command.flags[flagName].description || ""}')`];
13
+ if (flag == null ? void 0 : flag.alias) {
14
+ const arrayAlias = clerc.mustArray(flag.alias);
15
+ gen = [
16
+ ...gen,
17
+ ...arrayAlias.map((n) => `[CompletionResult]::new('${gracefulFlag(n)}', '${n}', [CompletionResultType]::ParameterName, '${command.flags[flagName].description || ""}')`)
18
+ ];
19
+ }
20
+ return gen.join("\n ");
21
+ }).join("\n ");
22
+ };
23
+ function getPwshCompletion(ctx) {
24
+ const { cli } = ctx;
25
+ const { _name: name, _commands: commands } = cli;
26
+ return `using namespace System.Management.Automation
27
+ using namespace System.Management.Automation.Language
11
28
 
12
- const mustArray = (a) => Array.isArray(a) ? a : [a];
13
- const gracefulFlagName = (n) => n.length <= 1 ? `-${n}` : `--${n}`;
14
- function generateNameAndAliasFromCommands(commands) {
15
- return Object.fromEntries(
16
- Object.entries(commands).map(([name, command]) => [name, [name, ...command.alias ? mustArray(command.alias) : []].join(", ")])
17
- );
18
- }
19
- function generateFlagNameAndAliasFromCommand(command) {
20
- return Object.fromEntries(
21
- Object.entries(command.flags || {}).map(([name, flag]) => [name, [name, ...mustArray(flag.alias || "")].map(gracefulFlagName).join(", ")])
22
- );
23
- }
24
- function getPadLength(strings) {
25
- const maxLength = Math.max(...strings.map((n) => n.length));
26
- return Math.floor((maxLength + 4) / 4) * 4;
29
+ Register-ArgumentCompleter -Native -CommandName '${name}' -ScriptBlock {
30
+ param($wordToComplete, $commandAst, $cursorPosition)
31
+
32
+ $commandElements = $commandAst.CommandElements
33
+ $command = @(
34
+ '${name}'
35
+ for ($i = 1; $i -lt $commandElements.Count; $i++) {
36
+ $element = $commandElements[$i]
37
+ if ($element -isnot [StringConstantExpressionAst] -or
38
+ $element.StringConstantType -ne [StringConstantType]::BareWord -or
39
+ $element.Value.StartsWith('-') -or
40
+ $element.Value -eq $wordToComplete) {
41
+ break
42
+ }
43
+ $element.Value
44
+ }) -join ';'
45
+
46
+ $completions = @(switch ($command) {
47
+ '${name}' {
48
+ ${Object.entries(commands).map(([_, command]) => getCompletionValue(command)).join("\n ")}
49
+ break
50
+ }
51
+ ${Object.entries(commands).map(([commandName, command]) => `'${name};${commandName}' {
52
+ ${getCompletionFlag(command)}
53
+ break
54
+ }`).join("\n ")}
55
+ })
56
+
57
+ $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
58
+ Sort-Object -Property ListItemText
59
+ }`;
27
60
  }
28
61
 
29
- const newline = () => {
30
- console.log();
31
- };
32
- const defaultOptions = {
33
- command: true,
34
- examples: [],
35
- notes: []
62
+ const completionMap = {
63
+ pwsh: getPwshCompletion
36
64
  };
37
- const helpPlugin = (_options) => clerc.definePlugin({
65
+ const completionsPlugin = (options = {}) => clerc.definePlugin({
38
66
  setup(cli) {
39
- const { command, ...rest } = { ...defaultOptions, ..._options };
67
+ const { command = true } = options;
40
68
  if (command) {
41
- cli = cli.command("help", "Show help").on("help", (ctx) => {
42
- showHelp(cli, ctx, rest);
43
- });
44
- }
45
- cli = cli.inspector((_ctx, next) => {
46
- const ctx = _ctx;
47
- if (ctx.flags.h || ctx.flags.help) {
48
- if (ctx.name === "help") {
49
- showSubcommandHelp(cli, {
50
- ...ctx,
51
- name: "help"
52
- });
53
- return;
69
+ cli = cli.command("completions", "Print shell completions to stdout").on("completions", (ctx) => {
70
+ if (!cli._name) {
71
+ throw new Error("CLI name is not defined!");
54
72
  }
55
- if (ctx.resolved) {
56
- showSubcommandHelp(cli, ctx);
73
+ const shell = String(ctx.parameters[0]);
74
+ if (!shell) {
75
+ throw new Error("Missing shell name");
76
+ }
77
+ if (shell in completionMap) {
78
+ console.log(completionMap[shell](ctx));
57
79
  } else {
58
- showHelp(cli, ctx, rest);
80
+ throw new clerc.NoSuchCommandError(`No such shell: ${shell}`);
59
81
  }
60
- return;
61
- }
62
- next();
63
- });
82
+ });
83
+ }
64
84
  return cli;
65
85
  }
66
86
  });
67
- function showHelp(cli, ctx, { examples, notes }) {
68
- if (ctx.parameters.length > 0) {
69
- showSubcommandHelp(cli, ctx);
70
- return;
71
- }
72
- cli._name && console.log(`${pc__default["default"].green(cli._name)} ${cli._version}`);
73
- if (cli._description) {
74
- console.log(cli._description);
75
- newline();
76
- }
77
- console.log(pc__default["default"].yellow("USAGE:"));
78
- console.log(` ${cli._name} <SUBCOMMAND> [OPTIONS]`);
79
- newline();
80
- console.log(pc__default["default"].yellow("COMMANDS:"));
81
- const commandNameAndAlias = generateNameAndAliasFromCommands(cli._commands);
82
- const commandsPadLength = getPadLength(Object.values(commandNameAndAlias));
83
- for (const [name, nameAndAlias] of Object.entries(commandNameAndAlias)) {
84
- console.log(` ${pc__default["default"].green(nameAndAlias.padEnd(commandsPadLength))}${cli._commands[name].description}`);
85
- }
86
- if (examples.length > 0) {
87
- newline();
88
- console.log(pc__default["default"].yellow("EXAMPLES:"));
89
- const examplesPadLength = getPadLength(examples.map((e) => e[0]));
90
- for (const [exampleCommand, exampleDescription] of examples) {
91
- console.log(` ${exampleCommand.padEnd(examplesPadLength)}${exampleDescription}`);
92
- }
93
- }
94
- if (notes.length > 0) {
95
- newline();
96
- console.log(pc__default["default"].yellow("NOTES:"));
97
- for (const note of notes) {
98
- console.log(` ${note}`);
99
- }
100
- }
101
- }
102
- function showSubcommandHelp(cli, ctx) {
103
- const commandName = String(ctx.name || ctx.parameters[0]);
104
- const commandToShowHelp = clerc.resolveCommand(cli._commands, commandName);
105
- if (!commandToShowHelp) {
106
- throw new clerc.NoSuchCommandsError(`No such command: ${commandName}`);
107
- }
108
- console.log(`${pc__default["default"].green(`${cli._name} ${commandToShowHelp.name}`)} ${cli._version}`);
109
- commandToShowHelp.description && console.log(commandToShowHelp.description);
110
- newline();
111
- console.log(pc__default["default"].yellow("USAGE:"));
112
- console.log(` ${cli._name} ${commandToShowHelp.name} [PARAMETERS] [FLAGS]`);
113
- const parameters = commandToShowHelp.parameters || {};
114
- const parameterKeys = Object.keys(parameters);
115
- if (parameterKeys.length > 0) {
116
- newline();
117
- console.log(pc__default["default"].yellow("PARAMETERS:"));
118
- const parametersPadLength = getPadLength(parameterKeys);
119
- for (const [name, param] of Object.entries(parameters)) {
120
- const resuired = param.required ? pc__default["default"].red(" (required)") : "";
121
- console.log(` ${pc__default["default"].green(name.padEnd(parametersPadLength))}${param.description}${resuired}`);
122
- }
123
- }
124
- const flagNameAndAlias = generateFlagNameAndAliasFromCommand(commandToShowHelp);
125
- if (Object.keys(flagNameAndAlias).length > 0) {
126
- newline();
127
- console.log(pc__default["default"].yellow("FLAGS:"));
128
- const flagsPadLength = getPadLength(Object.values(flagNameAndAlias));
129
- for (const [name, nameAndAlias] of Object.entries(flagNameAndAlias)) {
130
- console.log(` ${pc__default["default"].green(nameAndAlias.padEnd(flagsPadLength))}${commandToShowHelp.flags[name].description}`);
131
- }
132
- }
133
- }
134
87
 
135
- exports.helpPlugin = helpPlugin;
88
+ exports.completionsPlugin = completionsPlugin;
package/dist/index.d.ts CHANGED
@@ -1,20 +1,8 @@
1
1
  import * as clerc from 'clerc';
2
- import { Clerc } from 'clerc';
3
2
 
4
3
  interface Options {
5
- /**
6
- * Register a help command or not.
7
- */
8
4
  command?: boolean;
9
- /**
10
- * [example command, description]
11
- */
12
- examples?: [string, string][];
13
- /**
14
- * notes
15
- */
16
- notes?: string[];
17
5
  }
18
- declare const helpPlugin: (_options?: Options) => clerc.Plugin<Clerc<{}>, Clerc<{}>>;
6
+ declare const completionsPlugin: (options?: Options) => clerc.Plugin<clerc.Clerc<{}>, clerc.Clerc<{}>>;
19
7
 
20
- export { helpPlugin };
8
+ export { Options, completionsPlugin };
package/dist/index.mjs CHANGED
@@ -1,127 +1,84 @@
1
- import { definePlugin, resolveCommand, NoSuchCommandsError } from 'clerc';
2
- import pc from 'picocolors';
1
+ import { mustArray, definePlugin, NoSuchCommandError } from 'clerc';
3
2
 
4
- const mustArray = (a) => Array.isArray(a) ? a : [a];
5
- const gracefulFlagName = (n) => n.length <= 1 ? `-${n}` : `--${n}`;
6
- function generateNameAndAliasFromCommands(commands) {
7
- return Object.fromEntries(
8
- Object.entries(commands).map(([name, command]) => [name, [name, ...command.alias ? mustArray(command.alias) : []].join(", ")])
9
- );
10
- }
11
- function generateFlagNameAndAliasFromCommand(command) {
12
- return Object.fromEntries(
13
- Object.entries(command.flags || {}).map(([name, flag]) => [name, [name, ...mustArray(flag.alias || "")].map(gracefulFlagName).join(", ")])
14
- );
15
- }
16
- function getPadLength(strings) {
17
- const maxLength = Math.max(...strings.map((n) => n.length));
18
- return Math.floor((maxLength + 4) / 4) * 4;
19
- }
3
+ const gracefulFlag = (n) => n.length === 1 ? `-${n}` : `--${n}`;
20
4
 
21
- const newline = () => {
22
- console.log();
5
+ const getCompletionValue = (command) => `[CompletionResult]::new('${command.name}', '${command.name}', [CompletionResultType]::ParameterValue, '${command.description}')`;
6
+ const getCompletionFlag = (command) => {
7
+ return Object.entries(command.flags || {}).map(([flagName, flag]) => {
8
+ let gen = [`[CompletionResult]::new('${gracefulFlag(flagName)}', '${flagName}', [CompletionResultType]::ParameterName, '${command.flags[flagName].description || ""}')`];
9
+ if (flag == null ? void 0 : flag.alias) {
10
+ const arrayAlias = mustArray(flag.alias);
11
+ gen = [
12
+ ...gen,
13
+ ...arrayAlias.map((n) => `[CompletionResult]::new('${gracefulFlag(n)}', '${n}', [CompletionResultType]::ParameterName, '${command.flags[flagName].description || ""}')`)
14
+ ];
15
+ }
16
+ return gen.join("\n ");
17
+ }).join("\n ");
23
18
  };
24
- const defaultOptions = {
25
- command: true,
26
- examples: [],
27
- notes: []
19
+ function getPwshCompletion(ctx) {
20
+ const { cli } = ctx;
21
+ const { _name: name, _commands: commands } = cli;
22
+ return `using namespace System.Management.Automation
23
+ using namespace System.Management.Automation.Language
24
+
25
+ Register-ArgumentCompleter -Native -CommandName '${name}' -ScriptBlock {
26
+ param($wordToComplete, $commandAst, $cursorPosition)
27
+
28
+ $commandElements = $commandAst.CommandElements
29
+ $command = @(
30
+ '${name}'
31
+ for ($i = 1; $i -lt $commandElements.Count; $i++) {
32
+ $element = $commandElements[$i]
33
+ if ($element -isnot [StringConstantExpressionAst] -or
34
+ $element.StringConstantType -ne [StringConstantType]::BareWord -or
35
+ $element.Value.StartsWith('-') -or
36
+ $element.Value -eq $wordToComplete) {
37
+ break
38
+ }
39
+ $element.Value
40
+ }) -join ';'
41
+
42
+ $completions = @(switch ($command) {
43
+ '${name}' {
44
+ ${Object.entries(commands).map(([_, command]) => getCompletionValue(command)).join("\n ")}
45
+ break
46
+ }
47
+ ${Object.entries(commands).map(([commandName, command]) => `'${name};${commandName}' {
48
+ ${getCompletionFlag(command)}
49
+ break
50
+ }`).join("\n ")}
51
+ })
52
+
53
+ $completions.Where{ $_.CompletionText -like "$wordToComplete*" } |
54
+ Sort-Object -Property ListItemText
55
+ }`;
56
+ }
57
+
58
+ const completionMap = {
59
+ pwsh: getPwshCompletion
28
60
  };
29
- const helpPlugin = (_options) => definePlugin({
61
+ const completionsPlugin = (options = {}) => definePlugin({
30
62
  setup(cli) {
31
- const { command, ...rest } = { ...defaultOptions, ..._options };
63
+ const { command = true } = options;
32
64
  if (command) {
33
- cli = cli.command("help", "Show help").on("help", (ctx) => {
34
- showHelp(cli, ctx, rest);
35
- });
36
- }
37
- cli = cli.inspector((_ctx, next) => {
38
- const ctx = _ctx;
39
- if (ctx.flags.h || ctx.flags.help) {
40
- if (ctx.name === "help") {
41
- showSubcommandHelp(cli, {
42
- ...ctx,
43
- name: "help"
44
- });
45
- return;
65
+ cli = cli.command("completions", "Print shell completions to stdout").on("completions", (ctx) => {
66
+ if (!cli._name) {
67
+ throw new Error("CLI name is not defined!");
46
68
  }
47
- if (ctx.resolved) {
48
- showSubcommandHelp(cli, ctx);
69
+ const shell = String(ctx.parameters[0]);
70
+ if (!shell) {
71
+ throw new Error("Missing shell name");
72
+ }
73
+ if (shell in completionMap) {
74
+ console.log(completionMap[shell](ctx));
49
75
  } else {
50
- showHelp(cli, ctx, rest);
76
+ throw new NoSuchCommandError(`No such shell: ${shell}`);
51
77
  }
52
- return;
53
- }
54
- next();
55
- });
78
+ });
79
+ }
56
80
  return cli;
57
81
  }
58
82
  });
59
- function showHelp(cli, ctx, { examples, notes }) {
60
- if (ctx.parameters.length > 0) {
61
- showSubcommandHelp(cli, ctx);
62
- return;
63
- }
64
- cli._name && console.log(`${pc.green(cli._name)} ${cli._version}`);
65
- if (cli._description) {
66
- console.log(cli._description);
67
- newline();
68
- }
69
- console.log(pc.yellow("USAGE:"));
70
- console.log(` ${cli._name} <SUBCOMMAND> [OPTIONS]`);
71
- newline();
72
- console.log(pc.yellow("COMMANDS:"));
73
- const commandNameAndAlias = generateNameAndAliasFromCommands(cli._commands);
74
- const commandsPadLength = getPadLength(Object.values(commandNameAndAlias));
75
- for (const [name, nameAndAlias] of Object.entries(commandNameAndAlias)) {
76
- console.log(` ${pc.green(nameAndAlias.padEnd(commandsPadLength))}${cli._commands[name].description}`);
77
- }
78
- if (examples.length > 0) {
79
- newline();
80
- console.log(pc.yellow("EXAMPLES:"));
81
- const examplesPadLength = getPadLength(examples.map((e) => e[0]));
82
- for (const [exampleCommand, exampleDescription] of examples) {
83
- console.log(` ${exampleCommand.padEnd(examplesPadLength)}${exampleDescription}`);
84
- }
85
- }
86
- if (notes.length > 0) {
87
- newline();
88
- console.log(pc.yellow("NOTES:"));
89
- for (const note of notes) {
90
- console.log(` ${note}`);
91
- }
92
- }
93
- }
94
- function showSubcommandHelp(cli, ctx) {
95
- const commandName = String(ctx.name || ctx.parameters[0]);
96
- const commandToShowHelp = resolveCommand(cli._commands, commandName);
97
- if (!commandToShowHelp) {
98
- throw new NoSuchCommandsError(`No such command: ${commandName}`);
99
- }
100
- console.log(`${pc.green(`${cli._name} ${commandToShowHelp.name}`)} ${cli._version}`);
101
- commandToShowHelp.description && console.log(commandToShowHelp.description);
102
- newline();
103
- console.log(pc.yellow("USAGE:"));
104
- console.log(` ${cli._name} ${commandToShowHelp.name} [PARAMETERS] [FLAGS]`);
105
- const parameters = commandToShowHelp.parameters || {};
106
- const parameterKeys = Object.keys(parameters);
107
- if (parameterKeys.length > 0) {
108
- newline();
109
- console.log(pc.yellow("PARAMETERS:"));
110
- const parametersPadLength = getPadLength(parameterKeys);
111
- for (const [name, param] of Object.entries(parameters)) {
112
- const resuired = param.required ? pc.red(" (required)") : "";
113
- console.log(` ${pc.green(name.padEnd(parametersPadLength))}${param.description}${resuired}`);
114
- }
115
- }
116
- const flagNameAndAlias = generateFlagNameAndAliasFromCommand(commandToShowHelp);
117
- if (Object.keys(flagNameAndAlias).length > 0) {
118
- newline();
119
- console.log(pc.yellow("FLAGS:"));
120
- const flagsPadLength = getPadLength(Object.values(flagNameAndAlias));
121
- for (const [name, nameAndAlias] of Object.entries(flagNameAndAlias)) {
122
- console.log(` ${pc.green(nameAndAlias.padEnd(flagsPadLength))}${commandToShowHelp.flags[name].description}`);
123
- }
124
- }
125
- }
126
83
 
127
- export { helpPlugin };
84
+ export { completionsPlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clerc/plugin-completions",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "author": "Ray <nn_201312@163.com> (https://github.com/so1ve)",
5
5
  "description": "Clerc plugin completions",
6
6
  "keywords": [
@@ -43,7 +43,7 @@
43
43
  "clerc": "*"
44
44
  },
45
45
  "dependencies": {
46
- "clerc": "0.2.0"
46
+ "clerc": "0.3.0"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "puild",