1
0
mirror of https://github.com/CLIUtils/CLI11.git synced 2025-05-04 14:23:51 +00:00

style: pre-commit.ci fixes

This commit is contained in:
pre-commit-ci[bot] 2025-05-02 14:47:49 +00:00
parent 433ee18d0c
commit 94f08d9c20
3 changed files with 27 additions and 20 deletions

View File

@ -914,8 +914,11 @@ option_groups. These are:
is not allowed to have a single character short option starting with the same is not allowed to have a single character short option starting with the same
character as a single dash long form name; for example, `-s` and `-single` are character as a single dash long form name; for example, `-s` and `-single` are
not allowed in the same application. not allowed in the same application.
- `.allow_subcommand_prefix_matching()`:🚧 If this modifier is enabled, unambiguious prefix portions of a subcommand will match. - `.allow_subcommand_prefix_matching()`:🚧 If this modifier is enabled,
For example `upgrade_package` would match on `upgrade_`, `upg`, `u` as long as no other subcommand would also match. It also disallows subcommand names that are full prefixes of another subcommand. unambiguious prefix portions of a subcommand will match. For example
`upgrade_package` would match on `upgrade_`, `upg`, `u` as long as no other
subcommand would also match. It also disallows subcommand names that are full
prefixes of another subcommand.
- `.fallthrough()`: Allow extra unmatched options and positionals to "fall - `.fallthrough()`: Allow extra unmatched options and positionals to "fall
through" and be matched on a parent option. Subcommands by default are allowed through" and be matched on a parent option. Subcommands by default are allowed
to "fall through" as in they will first attempt to match on the current to "fall through" as in they will first attempt to match on the current

View File

@ -159,8 +159,11 @@ calls another command called "`git-thing`" with the remaining options intact.
### prefix matching ### prefix matching
A modifier is available for subcommand matching, `->allow_subcommand_prefix_matching()`. if this is enabled unambiguious prefix portions of a subcommand will match. A modifier is available for subcommand matching,
For Example `upgrade_package` would match on `upgrade_`, `upg`, `u` as long as no other subcommand would also match. It also disallows subcommand names that are full prefixes of another subcommand. `->allow_subcommand_prefix_matching()`. if this is enabled unambiguious prefix
portions of a subcommand will match. For Example `upgrade_package` would match
on `upgrade_`, `upg`, `u` as long as no other subcommand would also match. It
also disallows subcommand names that are full prefixes of another subcommand.
### Silent subcommands ### Silent subcommands

View File

@ -9,23 +9,25 @@
#include <CLI/CLI.hpp> #include <CLI/CLI.hpp>
#include <iostream> #include <iostream>
#include <limits> #include <limits>
#include <numeric>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <numeric>
// Levenshtein distance function code generated by chatgpt/copilot // Levenshtein distance function code generated by chatgpt/copilot
std::size_t levenshteinDistance(const std::string& s1, const std::string& s2) { std::size_t levenshteinDistance(const std::string &s1, const std::string &s2) {
std::size_t len1 = s1.size(), len2 = s2.size(); std::size_t len1 = s1.size(), len2 = s2.size();
if (len1 == 0) return len2; if(len1 == 0)
if (len2 == 0) return len1; return len2;
if(len2 == 0)
return len1;
std::vector<std::size_t> prev(len2 + 1), curr(len2 + 1); std::vector<std::size_t> prev(len2 + 1), curr(len2 + 1);
std::iota(prev.begin(), prev.end(), 0); // Fill prev with {0, 1, ..., len2} std::iota(prev.begin(), prev.end(), 0); // Fill prev with {0, 1, ..., len2}
for (std::size_t ii = 1; ii <= len1; ++ii) { for(std::size_t ii = 1; ii <= len1; ++ii) {
curr[0] = ii; curr[0] = ii;
for (std::size_t jj = 1; jj <= len2; ++jj) { for(std::size_t jj = 1; jj <= len2; ++jj) {
// If characters match, no substitution cost; otherwise, cost is 1. // If characters match, no substitution cost; otherwise, cost is 1.
std::size_t cost = (s1[ii - 1] == s2[jj - 1]) ? 0 : 1; std::size_t cost = (s1[ii - 1] == s2[jj - 1]) ? 0 : 1;
@ -34,7 +36,7 @@ std::size_t levenshteinDistance(const std::string& s1, const std::string& s2) {
// - Inserting a character into `s1` (curr[jj - 1] + 1) // - Inserting a character into `s1` (curr[jj - 1] + 1)
// - Substituting a character (prev[jj - 1] + cost) // - Substituting a character (prev[jj - 1] + cost)
curr[jj] = std::min({ prev[jj] + 1, curr[jj - 1] + 1, prev[jj - 1] + cost }); curr[jj] = std::min({prev[jj] + 1, curr[jj - 1] + 1, prev[jj - 1] + cost});
} }
prev = std::exchange(curr, prev); // Swap vectors efficiently prev = std::exchange(curr, prev); // Swap vectors efficiently
} }
@ -58,7 +60,7 @@ std::pair<std::string, std::size_t> findClosestMatch(const std::string &input,
} }
void addSubcommandCloseMatchDetection(CLI::App *app, std::size_t minDistance = 3) { void addSubcommandCloseMatchDetection(CLI::App *app, std::size_t minDistance = 3) {
//if extras are not allowed then there will be no remaining // if extras are not allowed then there will be no remaining
app->allow_extras(true); app->allow_extras(true);
// generate a list of subcommand names // generate a list of subcommand names
auto subs = app->get_subcommands(nullptr); auto subs = app->get_subcommands(nullptr);
@ -73,7 +75,7 @@ void addSubcommandCloseMatchDetection(CLI::App *app, std::size_t minDistance = 3
} }
} }
// add a callback that runs before a final callback and loops over the remaining arguments for subcommands // add a callback that runs before a final callback and loops over the remaining arguments for subcommands
app->parse_complete_callback([&app, minDistance,list]() { app->parse_complete_callback([&app, minDistance, list]() {
auto extras = app->remaining(); auto extras = app->remaining();
if(extras.empty()) { if(extras.empty()) {
return; return;
@ -93,7 +95,7 @@ void addSubcommandCloseMatchDetection(CLI::App *app, std::size_t minDistance = 3
/** This example demonstrates the use of close match detection to detect invalid commands that are close matches to /** This example demonstrates the use of close match detection to detect invalid commands that are close matches to
* existing ones * existing ones
*/ */
int main(int argc, const char* argv[]) { int main(int argc, const char *argv[]) {
int value{0}; int value{0};
CLI::App app{"cose string App"}; CLI::App app{"cose string App"};
@ -105,14 +107,13 @@ int main(int argc, const char* argv[]) {
app.add_subcommand("upgrade", ""); app.add_subcommand("upgrade", "");
app.add_subcommand("remove", ""); app.add_subcommand("remove", "");
app.add_subcommand("test", ""); app.add_subcommand("test", "");
//enable close matching for subcommands // enable close matching for subcommands
addSubcommandCloseMatchDetection(&app, 5); addSubcommandCloseMatchDetection(&app, 5);
CLI11_PARSE(app, argc, argv); CLI11_PARSE(app, argc, argv);
auto subs=app.get_subcommands(); auto subs = app.get_subcommands();
for (const auto& sub : subs) for(const auto &sub : subs) {
{ std::cout << sub->get_name() << "\n";
std::cout<<sub->get_name()<<"\n";
} }
return 0; return 0;
} }