| 61 | } |
| 62 | |
| 63 | void addSubcommandCloseMatchDetection(CLI::App *app, std::size_t minDistance = 3) { |
| 64 | // if extras are not allowed then there will be no remaining |
| 65 | app->allow_extras(true); |
| 66 | // generate a list of subcommand names |
| 67 | auto subs = app->get_subcommands(nullptr); |
| 68 | CLI::results_t list; |
| 69 | for(const auto *sub : subs) { |
| 70 | if(!sub->get_name().empty()) { |
| 71 | list.emplace_back(sub->get_name()); |
| 72 | } |
| 73 | const auto &aliases = sub->get_aliases(); |
| 74 | if(!aliases.empty()) { |
| 75 | list.insert(list.end(), aliases.begin(), aliases.end()); |
| 76 | } |
| 77 | } |
| 78 | // add a callback that runs before a final callback and loops over the remaining arguments for subcommands |
| 79 | app->parse_complete_callback([app, minDistance, list = std::move(list)]() { |
| 80 | for(auto &extra : app->remaining()) { |
| 81 | if(!extra.empty() && extra.front() != '-') { |
| 82 | auto closest = findClosestMatch(extra, list); |
| 83 | if(closest.second <= minDistance) { |
| 84 | std::cout << "unmatched command \"" << extra << "\", closest match is " << closest.first << "\n"; |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | }); |
| 89 | } |
| 90 | |
| 91 | /** This example demonstrates the use of close match detection to detect invalid commands that are close matches to |
| 92 | * existing ones |
no test coverage detected