Skip to content

Commit 571e471

Browse files
committed
feat(cli): add completion install command
1 parent 7f7a5e7 commit 571e471

7 files changed

Lines changed: 303 additions & 19 deletions

File tree

README.en.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ coder-studio auth ip list
7979
coder-studio help start
8080
coder-studio help completion
8181
eval "$(coder-studio completion bash)"
82+
coder-studio completion install bash
8283
```
8384

8485
For the detailed command reference, see `docs/development/cli.en.md`.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ coder-studio auth ip list
7878
coder-studio help start
7979
coder-studio help completion
8080
eval "$(coder-studio completion bash)"
81+
coder-studio completion install bash
8182
```
8283

8384
详细命令说明见:`docs/development/cli.md`

docs/development/cli.en.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Shell completion:
8080
coder-studio completion bash
8181
coder-studio completion zsh
8282
coder-studio completion fish
83+
coder-studio completion install bash
8384
```
8485

8586
Version:
@@ -118,6 +119,14 @@ Additional flags on specific commands:
118119

119120
The CLI can print completion scripts for `bash`, `zsh`, and `fish`. The command only writes the script to stdout.
120121

122+
Print scripts directly:
123+
124+
```bash
125+
coder-studio completion bash
126+
coder-studio completion zsh
127+
coder-studio completion fish
128+
```
129+
121130
Load it for the current shell session:
122131

123132
```bash
@@ -126,7 +135,21 @@ source <(coder-studio completion zsh)
126135
coder-studio completion fish | source
127136
```
128137

129-
Persistent installation examples:
138+
Install into your local shell setup automatically:
139+
140+
```bash
141+
coder-studio completion install bash
142+
coder-studio completion install zsh
143+
coder-studio completion install fish
144+
```
145+
146+
Install behavior:
147+
148+
- `bash`: writes `~/.coder-studio/completions/coder-studio.bash` and adds a managed `source` block to `~/.bashrc`
149+
- `zsh`: writes `~/.coder-studio/completions/coder-studio.zsh` and adds a managed `source` block to `~/.zshrc`
150+
- `fish`: writes `${XDG_CONFIG_HOME:-~/.config}/fish/completions/coder-studio.fish` without editing a profile
151+
152+
Manual persistent installation examples:
130153

131154
```bash
132155
coder-studio completion bash >> ~/.bashrc
@@ -136,7 +159,8 @@ coder-studio completion fish > ~/.config/fish/completions/coder-studio.fish
136159

137160
Notes:
138161

139-
- `completion` does not support `--json`
162+
- `coder-studio completion install <shell> --json` returns structured install output
163+
- `coder-studio completion <shell>` does not support `--json`
140164
- `coder-studio help completion` shows command usage
141165

142166
## Exit Codes

docs/development/cli.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Shell Completion:
8080
coder-studio completion bash
8181
coder-studio completion zsh
8282
coder-studio completion fish
83+
coder-studio completion install bash
8384
```
8485

8586
版本信息:
@@ -118,6 +119,14 @@ coder-studio help completion
118119

119120
CLI 可以输出 `bash``zsh``fish` 的补全脚本,命令本身只负责把脚本打印到标准输出。
120121

122+
直接打印脚本:
123+
124+
```bash
125+
coder-studio completion bash
126+
coder-studio completion zsh
127+
coder-studio completion fish
128+
```
129+
121130
即时加载:
122131

123132
```bash
@@ -126,7 +135,21 @@ source <(coder-studio completion zsh)
126135
coder-studio completion fish | source
127136
```
128137

129-
持久化安装示例:
138+
自动安装到本地 shell 配置:
139+
140+
```bash
141+
coder-studio completion install bash
142+
coder-studio completion install zsh
143+
coder-studio completion install fish
144+
```
145+
146+
安装行为:
147+
148+
- `bash`:写入 `~/.coder-studio/completions/coder-studio.bash`,并在 `~/.bashrc` 注入受管的 `source` 片段
149+
- `zsh`:写入 `~/.coder-studio/completions/coder-studio.zsh`,并在 `~/.zshrc` 注入受管的 `source` 片段
150+
- `fish`:写入 `${XDG_CONFIG_HOME:-~/.config}/fish/completions/coder-studio.fish`,不修改 profile
151+
152+
手动持久化安装示例:
130153

131154
```bash
132155
coder-studio completion bash >> ~/.bashrc
@@ -136,7 +159,8 @@ coder-studio completion fish > ~/.config/fish/completions/coder-studio.fish
136159

137160
说明:
138161

139-
- `completion` 不支持 `--json`
162+
- `coder-studio completion install <shell> --json` 会返回安装结果
163+
- `coder-studio completion <shell>` 不支持 `--json`
140164
- `coder-studio help completion` 可查看命令说明
141165

142166
## 退出码

packages/coder-studio/lib/cli.mjs

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import fs from 'node:fs/promises';
2-
import { generateCompletionScript, SUPPORTED_COMPLETION_SHELLS } from './completion.mjs';
2+
import { generateCompletionScript, installCompletionScript, SUPPORTED_COMPLETION_SHELLS } from './completion.mjs';
33
import { resolveLogPath } from './config.mjs';
44
import {
55
buildConfigPathsReport,
@@ -108,6 +108,7 @@ Usage:
108108
coder-studio config <subcommand>
109109
coder-studio auth <subcommand>
110110
coder-studio completion <bash|zsh|fish>
111+
coder-studio completion install <bash|zsh|fish> [--json]
111112
coder-studio --version
112113
113114
Global Flags:
@@ -129,6 +130,7 @@ Examples:
129130
coder-studio config root set /srv/coder-studio/workspaces
130131
coder-studio auth ip list
131132
eval "$(coder-studio completion bash)"
133+
coder-studio completion install bash
132134
133135
Run \`coder-studio config --help\`, \`coder-studio auth --help\`, or \`coder-studio help completion\` for detailed usage.
134136
`);
@@ -300,17 +302,33 @@ function printCompletionHelp() {
300302
301303
Usage:
302304
coder-studio completion <bash|zsh|fish>
305+
coder-studio completion install <bash|zsh|fish> [--json]
303306
304307
Description:
305-
Print a shell completion script to stdout. Evaluate or source the output in your shell profile.
308+
Print or install shell completion scripts.
306309
307310
Examples:
308311
eval "$(coder-studio completion bash)"
309312
source <(coder-studio completion zsh)
310313
coder-studio completion fish | source
314+
coder-studio completion install bash
315+
coder-studio completion install zsh --json
311316
`);
312317
}
313318

319+
function printCompletionInstall(result) {
320+
console.log(`installed: ${result.shell}`);
321+
console.log(`scriptPath: ${result.scriptPath}`);
322+
if (result.profilePath) {
323+
console.log(`profilePath: ${result.profilePath}`);
324+
console.log(`profileUpdated: ${result.profileUpdated ? 'yes' : 'no'}`);
325+
} else {
326+
console.log('profilePath: n/a');
327+
console.log('profileUpdated: no');
328+
}
329+
console.log(`activationCommand: ${result.activationCommand}`);
330+
}
331+
314332
function printHelpTopic(topic) {
315333
switch (topic) {
316334
case undefined:
@@ -933,23 +951,41 @@ export async function runCli(argv = process.argv.slice(2)) {
933951
}
934952

935953
if (command === 'completion') {
936-
if (flags.json) {
937-
throw usageError('completion does not support --json', 'completion');
954+
const [modeOrShell, maybeShell, ...rest] = positionals;
955+
if (!modeOrShell) {
956+
printCompletionHelp();
957+
return EXIT_SUCCESS;
938958
}
939959

940-
const [shell, ...rest] = positionals;
941-
if (!shell) {
942-
printCompletionHelp();
960+
if (modeOrShell === 'install') {
961+
const shell = maybeShell;
962+
if (!shell) {
963+
throw usageError('completion install requires <bash|zsh|fish>', 'completion');
964+
}
965+
if (rest.length > 0) {
966+
throw usageError('completion install accepts exactly one <shell> argument', 'completion');
967+
}
968+
if (!SUPPORTED_COMPLETION_SHELLS.includes(shell)) {
969+
throw usageError(`unsupported completion shell: ${shell}`, 'completion');
970+
}
971+
972+
const result = await installCompletionScript(shell);
973+
if (flags.json) printJson(result);
974+
else printCompletionInstall(result);
943975
return EXIT_SUCCESS;
944976
}
945-
if (rest.length > 0) {
977+
978+
if (flags.json) {
979+
throw usageError('completion does not support --json', 'completion');
980+
}
981+
if (maybeShell || rest.length > 0) {
946982
throw usageError('completion accepts exactly one <shell> argument', 'completion');
947983
}
948-
if (!SUPPORTED_COMPLETION_SHELLS.includes(shell)) {
949-
throw usageError(`unsupported completion shell: ${shell}`, 'completion');
984+
if (!SUPPORTED_COMPLETION_SHELLS.includes(modeOrShell)) {
985+
throw usageError(`unsupported completion shell: ${modeOrShell}`, 'completion');
950986
}
951987

952-
process.stdout.write(generateCompletionScript(shell));
988+
process.stdout.write(generateCompletionScript(modeOrShell));
953989
return EXIT_SUCCESS;
954990
}
955991

0 commit comments

Comments
 (0)