@jals1212/pi-spaces-cli 0.6.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -6,6 +6,43 @@ commands and options and a patch version fixes.
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.6.2
10
+
11
+ ### Fixed
12
+
13
+ - `pi-space --help <TAB>` (and `-h`) offers the commands with their summary,
14
+ `completion` included, so the help of a command is one Tab away.
15
+ - `--every` is completed in its own `target` group instead of among the space
16
+ names, since it is not a space.
17
+ - The completion text of the first `--help` says it also takes a command:
18
+ `print the help, or a command's: --help <command>`.
19
+
20
+ ## 0.6.1
21
+
22
+ ### Added
23
+
24
+ - `pi-space <command> --help` (also `-h`, and `pi-space --help <command>`)
25
+ prints the help of one command: what it does, its arguments and options, the
26
+ call options that apply to it, and examples. `--help` anywhere after the
27
+ command word counts, so `pi-space remove work --help` prints the help and
28
+ removes nothing. After a space name it still belongs to Pi:
29
+ `pi-space work --help` starts Pi with `--help`. An unknown command exits with
30
+ status 2. It reads no config file and starts nothing.
31
+
32
+ ### Changed
33
+
34
+ - Completion groups its candidates (commands, spaces, profiles, options) and
35
+ describes them: each command shows a one-line summary, `base` and the spaces
36
+ are told apart, a profile shows its command, and `remove` offers `--yes` and
37
+ `--no-backup`. `--help` is offered, as the options are, once the word starts
38
+ with `-`. The hidden `__complete` prints `<group>\t<value>\t<description>`
39
+ lines instead of bare words.
40
+ - `pi-space -<TAB>` offers the call options not typed yet (`--profile`,
41
+ `--dir`, `--config`, `--command`, `--setup`), and `--help` and `--version`
42
+ when nothing comes before.
43
+ - Completion no longer offers `completion` among the commands; it still works
44
+ typed in full, and `pi-space completion <TAB>` still offers `zsh`.
45
+
9
46
  ## 0.6.0
10
47
 
11
48
  ### Added
package/README.md CHANGED
@@ -28,9 +28,12 @@ The command words are reserved: a space can never be named `list`, `new`, `remov
28
28
  | `pi-space install <name\|--every> <source> [pi install options...]` | Runs Pi's `install` in a space. The source is required. |
29
29
  | `pi-space uninstall <name\|--every> <source> [pi options...]` | Runs Pi's `uninstall` (its alias of `remove`) in a space. The source is required. |
30
30
  | `pi-space completion zsh` | Prints the zsh completion script (see [Shell completion](#shell-completion)). Any other shell, or none, exits with status 2. |
31
+ | `pi-space <command> --help` | Shows the help of one command: what it does, its arguments and options, the call options that apply, and examples (`pi-space --help <command>` and `-h` work too). |
31
32
  | `pi-space --help` | Shows the usage. |
32
33
  | `pi-space --version` | Prints the version. |
33
34
 
35
+ `--help` (or `-h`) anywhere after a command word shows that command's help and does nothing else: `pi-space remove work --help` removes nothing, and it reads no config file. After a space name every argument belongs to Pi, so `pi-space work --help` starts Pi with `--help`. An unknown command (`pi-space --help ghost`) exits with status 2 and lists the commands.
36
+
34
37
  `--new` and `--remove`, the options of 0.3, were replaced by `new` and `remove`; they exit with status 2 and name the command to use.
35
38
 
36
39
  ### Packages in a space, or in every space
@@ -160,7 +163,7 @@ alias my-space='pi-space --profile my' # any POSIX shell
160
163
 
161
164
  ## Shell completion
162
165
 
163
- `pi-space` completes its commands, the profile names after `--profile`, files after `--config` and `--dir`, and the spaces. For zsh, add to `~/.zshrc` (after `compinit`):
166
+ `pi-space` completes its commands (each with a one-line summary), the profile names after `--profile`, files after `--config` and `--dir`, and the spaces. For zsh, add to `~/.zshrc` (after `compinit`):
164
167
 
165
168
  ```sh
166
169
  source <(pi-space completion zsh)
@@ -170,14 +173,18 @@ It asks the command itself for the candidates each time, through the hidden `pi-
170
173
 
171
174
  | After | Candidates |
172
175
  | --- | --- |
173
- | `pi-space` (and the call options) | the commands, `base` and the spaces |
174
- | `--profile` | the profile names, `pi` included |
176
+ | `pi-space` (and the call options) | the commands, then `base` and the spaces (`completion` is not offered, but works typed in full) |
177
+ | `--profile` | the profile names, `pi` included, each with its command |
175
178
  | `--config`, `--dir` | files (the shell's own completion) |
176
179
  | `remove`, `rename` | the spaces |
177
180
  | `setup` | the spaces and `--every` |
178
181
  | `list`, `update`, `install`, `uninstall` | `base`, the spaces and `--every` |
179
182
  | `completion` | `zsh` |
180
183
 
184
+ In first place the call options not typed yet come too, and `--help` and `--version` when nothing comes before. After a command word the options come too: `--help` for every command, and `--yes` and `--no-backup` after `remove`. zsh shows them once the word starts with `-`, so `pi-space new <TAB>` never fills in a lone `--help`.
185
+
186
+ The candidates come in groups, each with a description, and zsh lists each group apart: commands, spaces (`base` is "the home Pi starts with"), profiles, shells and options. The hidden `pi-space __complete` prints one `<group>\t<value>\t<description>` line per candidate (or the single line `__files__` when the shell should complete a file), so a script for another shell can use it.
187
+
181
188
  Completion also works through an abbreviation or alias like the one above: they expand first, so `my-space <TAB>` completes what `pi-space --profile my <TAB>` would. A config file that is wrong, or a profile that does not exist, just gives no candidates; completion never prints an error.
182
189
 
183
190
  ## Preparing a new space
package/dist/cli.js CHANGED
@@ -51,6 +51,7 @@ export const USAGE = `Usage: pi-space [--command <cmd>] [--dir <path>] [--setup
51
51
  pi-space install <name|--every> <source> install a package in a space (more words go to Pi)
52
52
  pi-space uninstall <name|--every> <source> remove a package from a space (more words go to Pi)
53
53
  pi-space completion zsh print the zsh completion script (source <(pi-space completion zsh))
54
+ pi-space <command> --help the help of one command
54
55
  pi-space --help print this help
55
56
  pi-space --version print the version
56
57
  --every takes the place of the name: base first (not for setup), then every space in turn; a failure does not stop the rest, and the exit status is 1 if any failed.
@@ -90,6 +91,7 @@ const REPLACED = {
90
91
 
91
92
 
92
93
 
94
+
93
95
 
94
96
 
95
97
 
@@ -109,6 +111,161 @@ const REPLACED = {
109
111
 
110
112
  const CALL_OPTIONS = { "--command": "command", "--dir": "dir", "--setup": "setup", "--profile": "profile", "--config": "config" } ;
111
113
 
114
+ function isHelpFlag(word ) {
115
+ return word === "--help" || word === "-h";
116
+ }
117
+
118
+ /** What each call option is, for the help of the commands it applies to. */
119
+ const CALL_HELP = {
120
+ command: ["--command <cmd>", 'the program to run instead of $PI_SPACES_COMMAND (default: pi), e.g. "my-launcher --"'],
121
+ dir: ["--dir <path>", "the spaces folder instead of $PI_SPACES_DIR; the Pi it starts gets it too"],
122
+ setup: ["--setup <cmd>", "the setup command instead of $PI_SPACES_SETUP; {home} and {name} become the space's folder and name"],
123
+ profile: ["--profile <name>", 'the profile of the config file instead of its "default"'],
124
+ config: ["--config <path>", "the config file instead of $PI_SPACES_CONFIG (default: ~/.pi-spaces/config.json)"],
125
+ };
126
+
127
+ /** The help of one command; the summary is the one line completion shows next to it. */
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+ const PI_ARGS = ["[pi args...]", "more words go to Pi, e.g. --extensions, --all or a source"];
143
+ const NAME_OR_EVERY = [
144
+ ["<name>", "base or a space"],
145
+ ["--every", "base first, then every space in turn; a failure does not stop the rest, and the exit status is 1 if any failed"],
146
+ ];
147
+
148
+ /** The commands, in the order completion lists them. They are reserved words: the core never lets a space be named one. */
149
+ const COMMANDS = {
150
+ list: {
151
+ summary: "list the spaces, or the packages of one",
152
+ usage: "list [<name|--every>]",
153
+ about: ["With a name it runs Pi's list in that space; with --every, in base and then every space."],
154
+ args: NAME_OR_EVERY,
155
+ options: [],
156
+ calls: ["command", "dir", "profile", "config"],
157
+ examples: ["pi-space list", "pi-space list work", "pi-space list --every"],
158
+ },
159
+ new: {
160
+ summary: "create a space",
161
+ usage: "new <name>",
162
+ about: ["Its settings.json declares the extension. It runs the setup command in it when there is one, and does not start Pi."],
163
+ args: [["<name>", "the name of the new space"]],
164
+ options: [],
165
+ calls: ["dir", "setup", "profile", "config"],
166
+ examples: ["pi-space new work", "pi-space --setup 'my-launcher --home {home} setup' new work"],
167
+ },
168
+ setup: {
169
+ summary: "run the setup command in a space",
170
+ usage: "setup <name|--every>",
171
+ about: ["It needs a setup command: --setup or $PI_SPACES_SETUP. It never runs in base."],
172
+ args: [
173
+ ["<name>", "a space"],
174
+ ["--every", "every space, never base; a failure does not stop the rest, and the exit status is 1 if any failed"],
175
+ ],
176
+ options: [],
177
+ calls: ["dir", "setup", "profile", "config"],
178
+ examples: ["pi-space setup work", "pi-space setup --every", "pi-space --setup 'my-launcher --home {home} setup' setup --every"],
179
+ },
180
+ rename: {
181
+ summary: "rename a space",
182
+ usage: "rename <old> <new>",
183
+ about: ["It refuses what remove refuses: base, the space you are in, and a space that holds the base home."],
184
+ args: [
185
+ ["<old>", "the space to rename"],
186
+ ["<new>", "its new name"],
187
+ ],
188
+ options: [],
189
+ calls: ["dir", "profile", "config"],
190
+ examples: ["pi-space rename work client"],
191
+ },
192
+ remove: {
193
+ summary: "delete a space, keeping a backup",
194
+ usage: "remove <name> [--yes|-y] [--no-backup]",
195
+ about: ["It deletes the space and everything in it, after asking, and keeps a backup in .backups unless told not to."],
196
+ args: [["<name>", "the space to delete"]],
197
+ options: [
198
+ { flag: "--yes", alias: "-y", text: "do not ask; keep a backup" },
199
+ { flag: "--no-backup", text: "delete without a backup" },
200
+ ],
201
+ calls: ["dir", "profile", "config"],
202
+ examples: ["pi-space remove work", "pi-space remove work --yes", "pi-space remove work --yes --no-backup"],
203
+ },
204
+ update: {
205
+ summary: "update the packages of a space",
206
+ usage: "update <name|--every> [pi args...]",
207
+ about: ["It runs Pi's update in a space, or in base and then every space."],
208
+ args: [...NAME_OR_EVERY, PI_ARGS],
209
+ options: [],
210
+ calls: ["command", "dir", "profile", "config"],
211
+ examples: ["pi-space update work", "pi-space update base --extensions", "pi-space --command 'my-launcher --' update --every"],
212
+ },
213
+ install: {
214
+ summary: "install a package in a space",
215
+ usage: "install <name|--every> <source> [pi args...]",
216
+ about: ["It runs Pi's install in a space, or in base and then every space."],
217
+ args: [...NAME_OR_EVERY, ["<source>", "the package to install, e.g. npm:some-package"], PI_ARGS],
218
+ options: [],
219
+ calls: ["command", "dir", "profile", "config"],
220
+ examples: ["pi-space install work npm:some-package", "pi-space install --every npm:some-package"],
221
+ },
222
+ uninstall: {
223
+ summary: "remove a package from a space",
224
+ usage: "uninstall <name|--every> <source> [pi args...]",
225
+ about: ["It runs Pi's uninstall (its alias of remove) in a space, or in base and then every space."],
226
+ args: [...NAME_OR_EVERY, ["<source>", "the package to remove, e.g. npm:some-package"], PI_ARGS],
227
+ options: [],
228
+ calls: ["command", "dir", "profile", "config"],
229
+ examples: ["pi-space uninstall work npm:some-package", "pi-space uninstall --every npm:some-package"],
230
+ },
231
+ completion: {
232
+ summary: "print the shell completion script",
233
+ usage: "completion <shell>",
234
+ about: ["Supported shells: zsh."],
235
+ args: [["<shell>", "zsh"]],
236
+ options: [],
237
+ calls: [],
238
+ examples: ["pi-space completion zsh", "source <(pi-space completion zsh)"],
239
+ },
240
+ };
241
+
242
+ /** --help after a command; GENERAL_OPTIONS has the --help that comes first. */
243
+ const HELP_OPTION = { flag: "--help", alias: "-h", text: "the help of this command" };
244
+
245
+ /** The options that stand alone in first place, as completion describes them. */
246
+ const GENERAL_OPTIONS = [
247
+ ["--help", "print the help, or a command's: --help <command>"],
248
+ ["--version", "print the version"],
249
+ ];
250
+
251
+ /** The help of one command: usage, what it does, arguments, options, the call options that apply, and examples. */
252
+ function commandHelp(name ) {
253
+ const help = COMMANDS[name];
254
+ const options = [...help.options, HELP_OPTION].map((option) => [option.alias ? `${option.flag}, ${option.alias}` : option.flag, option.text]);
255
+ const calls = help.calls.map((call) => CALL_HELP[call]);
256
+ const width = Math.max(...[...help.args, ...options, ...calls].map(([label]) => label.length)) + 2;
257
+ const rows = (list ) => list.map(([label, text]) => ` ${label.padEnd(width)}${text}`);
258
+ const sections = [
259
+ [`Usage: pi-space ${help.usage}`],
260
+ [`${help.summary[0].toUpperCase()}${help.summary.slice(1)}.`, ...help.about],
261
+ ["Arguments:", ...rows(help.args)],
262
+ ["Options:", ...rows(options)],
263
+ ...(calls.length > 0 ? [["Call options (before the command, for this call only):", ...rows(calls)]] : []),
264
+ ["Examples:", ...help.examples.map((example) => ` ${example}`)],
265
+ ];
266
+ return `${sections.map((section) => section.join("\n")).join("\n\n")}\n`;
267
+ }
268
+
112
269
  /**
113
270
  * The call options (--command, --dir, --setup, --profile, --config) come first; after a space name every argument belongs to Pi.
114
271
  * The commands (list, new, setup, remove, rename, update, install, uninstall, completion) are reserved words, so they
@@ -134,10 +291,12 @@ export function parseCli(args ) {
134
291
  function parseCommand(args ) {
135
292
  const [first, ...rest] = args;
136
293
  if (first === undefined) return { kind: "picker" };
137
- if (first === "--help" || first === "-h") return { kind: "help" };
294
+ if (isHelpFlag(first)) return parseHelp(rest);
138
295
  if (first === "--version" || first === "-v") return { kind: "version" };
139
296
  if (Object.hasOwn(REPLACED, first)) return { kind: "replaced", option: first, instead: REPLACED[first ] };
140
297
  if (first.startsWith("-")) return { kind: "unknown-option", option: first };
298
+ // --help after a command word is that command's help; after a space name it belongs to Pi (the launch below).
299
+ if (Object.hasOwn(COMMANDS, first) && rest.some(isHelpFlag)) return { kind: "command-help", command: first };
141
300
  if (first === "list" && rest.length === 0) return { kind: "list" };
142
301
  if (PACKAGE_VERBS.includes(first)) return parsePackages(first , rest);
143
302
  if (first === "new") return rest.length === 1 ? { kind: "new", name: rest[0] } : { kind: "usage" };
@@ -156,6 +315,13 @@ function parseCommand(args ) {
156
315
  return { kind: "launch", name: first, args: rest };
157
316
  }
158
317
 
318
+ /** `--help` alone is the general help; `--help <command>` is that command's. */
319
+ function parseHelp(rest ) {
320
+ if (rest.length === 0) return { kind: "help" };
321
+ if (rest.length === 1) return { kind: "command-help", command: rest[0] };
322
+ return { kind: "usage" };
323
+ }
324
+
159
325
  /** `setup <name>` or `setup --every`: exactly one argument. */
160
326
  function parseSetup(rest ) {
161
327
  if (rest.length !== 1) return { kind: "usage" };
@@ -386,6 +552,13 @@ export async function main(argv , io ) {
386
552
  case "help":
387
553
  io.stdout.write(USAGE);
388
554
  return io.exit(0);
555
+ case "command-help":
556
+ if (Object.hasOwn(COMMANDS, command.command)) {
557
+ io.stdout.write(commandHelp(command.command));
558
+ return io.exit(0);
559
+ }
560
+ io.stderr.write(`pi-space: No help for "${command.command}"; commands: ${Object.keys(COMMANDS).join(", ")}.\n`);
561
+ return io.exit(2);
389
562
  case "version":
390
563
  io.stdout.write(`${VERSION}\n`);
391
564
  return io.exit(0);
@@ -458,28 +631,59 @@ function printCompletion(shell , io ) {
458
631
  const FILES = "__files__";
459
632
 
460
633
  /**
461
- * The zsh script: it asks `pi-space __complete <the words before the cursor>` for candidates, one per line,
462
- * and falls back to the shell's file completion on the marker. An abbreviation or alias has already expanded
463
- * by then, so `my-space <TAB>` completes the words of what it stands for.
634
+ * The zsh script: it asks `pi-space __complete <the words before the cursor>` for candidates, one per line as
635
+ * `<group>\t<value>\t<description>`, and hands each group to _describe (a ":" in a value is escaped for it).
636
+ * The `__files__` marker falls back to the shell's file completion. An abbreviation or alias has already
637
+ * expanded by then, so `my-space <TAB>` completes the words of what it stands for.
638
+ * The options show only for a word that starts with "-", so `pi-space new <TAB>` never inserts a lone --help.
464
639
  */
465
640
  const ZSH_COMPLETION = [
466
641
  "#compdef pi-space",
467
642
  "# zsh completion for pi-space. Load it from .zshrc with: source <(pi-space completion zsh)",
468
643
  "_pi_space() {",
469
- " local -a lines",
644
+ " local -a lines cmds spaces targets profiles shells opts",
645
+ " local line group value text ret=1",
470
646
  ' lines=("${(@f)$(command "${words[1]}" __complete "${(@)words[2,CURRENT-1]}" 2>/dev/null)}")',
471
647
  ` if [[ "\${lines[1]}" == ${FILES} ]]; then`,
472
648
  " _files",
473
649
  " return",
474
650
  " fi",
475
- ' lines=("${(@)lines:#}")',
476
- " compadd -a lines",
651
+ ' for line in "${(@)lines}"; do',
652
+ ' [[ -n "$line" ]] || continue',
653
+ " group=${line%%$'\\t'*}",
654
+ " line=${line#*$'\\t'}",
655
+ " value=${line%%$'\\t'*}",
656
+ " text=${line#*$'\\t'}",
657
+ " [[ \"$text\" == \"$line\" ]] && text=",
658
+ " value=${value//:/\\\\:}",
659
+ ' case "$group" in',
660
+ ' command) cmds+=("$value:$text") ;;',
661
+ ' space) spaces+=("$value:$text") ;;',
662
+ ' target) targets+=("$value:$text") ;;',
663
+ ' profile) profiles+=("$value:$text") ;;',
664
+ ' shell) shells+=("$value:$text") ;;',
665
+ ' option) [[ "$PREFIX" == -* ]] && opts+=("$value:$text") ;;',
666
+ " esac",
667
+ " done",
668
+ " (( $#cmds )) && _describe -t commands 'command' cmds && ret=0",
669
+ " (( $#spaces )) && _describe -t spaces 'space' spaces && ret=0",
670
+ " (( $#targets )) && _describe -t targets 'target' targets && ret=0",
671
+ " (( $#profiles )) && _describe -t profiles 'profile' profiles && ret=0",
672
+ " (( $#shells )) && _describe -t shells 'shell' shells && ret=0",
673
+ " (( $#opts )) && _describe -t options 'option' opts && ret=0",
674
+ " return ret",
477
675
  "}",
478
676
  "compdef _pi_space pi-space",
479
677
  "",
480
678
  ].join("\n");
481
679
 
482
- const COMMAND_WORDS = ["list", "new", "setup", "rename", "remove", "update", "install", "uninstall", "completion"];
680
+ /** The groups of a `__complete` line; `target` is --every, which stands in for a space name. */
681
+
682
+
683
+ /** One `__complete` line; the description never holds a tab or a newline. */
684
+ function candidate(group , value , text ) {
685
+ return `${group}\t${value}\t${text.replace(/\s+/g, " ")}`;
686
+ }
483
687
 
484
688
  /**
485
689
  * The hidden `__complete <words before the cursor>`: one candidate per line, honoring the call options already
@@ -496,6 +700,49 @@ function complete(words , io ) {
496
700
  return io.exit(0);
497
701
  }
498
702
 
703
+ /** The commands with their summary; in first place `completion` is left out (it still works typed in full), after --help it is not. */
704
+ function commandCandidates(withCompletion ) {
705
+ return Object.entries(COMMANDS)
706
+ .filter(([name]) => withCompletion || name !== "completion")
707
+ .map(([name, help]) => candidate("command", name, help.summary));
708
+ }
709
+
710
+ /** The call options not typed yet, then --help and --version when nothing was typed before. */
711
+ function firstOptions(call , alone ) {
712
+ const calls = Object.entries(CALL_OPTIONS)
713
+ .filter(([, key]) => call[key] === undefined)
714
+ .map(([flag, key]) => candidate("option", flag, CALL_HELP[key][1]));
715
+ const general = alone ? GENERAL_OPTIONS.map(([flag, text]) => candidate("option", flag, text)) : [];
716
+ return [...calls, ...general];
717
+ }
718
+
719
+ /** `base`, if asked, then the spaces. */
720
+ function spaceCandidates(spaces , withBase ) {
721
+ return [...(withBase ? [candidate("space", BASE, "the home Pi starts with")] : []), ...spaces.map((name) => candidate("space", name, "space"))];
722
+ }
723
+
724
+ /** What follows a command word: its target, its own options and --help. */
725
+ function commandArguments(command , spaces ) {
726
+ const every = (text ) => candidate("target", "--every", text);
727
+ const options = [...COMMANDS[command].options, HELP_OPTION].map((option) => candidate("option", option.flag, option.text));
728
+ switch (command) {
729
+ case "remove":
730
+ case "rename":
731
+ return [...spaceCandidates(spaces, false), ...options];
732
+ case "setup":
733
+ return [...spaceCandidates(spaces, false), every("every space"), ...options];
734
+ case "list":
735
+ case "update":
736
+ case "install":
737
+ case "uninstall":
738
+ return [...spaceCandidates(spaces, true), every("every space (base first)"), ...options];
739
+ case "completion":
740
+ return [...SHELLS.map((shell) => candidate("shell", shell, `the ${shell} completion script`)), ...options];
741
+ default:
742
+ return options;
743
+ }
744
+ }
745
+
499
746
  function candidates(words , io ) {
500
747
  const call = {};
501
748
  let index = 0;
@@ -509,33 +756,32 @@ function candidates(words , io ) {
509
756
  const { dir } = resolveSettings(call, io);
510
757
  const rest = words.slice(index);
511
758
  const spaces = listSpaces(dir);
512
- if (rest.length === 0) return [...COMMAND_WORDS, BASE, ...spaces];
759
+ if (rest.length === 0) return [...commandCandidates(false), ...spaceCandidates(spaces, true), ...firstOptions(call, index === 0)];
513
760
  if (rest.length > 1) return [];
514
- switch (rest[0]) {
515
- case "remove":
516
- case "rename":
517
- return spaces;
518
- case "setup":
519
- return [...spaces, "--every"];
520
- case "list":
521
- case "update":
522
- case "install":
523
- case "uninstall":
524
- return [BASE, ...spaces, "--every"];
525
- case "completion":
526
- return SHELLS;
527
- default:
528
- return [];
529
- }
761
+ if (isHelpFlag(rest[0])) return commandCandidates(true);
762
+ if (!Object.hasOwn(COMMANDS, rest[0])) return [];
763
+ return commandArguments(rest[0], spaces);
530
764
  }
531
765
 
532
- /** The candidates for the value of a call option: profile names, the shell's files for a path, nothing for a command. */
766
+ /** The candidates for the value of a call option: profile names with their command, the shell's files for a path, nothing for a command. */
533
767
  function optionValues(option , call , io ) {
534
- if (option === "--profile") return profileNames(resolveSettings(call, io).config);
768
+ if (option === "--profile") {
769
+ const { config } = resolveSettings(call, io);
770
+ return profileNames(config).map((name) => candidate("profile", name, profileText(config, name, io)));
771
+ }
535
772
  if (option === "--config" || option === "--dir") return [FILES];
536
773
  return [];
537
774
  }
538
775
 
776
+ /** A profile's command, else "profile". */
777
+ function profileText(config , name , io ) {
778
+ try {
779
+ return profileByName(config, name, io.env, io.home).command || "profile";
780
+ } catch {
781
+ return "profile";
782
+ }
783
+ }
784
+
539
785
  /** Prints the reason and returns false when the setup command has an unclosed quote. */
540
786
  function checkSetup(io , source ) {
541
787
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jals1212/pi-spaces-cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "The pi-space command: pick a space and start Pi in it. Companion to the Pi extension @jals1212/pi-spaces.",
5
5
  "license": "MIT",
6
6
  "author": "jals1212",