Skip to content

Commit 72087d5

Browse files
Add SDKMAN (sdk) completion spec and version generator
Add completion support for the SDKMAN 'sdk' command: - sdk.json: Full completion spec covering all subcommands (install, uninstall, list, use, config, default, home, env, current, upgrade, version, broadcast, help, offline, selfupdate, update, flush) with their aliases, args, and options. - sdk.rs: Three Rust generators: - sdk_candidates: Lists all available SDK candidates from the local cache - sdk_installed_candidates: Lists locally installed candidates - sdk_versions: Context-aware generator that lists installed versions for the candidate specified in the preceding token Closes warpdotdev/warp#3344 Co-Authored-By: Oz <oz-agent@warp.dev>
1 parent 703ddea commit 72087d5

3 files changed

Lines changed: 363 additions & 0 deletions

File tree

command-signatures/json/sdk.json

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
{
2+
"name": "sdk",
3+
"description": "SDKMAN! - The Software Development Kit Manager",
4+
"subcommands": [
5+
{
6+
"name": [
7+
"install",
8+
"i"
9+
],
10+
"description": "Install a candidate version",
11+
"args": [
12+
{
13+
"name": "candidate",
14+
"description": "SDK candidate to install",
15+
"generatorName": "sdk_candidates"
16+
},
17+
{
18+
"name": "version",
19+
"description": "Version to install (defaults to latest stable)",
20+
"isOptional": true,
21+
"generatorName": "sdk_versions"
22+
},
23+
{
24+
"name": "local-path",
25+
"description": "Path to a local installation",
26+
"isOptional": true,
27+
"template": "folders"
28+
}
29+
]
30+
},
31+
{
32+
"name": [
33+
"uninstall",
34+
"rm"
35+
],
36+
"description": "Uninstall a candidate version",
37+
"args": [
38+
{
39+
"name": "candidate",
40+
"description": "SDK candidate to uninstall",
41+
"generatorName": "sdk_installed_candidates"
42+
},
43+
{
44+
"name": "version",
45+
"description": "Version to uninstall",
46+
"generatorName": "sdk_versions"
47+
}
48+
]
49+
},
50+
{
51+
"name": [
52+
"list",
53+
"ls"
54+
],
55+
"description": "List available candidates or candidate versions",
56+
"args": {
57+
"name": "candidate",
58+
"description": "SDK candidate to list versions for",
59+
"isOptional": true,
60+
"generatorName": "sdk_candidates"
61+
}
62+
},
63+
{
64+
"name": [
65+
"use",
66+
"u"
67+
],
68+
"description": "Use a candidate version in the current shell",
69+
"args": [
70+
{
71+
"name": "candidate",
72+
"description": "SDK candidate to use",
73+
"generatorName": "sdk_installed_candidates"
74+
},
75+
{
76+
"name": "version",
77+
"description": "Version to use",
78+
"generatorName": "sdk_versions"
79+
}
80+
]
81+
},
82+
{
83+
"name": "config",
84+
"description": "Edit the SDKMAN configuration"
85+
},
86+
{
87+
"name": [
88+
"default",
89+
"d"
90+
],
91+
"description": "Set the default candidate version for all shells",
92+
"args": [
93+
{
94+
"name": "candidate",
95+
"description": "SDK candidate to set default for",
96+
"generatorName": "sdk_installed_candidates"
97+
},
98+
{
99+
"name": "version",
100+
"description": "Version to set as default",
101+
"isOptional": true,
102+
"generatorName": "sdk_versions"
103+
}
104+
]
105+
},
106+
{
107+
"name": [
108+
"home",
109+
"h"
110+
],
111+
"description": "Show the installation path of a candidate version",
112+
"args": [
113+
{
114+
"name": "candidate",
115+
"description": "SDK candidate",
116+
"generatorName": "sdk_installed_candidates"
117+
},
118+
{
119+
"name": "version",
120+
"description": "Version to show path for",
121+
"generatorName": "sdk_versions"
122+
}
123+
]
124+
},
125+
{
126+
"name": [
127+
"env",
128+
"e"
129+
],
130+
"description": "Manage .sdkmanrc environment configuration",
131+
"args": {
132+
"name": "command",
133+
"description": "Env subcommand",
134+
"isOptional": true,
135+
"suggestions": [
136+
{
137+
"name": "init",
138+
"description": "Initialize a .sdkmanrc file in the current directory",
139+
"type": "subcommand"
140+
},
141+
{
142+
"name": "install",
143+
"description": "Install SDKs specified in .sdkmanrc",
144+
"type": "subcommand"
145+
},
146+
{
147+
"name": "clear",
148+
"description": "Reset SDKs to their default versions",
149+
"type": "subcommand"
150+
}
151+
]
152+
}
153+
},
154+
{
155+
"name": [
156+
"current",
157+
"c"
158+
],
159+
"description": "Display the current version of a candidate or all candidates",
160+
"args": {
161+
"name": "candidate",
162+
"description": "SDK candidate to show current version for",
163+
"isOptional": true,
164+
"generatorName": "sdk_installed_candidates"
165+
}
166+
},
167+
{
168+
"name": [
169+
"upgrade",
170+
"ug"
171+
],
172+
"description": "Show or perform upgrades for candidate versions",
173+
"args": {
174+
"name": "candidate",
175+
"description": "SDK candidate to upgrade",
176+
"isOptional": true,
177+
"generatorName": "sdk_installed_candidates"
178+
}
179+
},
180+
{
181+
"name": [
182+
"version",
183+
"v"
184+
],
185+
"description": "Display the current version of SDKMAN"
186+
},
187+
{
188+
"name": [
189+
"broadcast",
190+
"b"
191+
],
192+
"description": "Display the latest SDK release notifications"
193+
},
194+
{
195+
"name": "help",
196+
"description": "Show the SDKMAN help message",
197+
"args": {
198+
"name": "subcommand",
199+
"description": "Subcommand to get help for",
200+
"isOptional": true,
201+
"suggestions": [
202+
"install",
203+
"uninstall",
204+
"list",
205+
"use",
206+
"config",
207+
"default",
208+
"home",
209+
"env",
210+
"current",
211+
"upgrade",
212+
"version",
213+
"broadcast",
214+
"help",
215+
"offline",
216+
"selfupdate",
217+
"update",
218+
"flush"
219+
]
220+
}
221+
},
222+
{
223+
"name": "offline",
224+
"description": "Enable or disable offline mode",
225+
"args": {
226+
"name": "mode",
227+
"description": "Enable or disable offline mode",
228+
"isOptional": true,
229+
"suggestions": [
230+
{
231+
"name": "enable",
232+
"description": "Enable offline mode"
233+
},
234+
{
235+
"name": "disable",
236+
"description": "Disable offline mode"
237+
}
238+
]
239+
}
240+
},
241+
{
242+
"name": "selfupdate",
243+
"description": "Update SDKMAN itself",
244+
"args": {
245+
"name": "force",
246+
"description": "Force re-installation",
247+
"isOptional": true,
248+
"suggestions": [
249+
{
250+
"name": "force",
251+
"description": "Force re-installation of SDKMAN"
252+
}
253+
]
254+
}
255+
},
256+
{
257+
"name": "update",
258+
"description": "Refresh the candidate cache to discover new candidates"
259+
},
260+
{
261+
"name": "flush",
262+
"description": "Flush SDKMAN local state",
263+
"args": {
264+
"name": "target",
265+
"description": "What to flush",
266+
"isOptional": true,
267+
"suggestions": [
268+
{
269+
"name": "tmp",
270+
"description": "Flush the temporary folder"
271+
},
272+
{
273+
"name": "metadata",
274+
"description": "Flush the candidate metadata cache"
275+
},
276+
{
277+
"name": "version",
278+
"description": "Flush the cached SDKMAN version"
279+
}
280+
]
281+
}
282+
}
283+
]
284+
}

command-signatures/src/generators/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ mod powershell;
4141
mod pyenv;
4242
mod react_native;
4343
mod screen;
44+
mod sdk;
4445
mod ssh;
4546
mod systemctl;
4647
mod tar;
@@ -98,6 +99,7 @@ pub fn dynamic_command_signature_data() -> HashMap<String, DynamicCompletionData
9899
tmux::generator(),
99100
node::generator(),
100101
screen::generator(),
102+
sdk::generator(),
101103
powershell::get_help_generator(),
102104
powershell::get_process_generator(),
103105
powershell::debug_process_generator(),
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use warp_completion_metadata::{
2+
CommandBuilder, CommandSignatureGenerators, Generator, GeneratorResultsCollector, Suggestion,
3+
};
4+
5+
pub fn generator() -> CommandSignatureGenerators {
6+
CommandSignatureGenerators::new("sdk")
7+
.add_generator(
8+
"sdk_candidates",
9+
Generator::script(
10+
CommandBuilder::single_command(
11+
"cat ~/.sdkman/var/candidates",
12+
),
13+
|output| {
14+
output
15+
.trim()
16+
.split(',')
17+
.filter(|s| !s.is_empty())
18+
.map(|candidate| {
19+
Suggestion::with_description(candidate.trim(), "SDK candidate")
20+
})
21+
.collect_unordered_results()
22+
},
23+
),
24+
)
25+
.add_generator(
26+
"sdk_installed_candidates",
27+
Generator::script(
28+
CommandBuilder::single_command(
29+
"ls -1 ~/.sdkman/candidates",
30+
),
31+
|output| {
32+
output
33+
.trim()
34+
.lines()
35+
.filter(|s| !s.is_empty())
36+
.map(|candidate| {
37+
Suggestion::with_description(candidate.trim(), "Installed candidate")
38+
})
39+
.collect_unordered_results()
40+
},
41+
),
42+
)
43+
.add_generator(
44+
"sdk_versions",
45+
Generator::command_from_tokens(
46+
|tokens, has_trailing_whitespace, _| {
47+
// The candidate name is the token immediately before the version position.
48+
// With trailing whitespace, the last completed token is the candidate.
49+
// Without trailing whitespace, the second-to-last token is the candidate.
50+
let candidate = if has_trailing_whitespace {
51+
tokens.last().copied()
52+
} else {
53+
tokens.get(tokens.len().saturating_sub(2)).copied()
54+
};
55+
match candidate {
56+
Some(candidate) if !candidate.is_empty() && !candidate.starts_with('-') => {
57+
CommandBuilder::single_command(format!(
58+
"ls -1 ~/.sdkman/candidates/{}/",
59+
candidate
60+
))
61+
}
62+
_ => CommandBuilder::single_command("echo"),
63+
}
64+
},
65+
|output| {
66+
output
67+
.trim()
68+
.lines()
69+
.filter(|s| !s.is_empty() && *s != "current")
70+
.map(|version| {
71+
Suggestion::with_description(version.trim(), "Installed version")
72+
})
73+
.collect_unordered_results()
74+
},
75+
),
76+
)
77+
}

0 commit comments

Comments
 (0)