From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- vendor/clap_complete/.cargo-checksum.json | 2 +- vendor/clap_complete/Cargo.lock | 749 +++++++++++++++++++++ vendor/clap_complete/Cargo.toml | 121 +++- vendor/clap_complete/LICENSE-MIT | 2 +- vendor/clap_complete/README.md | 8 +- vendor/clap_complete/examples/completion-derive.rs | 83 +++ vendor/clap_complete/examples/completion.rs | 109 +++ vendor/clap_complete/examples/dynamic.rs | 37 + vendor/clap_complete/src/dynamic.rs | 551 +++++++++++++++ vendor/clap_complete/src/generator/mod.rs | 12 +- vendor/clap_complete/src/generator/utils.rs | 49 +- vendor/clap_complete/src/lib.rs | 12 +- vendor/clap_complete/src/macros.rs | 4 +- vendor/clap_complete/src/shells/bash.rs | 76 ++- vendor/clap_complete/src/shells/elvish.rs | 16 +- vendor/clap_complete/src/shells/fish.rs | 29 +- vendor/clap_complete/src/shells/powershell.rs | 16 +- vendor/clap_complete/src/shells/shell.rs | 80 ++- vendor/clap_complete/src/shells/zsh.rs | 45 +- 19 files changed, 1847 insertions(+), 154 deletions(-) create mode 100644 vendor/clap_complete/Cargo.lock create mode 100644 vendor/clap_complete/examples/completion-derive.rs create mode 100644 vendor/clap_complete/examples/completion.rs create mode 100644 vendor/clap_complete/examples/dynamic.rs create mode 100644 vendor/clap_complete/src/dynamic.rs (limited to 'vendor/clap_complete') diff --git a/vendor/clap_complete/.cargo-checksum.json b/vendor/clap_complete/.cargo-checksum.json index e45184732..6926ea04d 100644 --- a/vendor/clap_complete/.cargo-checksum.json +++ b/vendor/clap_complete/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"78b091c02d2d903bba91b0bbb8d769a294a4be411caf9ef358b38b7fe2aed844","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"29992473eab9cc65cb87acd7f8d9e76de780f7a7bf1cf8d225b1da5019b92461","src/generator/mod.rs":"63a0952a41e3d46769be84e6f6f6efebe187a9982090d0ec59100f2b0df79991","src/generator/utils.rs":"20fd8a7e18c66cf004f03cdd2af46b3f9fcee4b6d86d6f7bb94f2e15e98b2942","src/lib.rs":"4c1205e68ed8e12208ec96a430d9ca25982ff99c7d69dce73f28f9a48f680ca8","src/macros.rs":"63f96b4cf6e0704fb7df1335310e480bbcc5438b19337d46edfe587b393987b9","src/shells/bash.rs":"85823ec1abc1cb7fd5bd05387f19ae796bfba59edc5dba11860b3c3b2410f063","src/shells/elvish.rs":"d59f34254ca188ac2c0c96af9f0c14c55e579db1e97c6bd55699b4d50f365f66","src/shells/fish.rs":"e5c61b237c8b90d0ec582566d7aefef97fc90efcd964111a5bb987d0663d04e7","src/shells/mod.rs":"002352299be1ece75540e7b1502120590f4635f69a925b19484d272bd5491505","src/shells/powershell.rs":"95215c05d45a634150cc5dcd403f8468a47e316aa465e48c92775b2349cf2116","src/shells/shell.rs":"0c96280a1f7f1f4d14d62a958fca237825aa5e1b8b8f55f961972a2098f15e55","src/shells/zsh.rs":"2984c66f920ca5c91ad761ef9944e8fca3b73089e48a58ef605edb70e71af045"},"package":"df6f3613c0a3cddfd78b41b10203eb322cb29b600cbdf808a7d3db95691b8e25"} \ No newline at end of file +{"files":{"Cargo.lock":"d53222e493cada99842c2d6d0b91233175dc27cafbd4ac39d3a4b262b54c64c3","Cargo.toml":"135479adb22e0d6b534b4ac2ff74ef404d423cf95c77f74021c799094a4902a7","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","LICENSE-MIT":"0d687e1f07b58fe68bda74668ff6326125e5e5efa184cce755cd84ac535b7058","README.md":"1b3588e4808c7c82397439978e29dcd8c34925691dcd46ea52188bc7a18016fa","examples/completion-derive.rs":"09b32a23013801c54a8d97bd9f6491622d5dca511d2697bff14f813607aca123","examples/completion.rs":"57e57d7912c526a819e7316826171cf085f3c776c8e8d3e925045a00f538c35c","examples/dynamic.rs":"ea4acc40d3e0f29dc0a361fe2d492781b0c25f563f0e9c88953bf0c7e1dee118","src/dynamic.rs":"d9d6bd3efad431171207be08865e85ef0b03bd816b5f2568ae13fda9a1383712","src/generator/mod.rs":"539825646f53f940028107fdef70533695ffee70cd8ddb9f5cb98a740b3db78f","src/generator/utils.rs":"2486cdfc9edf1678fed953080ce48b3350e7b4a2f29e7e3a681b64d621f40f47","src/lib.rs":"7d14cf0f58409f4b92efa1e9813b74ad218e233ae07ca60c5f22b728e6635afd","src/macros.rs":"8445231263f03893ab3806e3f50747113bf8d638bd81e2a6bf33c9a0df224421","src/shells/bash.rs":"43db9bf78b1de14507b3dee31361b141a3feddfe156402e52a4d9700cee6bacc","src/shells/elvish.rs":"56504ca90a06d29a5f4efe42319c4465ab5582eb3b4aadec93b4627c165e5b7c","src/shells/fish.rs":"651d635bae3deab880168c2add526a2751f56c1d149aaf47b5a00ea23458a207","src/shells/mod.rs":"002352299be1ece75540e7b1502120590f4635f69a925b19484d272bd5491505","src/shells/powershell.rs":"c53820d916b02774395cb7068833f7c8382f15a89b447e151b430383755efdb7","src/shells/shell.rs":"5896fd71c67c386c0ba3edcf63bda4c81cab0d7b69261ac3f6a2e56a528349ec","src/shells/zsh.rs":"61d34ded630ad766051bd4b8383b8137fd894d452d1a6ee498309851131de81f"},"package":"10861370d2ba66b0f5989f83ebf35db6421713fd92351790e7fdd6c36774c56b"} \ No newline at end of file diff --git a/vendor/clap_complete/Cargo.lock b/vendor/clap_complete/Cargo.lock new file mode 100644 index 000000000..dd3bb2d6b --- /dev/null +++ b/vendor/clap_complete/Cargo.lock @@ -0,0 +1,749 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" + +[[package]] +name = "cc" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab512b39872b48c5ecf6b3bef2efb56dc0b986630d9da71a21a8c8f6878c334" +dependencies = [ + "backtrace", + "bitflags", + "clap_derive", + "clap_lex", + "once_cell", +] + +[[package]] +name = "clap_complete" +version = "4.0.7" +dependencies = [ + "clap", + "clap_lex", + "is_executable", + "os_str_bytes", + "pathdiff", + "shlex", + "snapbox", + "trycmd", + "unicode-xid", +] + +[[package]] +name = "clap_derive" +version = "4.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concolor" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "318d6c16e73b3a900eb212ad6a82fc7d298c5ab8184c7a9998646455bc474a16" +dependencies = [ + "bitflags", + "concolor-query", + "is-terminal", +] + +[[package]] +name = "concolor-query" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "escargot" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6" +dependencies = [ + "log", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "gimli" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys", +] + +[[package]] +name = "is_executable" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9acdc6d67b75e626ad644734e8bc6df893d9cd2a834129065d3dd6158ea9c8" +dependencies = [ + "winapi", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "os_pipe" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a252f1f8c11e84b3ab59d7a488e48e4478a93937e027076638c49536204639" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustix" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "similar" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" + +[[package]] +name = "snapbox" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbd7b250c7243273b5aec4ca366fced84ad716d110bb7baae4814678952ebde" +dependencies = [ + "concolor", + "libc", + "normalize-line-endings", + "os_pipe", + "similar", + "snapbox-macros", + "wait-timeout", + "windows-sys", + "yansi", +] + +[[package]] +name = "snapbox-macros" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "485e65c1203eb37244465e857d15a26d3a85a5410648ccb53b18bd44cb3a7336" + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "toml_datetime" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808b51e57d0ef8f71115d8f3a01e7d3750d01c79cac4b3eda910f4389fdf92fd" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1541ba70885967e662f69d31ab3aeca7b1aaecfcd58679590b893e9239c3646" +dependencies = [ + "combine", + "indexmap", + "itertools", + "serde", + "toml_datetime", +] + +[[package]] +name = "trycmd" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e381af441e13a3635303d26769620a9454aef05ec3303711efc3f1dd785a33af" +dependencies = [ + "escargot", + "glob", + "humantime", + "humantime-serde", + "rayon", + "serde", + "shlex", + "snapbox", + "toml_edit", +] + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff --git a/vendor/clap_complete/Cargo.toml b/vendor/clap_complete/Cargo.toml index 175767620..060c43c55 100644 --- a/vendor/clap_complete/Cargo.toml +++ b/vendor/clap_complete/Cargo.toml @@ -10,70 +10,145 @@ # See Cargo.toml.orig for the original contents. [package] -edition = "2018" +edition = "2021" +rust-version = "1.60.0" name = "clap_complete" -version = "3.1.1" -include = ["src/**/*", "Cargo.toml", "LICENSE-*", "README.md"] +version = "4.0.7" +include = [ + "build.rs", + "src/**/*", + "Cargo.toml", + "LICENSE*", + "README.md", + "benches/**/*", + "examples/**/*", +] description = "Generate shell completion scripts for your clap::Command" -documentation = "https://docs.rs/clap_complete" readme = "README.md" -keywords = ["clap", "cli", "completion", "bash"] +keywords = [ + "clap", + "cli", + "completion", + "bash", +] categories = ["command-line-interface"] license = "MIT OR Apache-2.0" repository = "https://github.com/clap-rs/clap/tree/master/clap_complete" + [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + [[package.metadata.release.pre-release-replacements]] file = "CHANGELOG.md" -min = 1 -replace = "{{version}}" search = "Unreleased" +replace = "{{version}}" +min = 1 [[package.metadata.release.pre-release-replacements]] -exactly = 1 file = "CHANGELOG.md" +search = '\.\.\.HEAD' replace = "...{{tag_name}}" -search = "\\.\\.\\.HEAD" +exactly = 1 [[package.metadata.release.pre-release-replacements]] file = "CHANGELOG.md" -min = 1 -replace = "{{date}}" search = "ReleaseDate" +replace = "{{date}}" +min = 1 [[package.metadata.release.pre-release-replacements]] -exactly = 1 file = "CHANGELOG.md" -replace = "\n## [Unreleased] - ReleaseDate\n" search = "" +replace = """ + +## [Unreleased] - ReleaseDate +""" +exactly = 1 [[package.metadata.release.pre-release-replacements]] -exactly = 1 file = "CHANGELOG.md" -replace = "\n[Unreleased]: https://github.com/clap-rs/clap/compare/{{tag_name}}...HEAD" search = "" +replace = """ + +[Unreleased]: https://github.com/clap-rs/clap/compare/{{tag_name}}...HEAD""" +exactly = 1 [[package.metadata.release.pre-release-replacements]] -exactly = 4 file = "README.md" -prerelease = true -replace = "github.com/clap-rs/clap/blob/{{tag_name}}/" search = "github.com/clap-rs/clap/blob/[^/]+/" +replace = "github.com/clap-rs/clap/blob/{{tag_name}}/" +exactly = 4 +prerelease = true [lib] bench = false + +[[example]] +name = "dynamic" +required-features = ["unstable-dynamic"] + [dependencies.clap] -version = "3.1.0" +version = "4.0.0" features = ["std"] default-features = false + +[dependencies.clap_lex] +version = "0.3.0" +optional = true + +[dependencies.is_executable] +version = "1.0.1" +optional = true + +[dependencies.os_str_bytes] +version = "6.0" +features = ["raw_os_str"] +optional = true +default-features = false + +[dependencies.pathdiff] +version = "0.2.1" +optional = true + +[dependencies.shlex] +version = "1.1.0" +optional = true + +[dependencies.unicode-xid] +version = "0.2.2" +optional = true + [dev-dependencies.clap] -version = "3.1.0" -features = ["std", "derive"] +version = "4.0.0" +features = [ + "std", + "derive", + "help", +] default-features = false -[dev-dependencies.pretty_assertions] -version = "1.0" +[dev-dependencies.snapbox] +version = "0.4" +features = ["diff"] + +[dev-dependencies.trycmd] +version = "0.14.5" +features = [ + "color-auto", + "diff", + "examples", +] +default-features = false [features] debug = ["clap/debug"] default = [] +unstable-dynamic = [ + "dep:clap_lex", + "dep:shlex", + "dep:unicode-xid", + "dep:os_str_bytes", + "clap/derive", + "dep:is_executable", + "dep:pathdiff", +] diff --git a/vendor/clap_complete/LICENSE-MIT b/vendor/clap_complete/LICENSE-MIT index 5acedf041..7b05b8453 100644 --- a/vendor/clap_complete/LICENSE-MIT +++ b/vendor/clap_complete/LICENSE-MIT @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2016 Kevin B. Knapp +Copyright (c) 2015-2022 Kevin B. Knapp and Clap Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/clap_complete/README.md b/vendor/clap_complete/README.md index 5336af86b..286775230 100644 --- a/vendor/clap_complete/README.md +++ b/vendor/clap_complete/README.md @@ -5,16 +5,16 @@ [![Crates.io](https://img.shields.io/crates/v/clap_complete?style=flat-square)](https://crates.io/crates/clap_complete) [![Crates.io](https://img.shields.io/crates/d/clap_complete?style=flat-square)](https://crates.io/crates/clap_complete) -[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v3.1.1/LICENSE-APACHE) -[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v3.1.1/LICENSE-MIT) +[![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v4.0.7/LICENSE-APACHE) +[![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/clap-rs/clap/blob/clap_complete-v4.0.7/LICENSE-MIT) Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT). 1. [About](#about) 2. [API Reference](https://docs.rs/clap_complete) 3. [Questions & Discussions](https://github.com/clap-rs/clap/discussions) -4. [CONTRIBUTING](https://github.com/clap-rs/clap/blob/clap_complete-v3.1.1/clap_complete/CONTRIBUTING.md) -5. [Sponsors](https://github.com/clap-rs/clap/blob/clap_complete-v3.1.1/README.md#sponsors) +4. [CONTRIBUTING](https://github.com/clap-rs/clap/blob/clap_complete-v4.0.7/clap_complete/CONTRIBUTING.md) +5. [Sponsors](https://github.com/clap-rs/clap/blob/clap_complete-v4.0.7/README.md#sponsors) ## About diff --git a/vendor/clap_complete/examples/completion-derive.rs b/vendor/clap_complete/examples/completion-derive.rs new file mode 100644 index 000000000..8eeebf89d --- /dev/null +++ b/vendor/clap_complete/examples/completion-derive.rs @@ -0,0 +1,83 @@ +//! How to use value hints and generate shell completions. +//! +//! Usage with zsh: +//! ```sh +//! cargo run --example value_hints_derive -- --generate=zsh > /usr/local/share/zsh/site-functions/_value_hints_derive +//! compinit +//! ./target/debug/examples/value_hints_derive -- +//! ``` +//! fish: +//! ```sh +//! cargo run --example value_hints_derive -- --generate=fish > value_hints_derive.fish +//! . ./value_hints_derive.fish +//! ./target/debug/examples/value_hints_derive -- +//! ``` +use clap::{Args, Command, CommandFactory, Parser, Subcommand, ValueHint}; +use clap_complete::{generate, Generator, Shell}; +use std::ffi::OsString; +use std::io; +use std::path::PathBuf; + +#[derive(Parser, Debug, PartialEq)] +#[command(name = "completion-derive")] +struct Opt { + // If provided, outputs the completion file for given shell + #[arg(long = "generate", value_enum)] + generator: Option, + #[clap(subcommand)] + command: Option, +} + +#[derive(Subcommand, Debug, PartialEq)] +enum Commands { + #[command(visible_alias = "hint")] + ValueHint(ValueHintOpt), +} + +#[derive(Args, Debug, PartialEq)] +struct ValueHintOpt { + // Showcasing all possible ValueHints: + #[arg(long, value_hint = ValueHint::Unknown)] + unknown: Option, + #[arg(long, value_hint = ValueHint::Other)] + other: Option, + #[arg(short, long, value_hint = ValueHint::AnyPath)] + path: Option, + #[arg(short, long, value_hint = ValueHint::FilePath)] + file: Option, + #[arg(short, long, value_hint = ValueHint::DirPath)] + dir: Option, + #[arg(short, long, value_hint = ValueHint::ExecutablePath)] + exe: Option, + #[arg(long, value_hint = ValueHint::CommandName)] + cmd_name: Option, + #[arg(short, long, value_hint = ValueHint::CommandString)] + cmd: Option, + // Command::trailing_var_ar is required to use ValueHint::CommandWithArguments + #[arg(trailing_var_arg = true, value_hint = ValueHint::CommandWithArguments)] + command_with_args: Vec, + #[arg(short, long, value_hint = ValueHint::Username)] + user: Option, + #[arg(long, value_hint = ValueHint::Hostname)] + host: Option, + #[arg(long, value_hint = ValueHint::Url)] + url: Option, + #[arg(long, value_hint = ValueHint::EmailAddress)] + email: Option, +} + +fn print_completions(gen: G, cmd: &mut Command) { + generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout()); +} + +fn main() { + let opt = Opt::parse(); + + if let Some(generator) = opt.generator { + let mut cmd = Opt::command(); + eprintln!("Generating completion file for {:?}...", generator); + print_completions(generator, &mut cmd); + } else { + println!("{:#?}", opt); + } +} diff --git a/vendor/clap_complete/examples/completion.rs b/vendor/clap_complete/examples/completion.rs new file mode 100644 index 000000000..0455d4f9c --- /dev/null +++ b/vendor/clap_complete/examples/completion.rs @@ -0,0 +1,109 @@ +//! Example to test arguments with different ValueHint values. +//! +//! Usage with zsh: +//! ```sh +//! cargo run --example value_hints -- --generate=zsh > /usr/local/share/zsh/site-functions/_value_hints +//! compinit +//! ./target/debug/examples/value_hints -- +//! ``` +//! fish: +//! ```sh +//! cargo run --example value_hints -- --generate=fish > value_hints.fish +//! . ./value_hints.fish +//! ./target/debug/examples/value_hints -- +//! ``` +use clap::{value_parser, Arg, Command, ValueHint}; +use clap_complete::{generate, Generator, Shell}; +use std::io; + +fn build_cli() -> Command { + let value_hint_command = Command::new("value-hint") + .visible_alias("hint") + .arg( + Arg::new("unknown") + .long("unknown") + .value_hint(ValueHint::Unknown), + ) + .arg(Arg::new("other").long("other").value_hint(ValueHint::Other)) + .arg( + Arg::new("path") + .long("path") + .short('p') + .value_hint(ValueHint::AnyPath), + ) + .arg( + Arg::new("file") + .long("file") + .short('f') + .value_hint(ValueHint::FilePath), + ) + .arg( + Arg::new("dir") + .long("dir") + .short('d') + .value_hint(ValueHint::DirPath), + ) + .arg( + Arg::new("exe") + .long("exe") + .short('e') + .value_hint(ValueHint::ExecutablePath), + ) + .arg( + Arg::new("cmd_name") + .long("cmd-name") + .value_hint(ValueHint::CommandName), + ) + .arg( + Arg::new("cmd") + .long("cmd") + .short('c') + .value_hint(ValueHint::CommandString), + ) + .arg( + Arg::new("command_with_args") + .num_args(1..) + // AppSettings::TrailingVarArg is required to use ValueHint::CommandWithArguments + .trailing_var_arg(true) + .value_hint(ValueHint::CommandWithArguments), + ) + .arg( + Arg::new("user") + .short('u') + .long("user") + .value_hint(ValueHint::Username), + ) + .arg( + Arg::new("host") + .long("host") + .value_hint(ValueHint::Hostname), + ) + .arg(Arg::new("url").long("url").value_hint(ValueHint::Url)) + .arg( + Arg::new("email") + .long("email") + .value_hint(ValueHint::EmailAddress), + ); + + Command::new("completion") + .arg( + Arg::new("generator") + .long("generate") + .value_parser(value_parser!(Shell)), + ) + .subcommand(value_hint_command) +} + +fn print_completions(gen: G, cmd: &mut Command) { + generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout()); +} + +fn main() { + let matches = build_cli().get_matches(); + + if let Some(generator) = matches.get_one::("generator") { + let mut cmd = build_cli(); + eprintln!("Generating completion file for {}...", generator); + print_completions(*generator, &mut cmd); + } +} diff --git a/vendor/clap_complete/examples/dynamic.rs b/vendor/clap_complete/examples/dynamic.rs new file mode 100644 index 000000000..5abf2de1f --- /dev/null +++ b/vendor/clap_complete/examples/dynamic.rs @@ -0,0 +1,37 @@ +use clap::FromArgMatches; +use clap::Subcommand; + +fn command() -> clap::Command { + let cmd = clap::Command::new("dynamic") + .arg( + clap::Arg::new("input") + .long("input") + .short('i') + .value_hint(clap::ValueHint::FilePath), + ) + .arg( + clap::Arg::new("format") + .long("format") + .short('F') + .value_parser(["json", "yaml", "toml"]), + ) + .args_conflicts_with_subcommands(true); + clap_complete::dynamic::bash::CompleteCommand::augment_subcommands(cmd) +} + +fn main() { + let cmd = command(); + let matches = cmd.get_matches(); + if let Ok(completions) = + clap_complete::dynamic::bash::CompleteCommand::from_arg_matches(&matches) + { + completions.complete(&mut command()); + } else { + println!("{:#?}", matches); + } +} + +#[test] +fn verify_cli() { + command().debug_assert(); +} diff --git a/vendor/clap_complete/src/dynamic.rs b/vendor/clap_complete/src/dynamic.rs new file mode 100644 index 000000000..929841ec8 --- /dev/null +++ b/vendor/clap_complete/src/dynamic.rs @@ -0,0 +1,551 @@ +//! Complete commands within shells + +/// Complete commands within bash +pub mod bash { + use std::ffi::OsString; + use std::io::Write; + + use unicode_xid::UnicodeXID; + + #[derive(clap::Subcommand)] + #[command(hide = true)] + #[allow(missing_docs)] + #[derive(Clone, Debug)] + pub enum CompleteCommand { + /// Register shell completions for this program + Complete(CompleteArgs), + } + + #[derive(clap::Args)] + #[command(group = clap::ArgGroup::new("complete").multiple(true).conflicts_with("register"))] + #[allow(missing_docs)] + #[derive(Clone, Debug)] + pub struct CompleteArgs { + /// Path to write completion-registration to + #[arg(long, required = true)] + register: Option, + + #[arg( + long, + required = true, + value_name = "COMP_CWORD", + hide_short_help = true, + group = "complete" + )] + index: Option, + + #[arg(long, hide_short_help = true, group = "complete")] + ifs: Option, + + #[arg( + long = "type", + required = true, + hide_short_help = true, + group = "complete" + )] + comp_type: Option, + + #[arg(long, hide_short_help = true, group = "complete")] + space: bool, + + #[arg( + long, + conflicts_with = "space", + hide_short_help = true, + group = "complete" + )] + no_space: bool, + + #[arg(raw = true, hide_short_help = true, group = "complete")] + comp_words: Vec, + } + + impl CompleteCommand { + /// Process the completion request + pub fn complete(&self, cmd: &mut clap::Command) -> std::convert::Infallible { + self.try_complete(cmd).unwrap_or_else(|e| e.exit()); + std::process::exit(0) + } + + /// Process the completion request + pub fn try_complete(&self, cmd: &mut clap::Command) -> clap::error::Result<()> { + debug!("CompleteCommand::try_complete: {:?}", self); + let CompleteCommand::Complete(args) = self; + if let Some(out_path) = args.register.as_deref() { + let mut buf = Vec::new(); + let name = cmd.get_name(); + let bin = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name()); + register(name, [bin], bin, &Behavior::default(), &mut buf)?; + if out_path == std::path::Path::new("-") { + std::io::stdout().write_all(&buf)?; + } else if out_path.is_dir() { + let out_path = out_path.join(file_name(name)); + std::fs::write(out_path, buf)?; + } else { + std::fs::write(out_path, buf)?; + } + } else { + let index = args.index.unwrap_or_default(); + let comp_type = args.comp_type.unwrap_or_default(); + let space = match (args.space, args.no_space) { + (true, false) => Some(true), + (false, true) => Some(false), + (true, true) => { + unreachable!("`--space` and `--no-space` set, clap should prevent this") + } + (false, false) => None, + } + .unwrap(); + let current_dir = std::env::current_dir().ok(); + let completions = complete( + cmd, + args.comp_words.clone(), + index, + comp_type, + space, + current_dir.as_deref(), + )?; + + let mut buf = Vec::new(); + for (i, completion) in completions.iter().enumerate() { + if i != 0 { + write!(&mut buf, "{}", args.ifs.as_deref().unwrap_or("\n"))?; + } + write!(&mut buf, "{}", completion.to_string_lossy())?; + } + std::io::stdout().write_all(&buf)?; + } + + Ok(()) + } + } + + /// The recommended file name for the registration code + pub fn file_name(name: &str) -> String { + format!("{}.bash", name) + } + + /// Define the completion behavior + pub enum Behavior { + /// Bare bones behavior + Minimal, + /// Fallback to readline behavior when no matches are generated + Readline, + /// Customize bash's completion behavior + Custom(String), + } + + impl Default for Behavior { + fn default() -> Self { + Self::Readline + } + } + + /// Generate code to register the dynamic completion + pub fn register( + name: &str, + executables: impl IntoIterator>, + completer: &str, + behavior: &Behavior, + buf: &mut dyn Write, + ) -> Result<(), std::io::Error> { + let escaped_name = name.replace('-', "_"); + debug_assert!( + escaped_name.chars().all(|c| c.is_xid_continue()), + "`name` must be an identifier, got `{}`", + escaped_name + ); + let mut upper_name = escaped_name.clone(); + upper_name.make_ascii_uppercase(); + + let executables = executables + .into_iter() + .map(|s| shlex::quote(s.as_ref()).into_owned()) + .collect::>() + .join(" "); + + let options = match behavior { + Behavior::Minimal => "-o nospace -o bashdefault", + Behavior::Readline => "-o nospace -o default -o bashdefault", + Behavior::Custom(c) => c.as_str(), + }; + + let completer = shlex::quote(completer); + + let script = r#" +_clap_complete_NAME() { + local IFS=$'\013' + local SUPPRESS_SPACE=0 + if compopt +o nospace 2> /dev/null; then + SUPPRESS_SPACE=1 + fi + if [[ ${SUPPRESS_SPACE} == 1 ]]; then + SPACE_ARG="--no-space" + else + SPACE_ARG="--space" + fi + COMPREPLY=( $("COMPLETER" complete --index ${COMP_CWORD} --type ${COMP_TYPE} ${SPACE_ARG} --ifs="$IFS" -- "${COMP_WORDS[@]}") ) + if [[ $? != 0 ]]; then + unset COMPREPLY + elif [[ $SUPPRESS_SPACE == 1 ]] && [[ "${COMPREPLY-}" =~ [=/:]$ ]]; then + compopt -o nospace + fi +} +complete OPTIONS -F _clap_complete_NAME EXECUTABLES +"# + .replace("NAME", &escaped_name) + .replace("EXECUTABLES", &executables) + .replace("OPTIONS", options) + .replace("COMPLETER", &completer) + .replace("UPPER", &upper_name); + + writeln!(buf, "{}", script)?; + Ok(()) + } + + /// Type of completion attempted that caused a completion function to be called + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + #[non_exhaustive] + pub enum CompType { + /// Normal completion + Normal, + /// List completions after successive tabs + Successive, + /// List alternatives on partial word completion + Alternatives, + /// List completions if the word is not unmodified + Unmodified, + /// Menu completion + Menu, + } + + impl clap::ValueEnum for CompType { + fn value_variants<'a>() -> &'a [Self] { + &[ + Self::Normal, + Self::Successive, + Self::Alternatives, + Self::Unmodified, + Self::Menu, + ] + } + fn to_possible_value(&self) -> ::std::option::Option { + match self { + Self::Normal => { + let value = "9"; + debug_assert_eq!(b'\t'.to_string(), value); + Some( + clap::builder::PossibleValue::new(value) + .alias("normal") + .help("Normal completion"), + ) + } + Self::Successive => { + let value = "63"; + debug_assert_eq!(b'?'.to_string(), value); + Some( + clap::builder::PossibleValue::new(value) + .alias("successive") + .help("List completions after successive tabs"), + ) + } + Self::Alternatives => { + let value = "33"; + debug_assert_eq!(b'!'.to_string(), value); + Some( + clap::builder::PossibleValue::new(value) + .alias("alternatives") + .help("List alternatives on partial word completion"), + ) + } + Self::Unmodified => { + let value = "64"; + debug_assert_eq!(b'@'.to_string(), value); + Some( + clap::builder::PossibleValue::new(value) + .alias("unmodified") + .help("List completions if the word is not unmodified"), + ) + } + Self::Menu => { + let value = "37"; + debug_assert_eq!(b'%'.to_string(), value); + Some( + clap::builder::PossibleValue::new(value) + .alias("menu") + .help("Menu completion"), + ) + } + } + } + } + + impl Default for CompType { + fn default() -> Self { + Self::Normal + } + } + + /// Complete the command specified + pub fn complete( + cmd: &mut clap::Command, + args: Vec, + arg_index: usize, + _comp_type: CompType, + _trailing_space: bool, + current_dir: Option<&std::path::Path>, + ) -> Result, std::io::Error> { + cmd.build(); + + let raw_args = clap_lex::RawArgs::new(args.into_iter()); + let mut cursor = raw_args.cursor(); + let mut target_cursor = raw_args.cursor(); + raw_args.seek( + &mut target_cursor, + clap_lex::SeekFrom::Start(arg_index as u64), + ); + // As we loop, `cursor` will always be pointing to the next item + raw_args.next_os(&mut target_cursor); + + // TODO: Multicall support + if !cmd.is_no_binary_name_set() { + raw_args.next_os(&mut cursor); + } + + let mut current_cmd = &*cmd; + let mut pos_index = 1; + let mut is_escaped = false; + while let Some(arg) = raw_args.next(&mut cursor) { + if cursor == target_cursor { + return complete_arg(&arg, current_cmd, current_dir, pos_index, is_escaped); + } + + debug!( + "complete::next: Begin parsing '{:?}' ({:?})", + arg.to_value_os(), + arg.to_value_os().as_raw_bytes() + ); + + if let Ok(value) = arg.to_value() { + if let Some(next_cmd) = current_cmd.find_subcommand(value) { + current_cmd = next_cmd; + pos_index = 0; + continue; + } + } + + if is_escaped { + pos_index += 1; + } else if arg.is_escape() { + is_escaped = true; + } else if let Some(_long) = arg.to_long() { + } else if let Some(_short) = arg.to_short() { + } else { + pos_index += 1; + } + } + + Err(std::io::Error::new( + std::io::ErrorKind::Other, + "No completion generated", + )) + } + + fn complete_arg( + arg: &clap_lex::ParsedArg<'_>, + cmd: &clap::Command, + current_dir: Option<&std::path::Path>, + pos_index: usize, + is_escaped: bool, + ) -> Result, std::io::Error> { + debug!( + "complete_arg: arg={:?}, cmd={:?}, current_dir={:?}, pos_index={}, is_escaped={}", + arg, + cmd.get_name(), + current_dir, + pos_index, + is_escaped + ); + let mut completions = Vec::new(); + + if !is_escaped { + if let Some((flag, value)) = arg.to_long() { + if let Ok(flag) = flag { + if let Some(value) = value { + if let Some(arg) = cmd.get_arguments().find(|a| a.get_long() == Some(flag)) + { + completions.extend( + complete_arg_value(value.to_str().ok_or(value), arg, current_dir) + .into_iter() + .map(|os| { + // HACK: Need better `OsStr` manipulation + format!("--{}={}", flag, os.to_string_lossy()).into() + }), + ) + } + } else { + completions.extend( + crate::generator::utils::longs_and_visible_aliases(cmd) + .into_iter() + .filter_map(|f| { + f.starts_with(flag).then(|| format!("--{}", f).into()) + }), + ); + } + } + } else if arg.is_escape() || arg.is_stdio() || arg.is_empty() { + // HACK: Assuming knowledge of is_escape / is_stdio + completions.extend( + crate::generator::utils::longs_and_visible_aliases(cmd) + .into_iter() + .map(|f| format!("--{}", f).into()), + ); + } + + if arg.is_empty() || arg.is_stdio() || arg.is_short() { + // HACK: Assuming knowledge of is_stdio + completions.extend( + crate::generator::utils::shorts_and_visible_aliases(cmd) + .into_iter() + // HACK: Need better `OsStr` manipulation + .map(|f| format!("{}{}", arg.to_value_os().to_str_lossy(), f).into()), + ); + } + } + + if let Some(positional) = cmd + .get_positionals() + .find(|p| p.get_index() == Some(pos_index)) + { + completions.extend(complete_arg_value(arg.to_value(), positional, current_dir)); + } + + if let Ok(value) = arg.to_value() { + completions.extend(complete_subcommand(value, cmd)); + } + + Ok(completions) + } + + fn complete_arg_value( + value: Result<&str, &clap_lex::RawOsStr>, + arg: &clap::Arg, + current_dir: Option<&std::path::Path>, + ) -> Vec { + let mut values = Vec::new(); + debug!("complete_arg_value: arg={:?}, value={:?}", arg, value); + + if let Some(possible_values) = crate::generator::utils::possible_values(arg) { + if let Ok(value) = value { + values.extend(possible_values.into_iter().filter_map(|p| { + let name = p.get_name(); + name.starts_with(value).then(|| name.into()) + })); + } + } else { + let value_os = match value { + Ok(value) => clap_lex::RawOsStr::from_str(value), + Err(value_os) => value_os, + }; + match arg.get_value_hint() { + clap::ValueHint::Other => { + // Should not complete + } + clap::ValueHint::Unknown | clap::ValueHint::AnyPath => { + values.extend(complete_path(value_os, current_dir, |_| true)); + } + clap::ValueHint::FilePath => { + values.extend(complete_path(value_os, current_dir, |p| p.is_file())); + } + clap::ValueHint::DirPath => { + values.extend(complete_path(value_os, current_dir, |p| p.is_dir())); + } + clap::ValueHint::ExecutablePath => { + use is_executable::IsExecutable; + values.extend(complete_path(value_os, current_dir, |p| p.is_executable())); + } + clap::ValueHint::CommandName + | clap::ValueHint::CommandString + | clap::ValueHint::CommandWithArguments + | clap::ValueHint::Username + | clap::ValueHint::Hostname + | clap::ValueHint::Url + | clap::ValueHint::EmailAddress => { + // No completion implementation + } + _ => { + // Safe-ish fallback + values.extend(complete_path(value_os, current_dir, |_| true)); + } + } + values.sort(); + } + + values + } + + fn complete_path( + value_os: &clap_lex::RawOsStr, + current_dir: Option<&std::path::Path>, + is_wanted: impl Fn(&std::path::Path) -> bool, + ) -> Vec { + let mut completions = Vec::new(); + + let current_dir = match current_dir { + Some(current_dir) => current_dir, + None => { + // Can't complete without a `current_dir` + return Vec::new(); + } + }; + let (existing, prefix) = value_os + .split_once('\\') + .unwrap_or((clap_lex::RawOsStr::from_str(""), value_os)); + let root = current_dir.join(existing.to_os_str()); + debug!("complete_path: root={:?}, prefix={:?}", root, prefix); + + for entry in std::fs::read_dir(&root) + .ok() + .into_iter() + .flatten() + .filter_map(Result::ok) + { + let raw_file_name = clap_lex::RawOsString::new(entry.file_name()); + if !raw_file_name.starts_with_os(prefix) { + continue; + } + + if entry.metadata().map(|m| m.is_dir()).unwrap_or(false) { + let path = entry.path(); + let mut suggestion = pathdiff::diff_paths(&path, current_dir).unwrap_or(path); + suggestion.push(""); // Ensure trailing `/` + completions.push(suggestion.as_os_str().to_owned()); + } else { + let path = entry.path(); + if is_wanted(&path) { + let suggestion = pathdiff::diff_paths(&path, current_dir).unwrap_or(path); + completions.push(suggestion.as_os_str().to_owned()); + } + } + } + + completions + } + + fn complete_subcommand(value: &str, cmd: &clap::Command) -> Vec { + debug!( + "complete_subcommand: cmd={:?}, value={:?}", + cmd.get_name(), + value + ); + + let mut scs = crate::generator::utils::all_subcommands(cmd) + .into_iter() + .filter(|x| x.0.starts_with(value)) + .map(|x| OsString::from(&x.0)) + .collect::>(); + scs.sort(); + scs.dedup(); + scs + } +} diff --git a/vendor/clap_complete/src/generator/mod.rs b/vendor/clap_complete/src/generator/mod.rs index 2d00c281d..c025697ed 100644 --- a/vendor/clap_complete/src/generator/mod.rs +++ b/vendor/clap_complete/src/generator/mod.rs @@ -83,10 +83,8 @@ pub trait Generator { /// /// ``` /// // src/cli.rs -/// -/// use clap::{Command, Arg}; -/// -/// pub fn build_cli() -> Command<'static> { +/// # use clap::{Command, Arg, ArgAction}; +/// pub fn build_cli() -> Command { /// Command::new("compl") /// .about("Tests completions") /// .arg(Arg::new("file") @@ -95,7 +93,7 @@ pub trait Generator { /// .about("tests things") /// .arg(Arg::new("case") /// .long("case") -/// .takes_value(true) +/// .action(ArgAction::Set) /// .help("the case to test"))) /// } /// ``` @@ -195,7 +193,7 @@ where /// /// # Examples /// -/// Assuming a separate `cli.rs` like the [example above](generate_to()), +/// Assuming a separate `cli.rs` like the [`generate_to` example](generate_to()), /// we can let users generate a completion script using a command: /// /// ```ignore @@ -236,7 +234,7 @@ where G: Generator, S: Into, { - cmd._build_all(); + cmd.build(); gen.generate(cmd, buf) } diff --git a/vendor/clap_complete/src/generator/utils.rs b/vendor/clap_complete/src/generator/utils.rs index b8aaa4bd5..ca76d189b 100644 --- a/vendor/clap_complete/src/generator/utils.rs +++ b/vendor/clap_complete/src/generator/utils.rs @@ -19,10 +19,7 @@ pub fn all_subcommands(cmd: &Command) -> Vec<(String, String)> { /// Finds the subcommand [`clap::Command`] from the given [`clap::Command`] with the given path. /// /// **NOTE:** `path` should not contain the root `bin_name`. -pub fn find_subcommand_with_path<'help, 'cmd>( - p: &'cmd Command<'help>, - path: Vec<&str>, -) -> &'cmd Command<'help> { +pub fn find_subcommand_with_path<'cmd>(p: &'cmd Command, path: Vec<&str>) -> &'cmd Command { let mut cmd = p; for sc in path { @@ -42,10 +39,6 @@ pub fn subcommands(p: &Command) -> Vec<(String, String)> { let mut subcmds = vec![]; - if !p.has_subcommands() { - return subcmds; - } - for sc in p.get_subcommands() { let sc_bin_name = sc.get_bin_name().unwrap(); @@ -62,7 +55,7 @@ pub fn subcommands(p: &Command) -> Vec<(String, String)> { } /// Gets all the short options, their visible aliases and flags of a [`clap::Command`]. -/// Includes `h` and `V` depending on the [`clap::AppSettings`]. +/// Includes `h` and `V` depending on the [`clap::Command`] settings. pub fn shorts_and_visible_aliases(p: &Command) -> Vec { debug!("shorts: name={}", p.get_name()); @@ -87,7 +80,7 @@ pub fn shorts_and_visible_aliases(p: &Command) -> Vec { } /// Gets all the long options, their visible aliases and flags of a [`clap::Command`]. -/// Includes `help` and `version` depending on the [`clap::AppSettings`]. +/// Includes `help` and `version` depending on the [`clap::Command`] settings. pub fn longs_and_visible_aliases(p: &Command) -> Vec { debug!("longs: name={}", p.get_name()); @@ -117,22 +110,33 @@ pub fn longs_and_visible_aliases(p: &Command) -> Vec { } /// Gets all the flags of a [`clap::Command`](Command). -/// Includes `help` and `version` depending on the [`clap::AppSettings`]. -pub fn flags<'help>(p: &Command<'help>) -> Vec> { +/// Includes `help` and `version` depending on the [`clap::Command`] settings. +pub fn flags(p: &Command) -> Vec { debug!("flags: name={}", p.get_name()); p.get_arguments() - .filter(|a| !a.is_takes_value_set() && !a.is_positional()) + .filter(|a| !a.get_num_args().expect("built").takes_values() && !a.is_positional()) .cloned() .collect() } +/// Get the possible values for completion +pub fn possible_values(a: &Arg) -> Option> { + if !a.get_num_args().expect("built").takes_values() { + None + } else { + a.get_value_parser() + .possible_values() + .map(|pvs| pvs.collect()) + } +} + #[cfg(test)] mod tests { use super::*; use clap::Arg; - use pretty_assertions::assert_eq; + use clap::ArgAction; - fn common_app() -> Command<'static> { + fn common_app() -> Command { Command::new("myapp") .subcommand( Command::new("test").subcommand(Command::new("config")).arg( @@ -141,6 +145,7 @@ mod tests { .short_alias('c') .visible_short_alias('p') .long("file") + .action(ArgAction::SetTrue) .visible_alias("path"), ), ) @@ -148,17 +153,17 @@ mod tests { .bin_name("my-cmd") } - fn built() -> Command<'static> { + fn built() -> Command { let mut cmd = common_app(); - cmd._build_all(); + cmd.build(); cmd } - fn built_with_version() -> Command<'static> { + fn built_with_version() -> Command { let mut cmd = common_app().version("3.0"); - cmd._build_all(); + cmd.build(); cmd } @@ -188,6 +193,12 @@ mod tests { ("help".to_string(), "my-cmd help".to_string()), ("config".to_string(), "my-cmd test config".to_string()), ("help".to_string(), "my-cmd test help".to_string()), + ("config".to_string(), "my-cmd test help config".to_string()), + ("help".to_string(), "my-cmd test help help".to_string()), + ("test".to_string(), "my-cmd help test".to_string()), + ("hello".to_string(), "my-cmd help hello".to_string()), + ("help".to_string(), "my-cmd help help".to_string()), + ("config".to_string(), "my-cmd help test config".to_string()), ] ); } diff --git a/vendor/clap_complete/src/lib.rs b/vendor/clap_complete/src/lib.rs index a22ff9ac3..80fead4a5 100644 --- a/vendor/clap_complete/src/lib.rs +++ b/vendor/clap_complete/src/lib.rs @@ -22,11 +22,11 @@ //! ## Example //! //! ```rust,no_run -//! use clap::{Command, AppSettings, Arg, ValueHint}; +//! use clap::{Command, Arg, ValueHint, value_parser, ArgAction}; //! use clap_complete::{generate, Generator, Shell}; //! use std::io; //! -//! fn build_cli() -> Command<'static> { +//! fn build_cli() -> Command { //! Command::new("example") //! .arg(Arg::new("file") //! .help("some input file") @@ -35,7 +35,8 @@ //! .arg( //! Arg::new("generator") //! .long("generate") -//! .possible_values(Shell::possible_values()), +//! .action(ArgAction::Set) +//! .value_parser(value_parser!(Shell)), //! ) //! } //! @@ -46,7 +47,7 @@ //! fn main() { //! let matches = build_cli().get_matches(); //! -//! if let Ok(generator) = matches.value_of_t::("generator") { +//! if let Some(generator) = matches.get_one::("generator").copied() { //! let mut cmd = build_cli(); //! eprintln!("Generating completion file for {}...", generator); //! print_completions(generator, &mut cmd); @@ -68,3 +69,6 @@ pub use generator::generate; pub use generator::generate_to; pub use generator::Generator; pub use shells::Shell; + +#[cfg(feature = "unstable-dynamic")] +pub mod dynamic; diff --git a/vendor/clap_complete/src/macros.rs b/vendor/clap_complete/src/macros.rs index def051434..bc6979460 100644 --- a/vendor/clap_complete/src/macros.rs +++ b/vendor/clap_complete/src/macros.rs @@ -10,8 +10,8 @@ macro_rules! w { #[cfg(feature = "debug")] macro_rules! debug { ($($arg:tt)*) => { - print!("[{:>w$}] \t", module_path!(), w = 28); - println!($($arg)*) + eprint!("[{:>w$}] \t", module_path!(), w = 28); + eprintln!($($arg)*) } } diff --git a/vendor/clap_complete/src/shells/bash.rs b/vendor/clap_complete/src/shells/bash.rs index 08bf1190c..e110537e5 100644 --- a/vendor/clap_complete/src/shells/bash.rs +++ b/vendor/clap_complete/src/shells/bash.rs @@ -31,8 +31,8 @@ impl Generator for Bash { for i in ${{COMP_WORDS[@]}} do - case \"${{i}}\" in - \"$1\") + case \"${{cmd}},${{i}}\" in + \",$1\") cmd=\"{cmd}\" ;;{subcmds} *) @@ -75,26 +75,52 @@ complete -F _{name} -o bashdefault -o default {name} fn all_subcommands(cmd: &Command) -> String { debug!("all_subcommands"); - let mut subcmds = vec![String::new()]; - let mut scs = utils::all_subcommands(cmd) - .iter() - .map(|x| x.0.clone()) - .collect::>(); - - scs.sort(); - scs.dedup(); + fn add_command( + parent_fn_name: &str, + cmd: &Command, + subcmds: &mut Vec<(String, String, String)>, + ) { + let fn_name = format!( + "{parent_fn_name}__{cmd_name}", + parent_fn_name = parent_fn_name, + cmd_name = cmd.get_name().to_string().replace('-', "__") + ); + subcmds.push(( + parent_fn_name.to_string(), + cmd.get_name().to_string(), + fn_name.clone(), + )); + for alias in cmd.get_visible_aliases() { + subcmds.push(( + parent_fn_name.to_string(), + alias.to_string(), + fn_name.clone(), + )); + } + for subcmd in cmd.get_subcommands() { + add_command(&fn_name, subcmd, subcmds); + } + } + let mut subcmds = vec![]; + let fn_name = cmd.get_name().replace('-', "__"); + for subcmd in cmd.get_subcommands() { + add_command(&fn_name, subcmd, &mut subcmds); + } + subcmds.sort(); - subcmds.extend(scs.iter().map(|sc| { - format!( - "{name}) - cmd+=\"__{fn_name}\" + let mut cases = vec![String::new()]; + for (parent_fn_name, name, fn_name) in subcmds { + cases.push(format!( + "{parent_fn_name},{name}) + cmd=\"{fn_name}\" ;;", - name = sc, - fn_name = sc.replace('-', "__") - ) - })); + parent_fn_name = parent_fn_name, + name = name, + fn_name = fn_name, + )); + } - subcmds.join("\n ") + cases.join("\n ") } fn subcommand_details(cmd: &Command) -> String { @@ -125,9 +151,9 @@ fn subcommand_details(cmd: &Command) -> String { return 0 ;;", subcmd = sc.replace('-', "__"), - sc_opts = all_options_for_path(cmd, &*sc), + sc_opts = all_options_for_path(cmd, sc), level = sc.split("__").map(|_| 1).sum::(), - opts_details = option_details_for_path(cmd, &*sc) + opts_details = option_details_for_path(cmd, sc) ) })); @@ -174,12 +200,12 @@ fn option_details_for_path(cmd: &Command, path: &str) -> String { fn vals_for(o: &Arg) -> String { debug!("vals_for: o={}", o.get_id()); - if let Some(vals) = o.get_possible_values() { + if let Some(vals) = crate::generator::utils::possible_values(o) { format!( "$(compgen -W \"{}\" -- \"${{cur}}\")", vals.iter() - .filter(|pv| pv.is_hide_set()) - .map(PossibleValue::get_name) + .filter(|pv| !pv.is_hide_set()) + .map(|n| n.get_name()) .collect::>() .join(" ") ) @@ -201,7 +227,7 @@ fn all_options_for_path(cmd: &Command, path: &str) -> String { write!(&mut opts, "--{} ", long).unwrap(); } for pos in p.get_positionals() { - if let Some(vals) = pos.get_possible_values() { + if let Some(vals) = utils::possible_values(pos) { for value in vals { write!(&mut opts, "{} ", value.get_name()).unwrap(); } diff --git a/vendor/clap_complete/src/shells/elvish.rs b/vendor/clap_complete/src/shells/elvish.rs index 959372087..07da28348 100644 --- a/vendor/clap_complete/src/shells/elvish.rs +++ b/vendor/clap_complete/src/shells/elvish.rs @@ -1,5 +1,6 @@ use std::io::Write; +use clap::builder::StyledStr; use clap::*; use crate::generator::{utils, Generator}; @@ -19,8 +20,7 @@ impl Generator for Elvish { .get_bin_name() .expect("crate::generate should have set the bin_name"); - let mut names = vec![]; - let subcommands_cases = generate_inner(cmd, "", &mut names); + let subcommands_cases = generate_inner(cmd, ""); let result = format!( r#" @@ -59,18 +59,14 @@ fn escape_string(string: &str) -> String { string.replace('\'', "''") } -fn get_tooltip(help: Option<&str>, data: T) -> String { +fn get_tooltip(help: Option<&StyledStr>, data: T) -> String { match help { - Some(help) => escape_string(help), + Some(help) => escape_string(&help.to_string()), _ => data.to_string(), } } -fn generate_inner<'help>( - p: &Command<'help>, - previous_command_name: &str, - names: &mut Vec<&'help str>, -) -> String { +fn generate_inner(p: &Command, previous_command_name: &str) -> String { debug!("generate_inner"); let command_name = if previous_command_name.is_empty() { @@ -134,7 +130,7 @@ fn generate_inner<'help>( ); for subcommand in p.get_subcommands() { - let subcommand_subcommands_cases = generate_inner(subcommand, &command_name, names); + let subcommand_subcommands_cases = generate_inner(subcommand, &command_name); subcommands_cases.push_str(&subcommand_subcommands_cases); } diff --git a/vendor/clap_complete/src/shells/fish.rs b/vendor/clap_complete/src/shells/fish.rs index 9b516084b..fd2f3a4f8 100644 --- a/vendor/clap_complete/src/shells/fish.rs +++ b/vendor/clap_complete/src/shells/fish.rs @@ -27,8 +27,13 @@ impl Generator for Fish { } // Escape string inside single quotes -fn escape_string(string: &str) -> String { - string.replace('\\', "\\\\").replace('\'', "\\'") +fn escape_string(string: &str, escape_comma: bool) -> String { + let string = string.replace('\\', "\\\\").replace('\'', "\\'"); + if escape_comma { + string.replace(',', "\\,") + } else { + string + } } fn gen_fish_inner( @@ -88,12 +93,13 @@ fn gen_fish_inner( if let Some(longs) = option.get_long_and_visible_aliases() { for long in longs { - template.push_str(format!(" -l {}", escape_string(long)).as_str()); + template.push_str(format!(" -l {}", escape_string(long, false)).as_str()); } } if let Some(data) = option.get_help() { - template.push_str(format!(" -d '{}'", escape_string(data)).as_str()); + template + .push_str(format!(" -d '{}'", escape_string(&data.to_string(), false)).as_str()); } template.push_str(value_completion(option).as_str()); @@ -113,12 +119,13 @@ fn gen_fish_inner( if let Some(longs) = flag.get_long_and_visible_aliases() { for long in longs { - template.push_str(format!(" -l {}", escape_string(long)).as_str()); + template.push_str(format!(" -l {}", escape_string(long, false)).as_str()); } } if let Some(data) = flag.get_help() { - template.push_str(format!(" -d '{}'", escape_string(data)).as_str()); + template + .push_str(format!(" -d '{}'", escape_string(&data.to_string(), false)).as_str()); } buffer.push_str(template.as_str()); @@ -132,7 +139,7 @@ fn gen_fish_inner( template.push_str(format!(" -a \"{}\"", &subcommand.get_name()).as_str()); if let Some(data) = subcommand.get_about() { - template.push_str(format!(" -d '{}'", escape_string(data)).as_str()) + template.push_str(format!(" -d '{}'", escape_string(&data.to_string(), false)).as_str()) } buffer.push_str(template.as_str()); @@ -148,11 +155,11 @@ fn gen_fish_inner( } fn value_completion(option: &Arg) -> String { - if !option.is_takes_value_set() { + if !option.get_num_args().expect("built").takes_values() { return "".to_string(); } - if let Some(data) = option.get_possible_values() { + if let Some(data) = crate::generator::utils::possible_values(option) { // We return the possible values with their own empty description e.g. {a\t,b\t} // this makes sure that a and b don't get the description of the option or argument format!( @@ -163,8 +170,8 @@ fn value_completion(option: &Arg) -> String { } else { Some(format!( "{}\t{}", - escape_string(value.get_name()).as_str(), - escape_string(value.get_help().unwrap_or_default()).as_str() + escape_string(value.get_name(), true).as_str(), + escape_string(&value.get_help().unwrap_or_default().to_string(), true) )) }) .collect::>() diff --git a/vendor/clap_complete/src/shells/powershell.rs b/vendor/clap_complete/src/shells/powershell.rs index d35e61c7d..0d3a2a55f 100644 --- a/vendor/clap_complete/src/shells/powershell.rs +++ b/vendor/clap_complete/src/shells/powershell.rs @@ -1,5 +1,6 @@ use std::io::Write; +use clap::builder::StyledStr; use clap::*; use crate::generator::{utils, Generator}; @@ -19,8 +20,7 @@ impl Generator for PowerShell { .get_bin_name() .expect("crate::generate should have set the bin_name"); - let mut names = vec![]; - let subcommands_cases = generate_inner(cmd, "", &mut names); + let subcommands_cases = generate_inner(cmd, ""); let result = format!( r#" @@ -64,18 +64,14 @@ fn escape_string(string: &str) -> String { string.replace('\'', "''") } -fn get_tooltip(help: Option<&str>, data: T) -> String { +fn get_tooltip(help: Option<&StyledStr>, data: T) -> String { match help { - Some(help) => escape_string(help), + Some(help) => escape_string(&help.to_string()), _ => data.to_string(), } } -fn generate_inner<'help>( - p: &Command<'help>, - previous_command_name: &str, - names: &mut Vec<&'help str>, -) -> String { +fn generate_inner(p: &Command, previous_command_name: &str) -> String { debug!("generate_inner"); let command_name = if previous_command_name.is_empty() { @@ -170,7 +166,7 @@ fn generate_inner<'help>( ); for subcommand in p.get_subcommands() { - let subcommand_subcommands_cases = generate_inner(subcommand, &command_name, names); + let subcommand_subcommands_cases = generate_inner(subcommand, &command_name); subcommands_cases.push_str(&subcommand_subcommands_cases); } diff --git a/vendor/clap_complete/src/shells/shell.rs b/vendor/clap_complete/src/shells/shell.rs index 63063bb7c..f6e70f575 100644 --- a/vendor/clap_complete/src/shells/shell.rs +++ b/vendor/clap_complete/src/shells/shell.rs @@ -1,7 +1,9 @@ use std::fmt::Display; +use std::path::Path; use std::str::FromStr; -use clap::{ArgEnum, PossibleValue}; +use clap::builder::PossibleValue; +use clap::ValueEnum; use crate::shells; use crate::Generator; @@ -22,15 +24,6 @@ pub enum Shell { Zsh, } -impl Shell { - /// Report all `possible_values` - pub fn possible_values() -> impl Iterator> { - Shell::value_variants() - .iter() - .filter_map(ArgEnum::to_possible_value) - } -} - impl Display for Shell { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.to_possible_value() @@ -54,7 +47,7 @@ impl FromStr for Shell { } // Hand-rolled so it can work even when `derive` feature is disabled -impl ArgEnum for Shell { +impl ValueEnum for Shell { fn value_variants<'a>() -> &'a [Self] { &[ Shell::Bash, @@ -65,7 +58,7 @@ impl ArgEnum for Shell { ] } - fn to_possible_value<'a>(&self) -> Option> { + fn to_possible_value<'a>(&self) -> Option { Some(match self { Shell::Bash => PossibleValue::new("bash"), Shell::Elvish => PossibleValue::new("elvish"), @@ -97,3 +90,66 @@ impl Generator for Shell { } } } + +impl Shell { + /// Parse a shell from a path to the executable for the shell + /// + /// # Examples + /// + /// ``` + /// use clap_complete::shells::Shell; + /// + /// assert_eq!(Shell::from_shell_path("/bin/bash"), Some(Shell::Bash)); + /// assert_eq!(Shell::from_shell_path("/usr/bin/zsh"), Some(Shell::Zsh)); + /// assert_eq!(Shell::from_shell_path("/opt/my_custom_shell"), None); + /// ``` + pub fn from_shell_path>(path: P) -> Option { + parse_shell_from_path(path.as_ref()) + } + + /// Determine the user's current shell from the environment + /// + /// This will read the SHELL environment variable and try to determine which shell is in use + /// from that. + /// + /// If SHELL is not set, then on windows, it will default to powershell, and on + /// other OSes it will return `None`. + /// + /// If SHELL is set, but contains a value that doesn't correspond to one of the supported shell + /// types, then return `None`. + /// + /// # Example: + /// + /// ```no_run + /// # use clap::Command; + /// use clap_complete::{generate, shells::Shell}; + /// # fn build_cli() -> Command { + /// # Command::new("compl") + /// # } + /// let mut cmd = build_cli(); + /// generate(Shell::from_env().unwrap_or(Shell::Bash), &mut cmd, "myapp", &mut std::io::stdout()); + /// ``` + pub fn from_env() -> Option { + if let Some(env_shell) = std::env::var_os("SHELL") { + Shell::from_shell_path(env_shell) + } else if cfg!(windows) { + Some(Shell::PowerShell) + } else { + None + } + } +} + +// use a separate function to avoid having to monomorphize the entire function due +// to from_shell_path being generic +fn parse_shell_from_path(path: &Path) -> Option { + let name = path.file_stem()?.to_str()?; + match name { + "bash" => Some(Shell::Bash), + "zsh" => Some(Shell::Zsh), + "fish" => Some(Shell::Fish), + "elvish" => Some(Shell::Elvish), + "powershell" | "powershell_ise" => Some(Shell::PowerShell), + _ => None, + } +} diff --git a/vendor/clap_complete/src/shells/zsh.rs b/vendor/clap_complete/src/shells/zsh.rs index 2b64739ce..580de77a2 100644 --- a/vendor/clap_complete/src/shells/zsh.rs +++ b/vendor/clap_complete/src/shells/zsh.rs @@ -153,12 +153,10 @@ fn subcommands_of(p: &Command) -> String { let text = format!( "'{name}:{help}' \\", name = name, - help = escape_help(subcommand.get_about().unwrap_or("")) + help = escape_help(&subcommand.get_about().unwrap_or_default().to_string()) ); - if !text.is_empty() { - ret.push(text); - } + ret.push(text); } // The subcommands @@ -234,7 +232,7 @@ fn get_subcommands_of(parent: &Command) -> String { ); let mut segments = vec![format!("({})", name)]; let subcommand_args = get_args_of( - parser_of(parent, &*bin_name).expect(INTERNAL_ERROR_MSG), + parser_of(parent, bin_name).expect(INTERNAL_ERROR_MSG), Some(parent), ); @@ -243,7 +241,7 @@ fn get_subcommands_of(parent: &Command) -> String { } // Get the help text of all child subcommands. - let children = get_subcommands_of(parser_of(parent, &*bin_name).expect(INTERNAL_ERROR_MSG)); + let children = get_subcommands_of(parser_of(parent, bin_name).expect(INTERNAL_ERROR_MSG)); if !children.is_empty() { segments.push(children); @@ -280,13 +278,10 @@ esac", // // Given the bin_name "a b c" and the Command for "a" this returns the "c" Command. // Given the bin_name "a b c" and the Command for "b" this returns the "c" Command. -fn parser_of<'help, 'cmd>( - parent: &'cmd Command<'help>, - bin_name: &str, -) -> Option<&'cmd Command<'help>> { +fn parser_of<'cmd>(parent: &'cmd Command, bin_name: &str) -> Option<&'cmd Command> { debug!("parser_of: p={}, bin_name={}", parent.get_name(), bin_name); - if bin_name == parent.get_bin_name().unwrap_or(&String::new()) { + if bin_name == parent.get_bin_name().unwrap_or_default() { return Some(parent); } @@ -359,7 +354,7 @@ fn get_args_of(parent: &Command, p_global: Option<&Command>) -> String { // Uses either `possible_vals` or `value_hint` to give hints about possible argument values fn value_completion(arg: &Arg) -> Option { - if let Some(values) = &arg.get_possible_values() { + if let Some(values) = crate::generator::utils::possible_values(arg) { if values .iter() .any(|value| !value.is_hide_set() && value.get_help().is_some()) @@ -375,7 +370,8 @@ fn value_completion(arg: &Arg) -> Option { Some(format!( r#"{name}\:"{tooltip}""#, name = escape_value(value.get_name()), - tooltip = value.get_help().map(escape_help).unwrap_or_default() + tooltip = + escape_help(&value.get_help().unwrap_or_default().to_string()), )) } }) @@ -388,7 +384,7 @@ fn value_completion(arg: &Arg) -> Option { values .iter() .filter(|pv| !pv.is_hide_set()) - .map(PossibleValue::get_name) + .map(|n| n.get_name()) .collect::>() .join(" ") )) @@ -448,10 +444,10 @@ fn write_opts_of(p: &Command, p_global: Option<&Command>) -> String { for o in p.get_opts() { debug!("write_opts_of:iter: o={}", o.get_id()); - let help = o.get_help().map_or(String::new(), escape_help); + let help = escape_help(&o.get_help().unwrap_or_default().to_string()); let conflicts = arg_conflicts(p, o, p_global); - let multiple = if o.is_multiple_occurrences_set() { + let multiple = if let ArgAction::Count | ArgAction::Append = o.get_action() { "*" } else { "" @@ -465,10 +461,7 @@ fn write_opts_of(p: &Command, p_global: Option<&Command>) -> String { Some(val) => format!(":{}:{}", vn, val), None => format!(":{}: ", vn), }; - let vc = match o.get_num_vals() { - Some(num_vals) => vc.repeat(num_vals), - None => vc, - }; + let vc = vc.repeat(o.get_num_args().expect("built").min_values()); if let Some(shorts) = o.get_short_and_visible_aliases() { for short in shorts { @@ -551,10 +544,10 @@ fn write_flags_of(p: &Command, p_global: Option<&Command>) -> String { for f in utils::flags(p) { debug!("write_flags_of:iter: f={}", f.get_id()); - let help = f.get_help().map_or(String::new(), escape_help); + let help = escape_help(&f.get_help().unwrap_or_default().to_string()); let conflicts = arg_conflicts(p, &f, p_global); - let multiple = if f.is_multiple_occurrences_set() { + let multiple = if let ArgAction::Count | ArgAction::Append = f.get_action() { "*" } else { "" @@ -632,7 +625,8 @@ fn write_positionals_of(p: &Command) -> String { for arg in p.get_positionals() { debug!("write_positionals_of:iter: arg={}", arg.get_id()); - let cardinality = if arg.is_multiple_values_set() || arg.is_multiple_occurrences_set() { + let num_args = arg.get_num_args().expect("built"); + let cardinality = if num_args.max_values() > 1 { "*:" } else if !arg.is_required_set() { ":" @@ -646,12 +640,13 @@ fn write_positionals_of(p: &Command) -> String { name = arg.get_id(), help = arg .get_help() - .map_or("".to_owned(), |v| " -- ".to_owned() + v) + .map(|s| s.to_string()) + .map_or("".to_owned(), |v| " -- ".to_owned() + &v) .replace('[', "\\[") .replace(']', "\\]") .replace('\'', "'\\''") .replace(':', "\\:"), - value_completion = value_completion(arg).unwrap_or_else(|| "".to_string()) + value_completion = value_completion(arg).unwrap_or_default() ); debug!("write_positionals_of:iter: Wrote...{}", a); -- cgit v1.2.3