@@ -1103,4 +1103,313 @@ def __journalctlCompletion { 'complete': ['journalctl'] } ([str] -- [str])
11031103 end
11041104end
11051105# }}}
1106+ # cargo {{{
1107+ # Options valid both at the top level and after any subcommand.
1108+ def __cargoCommonOptions ( -- [str])
1109+ ['-h' '--help' '-V' '--version' '-v' '--verbose' '-q' '--quiet'
1110+ '--color' '--config' '-Z' '--frozen' '--locked' '--offline']
1111+ end
1112+
1113+ # Parse `cargo --list` for the available subcommands (includes installed third-party ones).
1114+ def __cargoSubcommands ( -- [str])
1115+ ['cargo' '--list'] * ^ ; drop lines
1116+ (' ' startsWith) filter
1117+ (trim) map
1118+ (len 0 >) filter
1119+ (wsplit :0:) map
1120+ end
1121+
1122+ # Installed targets from rustup if available, otherwise all targets known to rustc.
1123+ def __cargoTargets ( -- [str])
1124+ ['rustup' 'target' 'list'] * ^ ? code! drop out!
1125+ @code 0 = if
1126+ @out lines ('(installed)' in) filter (wsplit :0:) map
1127+ else
1128+ ['rustc' '--print' 'target-list'] * ^ ; drop lines (len 0 >) filter
1129+ end
1130+ end
1131+
1132+ # Feature names from the current crate's manifest.
1133+ def __cargoFeatures ( -- [str])
1134+ ['cargo' 'read-manifest'] * ^ ; drop out!
1135+ @out trim len 0 > if
1136+ @out parseJson match
1137+ dict d : @d 'features' {} getDef match
1138+ dict features : @features keys,
1139+ _ : [] as [str],
1140+ end,
1141+ _ : [] as [str],
1142+ end
1143+ else
1144+ [] as [str]
1145+ end
1146+ end
1147+
1148+ # Workspace package names from cargo metadata.
1149+ def __cargoPackages ( -- [str])
1150+ ['cargo' 'metadata' '--no-deps' '--format-version' '1'] * ^ ; drop out!
1151+ @out trim len 0 > if
1152+ @out parseJson match
1153+ dict d : @d 'packages' [] getDef match
1154+ list packages :
1155+ @packages
1156+ (pkg! @pkg match
1157+ dict p : @p 'name' '' getDef match str name : @name, _ : '', end,
1158+ _ : '',
1159+ end) map
1160+ (len 0 >) filter,
1161+ _ : [] as [str],
1162+ end,
1163+ _ : [] as [str],
1164+ end
1165+ else
1166+ [] as [str]
1167+ end
1168+ end
1169+
1170+ # cargo prints the available target names to stderr when the flag is given no value,
1171+ # e.g. `cargo run --bin` lists "Available binaries:" with one indented name per line.
1172+ def __cargoTargetNames (str -- [str])
1173+ flag!
1174+ { 'bin': 'run', 'example': 'run', 'test': 'test', 'bench': 'bench' } @flag 'run' getDef subcmd!
1175+ ['cargo' @subcmd $"--{@flag}"] * ^ ; err! drop
1176+ @err lines (' ' startsWith) filter (trim) map (len 0 >) filter
1177+ end
1178+
1179+ # Crates listed by `cargo install --list`; unindented lines are "name vX.Y.Z:".
1180+ def __cargoInstalled ( -- [str])
1181+ ['cargo' 'install' '--list'] * ^ ; drop lines
1182+ (len 0 >) filter
1183+ (' ' startsWith not) filter
1184+ (wsplit :0:) map
1185+ end
1186+
1187+ def __cargoOptionsForSubcmd (str -- [str])
1188+ cmd!
1189+ {
1190+ 'add': [
1191+ '--dev' '--build' '--dry-run' '--optional' '--no-optional' '--rename'
1192+ '--features' '--default-features' '--no-default-features'
1193+ '--path' '--git' '--branch' '--tag' '--rev' '--registry'
1194+ '-p' '--package' '--manifest-path'
1195+ ],
1196+ 'bench': [
1197+ '-p' '--package' '--exclude' '-j' '--jobs' '--lib' '--bin' '--bins'
1198+ '--example' '--examples' '--test' '--tests' '--bench' '--benches'
1199+ '--all-targets' '--no-run' '--no-fail-fast' '--workspace'
1200+ '--features' '--all-features' '--no-default-features'
1201+ '--target' '--target-dir' '--manifest-path' '--message-format'
1202+ '--profile' '--ignore-rust-version' '--unit-graph'
1203+ ],
1204+ 'build': [
1205+ '-p' '--package' '--exclude' '-j' '--jobs' '--lib' '--bin' '--bins'
1206+ '--example' '--examples' '--test' '--tests' '--bench' '--benches'
1207+ '--all-targets' '--workspace' '--release' '--profile'
1208+ '--features' '--all-features' '--no-default-features'
1209+ '--target' '--target-dir' '--out-dir' '--manifest-path' '--message-format'
1210+ '--build-plan' '--unit-graph' '--future-incompat-report' '--ignore-rust-version'
1211+ ],
1212+ 'check': [
1213+ '-p' '--package' '--exclude' '-j' '--jobs' '--lib' '--bin' '--bins'
1214+ '--example' '--examples' '--test' '--tests' '--bench' '--benches'
1215+ '--all-targets' '--workspace' '--release' '--profile'
1216+ '--features' '--all-features' '--no-default-features'
1217+ '--target' '--target-dir' '--manifest-path' '--message-format'
1218+ '--unit-graph' '--future-incompat-report' '--ignore-rust-version'
1219+ ],
1220+ 'clean': [
1221+ '-p' '--package' '--manifest-path' '--target' '--target-dir'
1222+ '--profile' '--release' '--doc' '--dry-run'
1223+ ],
1224+ 'doc': [
1225+ '-p' '--package' '--exclude' '-j' '--jobs' '--lib' '--bin' '--bins'
1226+ '--open' '--no-deps' '--document-private-items' '--workspace'
1227+ '--release' '--profile' '--features' '--all-features' '--no-default-features'
1228+ '--target' '--target-dir' '--manifest-path' '--message-format'
1229+ '--ignore-rust-version' '--unit-graph'
1230+ ],
1231+ 'fetch': [
1232+ '--manifest-path' '--target'
1233+ ],
1234+ 'fix': [
1235+ '-p' '--package' '--exclude' '-j' '--jobs' '--lib' '--bin' '--bins'
1236+ '--example' '--examples' '--test' '--tests' '--bench' '--benches'
1237+ '--all-targets' '--workspace' '--release' '--profile'
1238+ '--features' '--all-features' '--no-default-features'
1239+ '--target' '--target-dir' '--manifest-path' '--message-format'
1240+ '--broken-code' '--edition' '--edition-idioms'
1241+ '--allow-no-vcs' '--allow-dirty' '--allow-staged' '--ignore-rust-version'
1242+ ],
1243+ 'generate-lockfile': [
1244+ '--manifest-path'
1245+ ],
1246+ 'init': [
1247+ '--registry' '--vcs' '--edition' '--name' '--bin' '--lib'
1248+ ],
1249+ 'install': [
1250+ '--version' '--git' '--branch' '--tag' '--rev' '--path'
1251+ '-j' '--jobs' '--features' '--all-features' '--no-default-features'
1252+ '--profile' '--bin' '--bins' '--example' '--examples'
1253+ '--target' '--target-dir' '--root' '--index' '--registry'
1254+ '--list' '-f' '--force' '--no-track' '--debug'
1255+ ],
1256+ 'locate-project': [
1257+ '--manifest-path' '--message-format' '--workspace'
1258+ ],
1259+ 'login': [
1260+ '--registry'
1261+ ],
1262+ 'logout': [
1263+ '--registry'
1264+ ],
1265+ 'metadata': [
1266+ '--features' '--all-features' '--no-default-features'
1267+ '--filter-platform' '--manifest-path' '--format-version' '--no-deps'
1268+ ],
1269+ 'new': [
1270+ '--registry' '--vcs' '--edition' '--name' '--bin' '--lib'
1271+ ],
1272+ 'owner': [
1273+ '-a' '--add' '-r' '--remove' '-l' '--list' '--index' '--token' '--registry'
1274+ ],
1275+ 'package': [
1276+ '-l' '--list' '--no-verify' '--no-metadata' '--allow-dirty'
1277+ '--target' '--target-dir' '--features' '--all-features' '--no-default-features'
1278+ '--manifest-path' '-j' '--jobs'
1279+ ],
1280+ 'pkgid': [
1281+ '-p' '--package' '--manifest-path'
1282+ ],
1283+ 'publish': [
1284+ '--index' '--token' '--no-verify' '--allow-dirty' '--dry-run' '--registry'
1285+ '--target' '--target-dir' '--manifest-path'
1286+ '--features' '--all-features' '--no-default-features' '-j' '--jobs'
1287+ ],
1288+ 'remove': [
1289+ '--dev' '--build' '--dry-run' '-p' '--package' '--manifest-path'
1290+ ],
1291+ 'run': [
1292+ '--bin' '--example' '-p' '--package' '-j' '--jobs' '--release' '--profile'
1293+ '--features' '--all-features' '--no-default-features'
1294+ '--target' '--target-dir' '--manifest-path' '--message-format'
1295+ '--unit-graph' '--ignore-rust-version'
1296+ ],
1297+ 'rustc': [
1298+ '-p' '--package' '-j' '--jobs' '--lib' '--bin' '--bins'
1299+ '--example' '--examples' '--test' '--tests' '--bench' '--benches'
1300+ '--all-targets' '--release' '--profile'
1301+ '--features' '--all-features' '--no-default-features'
1302+ '--target' '--target-dir' '--print' '--manifest-path' '--message-format'
1303+ '--unit-graph' '--ignore-rust-version' '--future-incompat-report'
1304+ ],
1305+ 'rustdoc': [
1306+ '-p' '--package' '-j' '--jobs' '--lib' '--bin' '--bins'
1307+ '--example' '--examples' '--test' '--tests' '--bench' '--benches'
1308+ '--all-targets' '--open' '--release' '--profile'
1309+ '--features' '--all-features' '--no-default-features'
1310+ '--target' '--target-dir' '--manifest-path' '--message-format'
1311+ '--unit-graph' '--ignore-rust-version'
1312+ ],
1313+ 'search': [
1314+ '--index' '--limit' '--registry'
1315+ ],
1316+ 'test': [
1317+ '--lib' '--bin' '--bins' '--example' '--examples' '--test' '--tests'
1318+ '--bench' '--benches' '--all-targets' '--doc'
1319+ '-p' '--package' '--exclude' '-j' '--jobs' '--no-run' '--no-fail-fast'
1320+ '--workspace' '--release' '--profile'
1321+ '--features' '--all-features' '--no-default-features'
1322+ '--target' '--target-dir' '--manifest-path' '--message-format'
1323+ '--ignore-rust-version' '--unit-graph' '--future-incompat-report'
1324+ ],
1325+ 'tree': [
1326+ '-p' '--package' '--exclude' '--features' '--all-features' '--no-default-features'
1327+ '--target' '-e' '--edges' '-i' '--invert' '--prefix' '--charset'
1328+ '-f' '--format' '--workspace' '--no-dedupe' '-d' '--duplicates' '--manifest-path'
1329+ ],
1330+ 'uninstall': [
1331+ '-p' '--package' '--bin' '--root'
1332+ ],
1333+ 'update': [
1334+ '-p' '--package' '--precise' '-w' '--workspace' '--aggressive' '--dry-run'
1335+ '--manifest-path' '--ignore-rust-version'
1336+ ],
1337+ 'vendor': [
1338+ '-s' '--sync' '--no-delete' '--respect-source-config' '--versioned-dirs'
1339+ '--manifest-path'
1340+ ],
1341+ 'verify-project': [
1342+ '--manifest-path'
1343+ ],
1344+ 'yank': [
1345+ '--vers' '--undo' '--index' '--token' '--registry'
1346+ ]
1347+ }
1348+ @cmd [] getDef
1349+ end
1350+
1351+ # Default completions after a subcommand: common options plus the subcommand-specific ones.
1352+ def __cargoSubcmdCompletions (str -- [str])
1353+ cmd!
1354+ __cargoCommonOptions @cmd __cargoOptionsForSubcmd extend
1355+ end
1356+
1357+ def __cargoCompletion { 'complete': ['cargo'] } ([str] -- [str])
1358+ input!
1359+ @input len 0 > if
1360+ @input :0: rawSubcmd!
1361+ @rawSubcmd match
1362+ 'b' : 'build',
1363+ 'c' : 'check',
1364+ 'r' : 'run',
1365+ 't' : 'test',
1366+ 'd' : 'doc',
1367+ _ : @rawSubcmd,
1368+ end subcmd!
1369+ @input :-1: last!
1370+
1371+ # Subcommands where --bin/--example (and --test/--bench) take a target name.
1372+ ['bench' 'build' 'check' 'run' 'rustc' 'test'] binExampleCmds!
1373+ ['bench' 'build' 'check' 'rustc' 'test'] testBenchCmds!
1374+
1375+ @last match
1376+ '-p' '--package' '--exclude' : __cargoPackages,
1377+ '--target' : __cargoTargets,
1378+ '--features' : __cargoFeatures,
1379+ '--color' : ['auto' 'always' 'never'],
1380+ '--vcs' : ['git' 'hg' 'pijul' 'fossil' 'none'],
1381+ '--edition' : ['2015' '2018' '2021' '2024'],
1382+ '--message-format' : ['human' 'short' 'json' 'json-diagnostic-short' 'json-diagnostic-rendered-ansi' 'json-render-diagnostics'],
1383+ '--profile' : ['dev' 'release' 'test' 'bench'],
1384+ '--bin' '--example' :
1385+ @binExampleCmds (@subcmd =) any
1386+ (@last 2: __cargoTargetNames)
1387+ (@subcmd __cargoSubcmdCompletions) iff,
1388+ '--test' '--bench' :
1389+ @testBenchCmds (@subcmd =) any
1390+ (@last 2: __cargoTargetNames)
1391+ (@subcmd __cargoSubcmdCompletions) iff,
1392+ '-e' '--edges' :
1393+ @subcmd 'tree' =
1394+ (['features' 'normal' 'build' 'dev' 'all' 'no-dev' 'no-build' 'no-normal'])
1395+ (@subcmd __cargoSubcmdCompletions) iff,
1396+ '--prefix' :
1397+ @subcmd 'tree' =
1398+ (['depth' 'indent' 'none'])
1399+ (@subcmd __cargoSubcmdCompletions) iff,
1400+ '--charset' :
1401+ @subcmd 'tree' =
1402+ (['utf8' 'ascii'])
1403+ (@subcmd __cargoSubcmdCompletions) iff,
1404+ _ : @subcmd match
1405+ 'help' : __cargoSubcommands,
1406+ 'uninstall' : __cargoInstalled @subcmd __cargoSubcmdCompletions extend,
1407+ _ : @subcmd __cargoSubcmdCompletions,
1408+ end,
1409+ end
1410+ else
1411+ __cargoSubcommands ['--list' '--explain' '-C'] extend __cargoCommonOptions extend
1412+ end
1413+ end
1414+ # }}}
11061415# }}}
0 commit comments