From 4b983b8f035dbd854edc3fd50c767d913bf775ad Mon Sep 17 00:00:00 2001 From: Pavel Belikov Date: Sat, 23 Dec 2017 21:07:26 +0300 Subject: add examples --- CMakeLists.txt | 8 +++ README.md | 7 +++ examples/bash_completion.sh | 13 +++++ examples/completion.cxx | 27 ++++++++++ examples/gitlike.cxx | 129 ++++++++++++++++++++++++++++++++++++++++++++ gitlike.cxx | 129 -------------------------------------------- 6 files changed, 184 insertions(+), 129 deletions(-) create mode 100644 examples/bash_completion.sh create mode 100644 examples/completion.cxx create mode 100644 examples/gitlike.cxx delete mode 100644 gitlike.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 322e8d1..d0aaa69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,14 @@ add_executable(argstest-multiple-inclusion test/multiple_inclusion_1.cxx test/mu target_link_libraries(argstest-multiple-inclusion args) set_property(TARGET argstest-multiple-inclusion PROPERTY CXX_STANDARD 11) +add_executable(gitlike examples/gitlike.cxx) +target_link_libraries(gitlike args) +set_property(TARGET gitlike PROPERTY CXX_STANDARD 11) + +add_executable(completion examples/completion.cxx) +target_link_libraries(completion args) +set_property(TARGET completion PROPERTY CXX_STANDARD 11) + enable_testing() add_test(NAME "test" COMMAND argstest) add_test(NAME "test-multiple-inclusion" COMMAND argstest-multiple-inclusion) diff --git a/README.md b/README.md index f3a35d8..5327549 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ It: * Allows one value flag to take a specific number of values (like `--foo first second`, where --foo slurps both arguments). * Allows you to have value flags only optionally accept values +* Provides autocompletion for bash # What does it not do? @@ -179,10 +180,16 @@ int main(int argc, char **argv) { args::ArgumentParser parser("This is a test program.", "This goes after the options."); args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); + args::CompletionFlag completion(parser, {"complete"}); try { parser.ParseCLI(argc, argv); } + catch (args::Completion e) + { + std::cout << e.what(); + return 0; + } catch (args::Help) { std::cout << parser; diff --git a/examples/bash_completion.sh b/examples/bash_completion.sh new file mode 100644 index 0000000..54937ad --- /dev/null +++ b/examples/bash_completion.sh @@ -0,0 +1,13 @@ +_args() { + _init_completion -n 2> /dev/null + local program comparg + + program="${COMP_WORDS[0]}" + comparg="--complete" # replace this with your flag + + COMPREPLY=($("$program" "$comparg" bash "$COMP_CWORD" "${COMP_WORDS[@]}" 2> /dev/null)) + [[ $COMPREPLY ]] && return + _filedir +} + +complete -F _args completion diff --git a/examples/completion.cxx b/examples/completion.cxx new file mode 100644 index 0000000..3122c30 --- /dev/null +++ b/examples/completion.cxx @@ -0,0 +1,27 @@ +/* Copyright © 2016-2017 Taylor C. Richberger and Pavel Belikov + * This code is released under the license described in the LICENSE file + */ + +#include "args.hxx" +#include + +int main(int argc, const char **argv) +{ + args::ArgumentParser p("parser"); + args::CompletionFlag c(p, {"complete"}); + args::ValueFlag f(p, "name", "description", {'f', "foo"}, "abc"); + args::ValueFlag b(p, "name", "description", {'b', "bar"}, "abc"); + args::MapFlag m(p, "mappos", "mappos", {'m', "map"}, {{"1",1}, {"2", 2}}); + args::Positional pos(p, "name", "desc"); + + try + { + p.ParseCLI(argc, argv); + } + catch (args::Completion &e) + { + std::cout << e.what(); + } + + return 0; +} diff --git a/examples/gitlike.cxx b/examples/gitlike.cxx new file mode 100644 index 0000000..aa0e20e --- /dev/null +++ b/examples/gitlike.cxx @@ -0,0 +1,129 @@ +/* Copyright © 2016 Taylor C. Richberger + * This code is released under the license described in the LICENSE file + */ + +#include +#include +#include +#include + +void Init(const std::string &progname, std::vector::const_iterator beginargs, std::vector::const_iterator endargs); +void Add(const std::string &progname, std::vector::const_iterator beginargs, std::vector::const_iterator endargs); + +using commandtype = std::function::const_iterator, std::vector::const_iterator)>; + +int main(int argc, char **argv) +{ + std::unordered_map map{ + {"init", Init}, + {"add", Add}}; + + const std::vector args(argv + 1, argv + argc); + args::ArgumentParser parser("This is a git-like program", "Valid commands are init and add"); + args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); + parser.Prog(argv[0]); + parser.ProglinePostfix("{command options}"); + args::Flag version(parser, "version", "Show the version of this program", {"version"}); + args::ValueFlag htmlpath(parser, "html-path", "Specify the html path", {"html-path"}); + args::MapPositional command(parser, "command", "Command to execute", map); + command.KickOut(true); + try + { + auto next = parser.ParseArgs(args); + std::cout << std::boolalpha; + std::cout << "Before command options:" << std::endl; + std::cout << "Version called: " << bool{version} << std::endl; + std::cout << "html-path called: " << bool{htmlpath} << ", value: " << args::get(htmlpath) << std::endl; + if (command) + { + args::get(command)(argv[0], next, std::end(args)); + } else + { + std::cout << parser; + } + } + catch (args::Help) + { + std::cout << parser; + return 0; + } + catch (args::Error e) + { + std::cerr << e.what() << std::endl; + std::cerr << parser; + return 1; + } + return 0; +} + +void Init(const std::string &progname, std::vector::const_iterator beginargs, std::vector::const_iterator endargs) +{ + std::cout << "In Init" << std::endl; + args::ArgumentParser parser(""); + parser.Prog(progname + " init"); + args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); + args::ValueFlag templatedir(parser, "template-directory", "directory from which templates will be used", {"template"}); + args::Flag bare(parser, "bare", "create a bare repository", {"bare"}); + args::Flag quiet(parser, "quiet", "be quiet", {'q', "quiet"}); + args::Positional directory(parser, "directory", "The directory to create in", "."); + try + { + parser.ParseArgs(beginargs, endargs); + std::cout << std::boolalpha; + std::cout << "templatedir: " << bool{templatedir} << ", value: " << args::get(templatedir) << std::endl; + std::cout << "bare: " << bool{bare} << std::endl; + std::cout << "quiet: " << bool{quiet} << std::endl; + std::cout << "directory: " << bool{directory} << ", value: " << args::get(directory) << std::endl; + } + catch (args::Help) + { + std::cout << parser; + return; + } + catch (args::ParseError e) + { + std::cerr << e.what() << std::endl; + std::cerr << parser; + return; + } +} + +void Add(const std::string &progname, std::vector::const_iterator beginargs, std::vector::const_iterator endargs) +{ + std::cout << "In Add" << std::endl; + args::ArgumentParser parser(""); + parser.Prog(progname + " add"); + args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); + args::Flag dryrun(parser, "dryrun", "dry run", {'n', "dry-run"}); + args::Flag verbose(parser, "verbose", "be verbose", {'v', "verbose"}); + args::Flag refresh(parser, "refresh", "Don't add, only refresh the index", {"refresh"}); + args::PositionalList pathspec(parser, "pathspec", "pathspecs"); + try + { + parser.ParseArgs(beginargs, endargs); + std::cout << std::boolalpha; + std::cout << "dryrun: " << bool{dryrun} << std::endl;; + std::cout << "verbose: " << bool{verbose} << std::endl; + std::cout << "refresh: " << bool{refresh} << std::endl; + std::cout << "pathspec: " << bool{pathspec} << std::endl; + if (pathspec) + { + std::cout << "values: " << std::endl; + for (const auto &spec: args::get(pathspec)) + { + std::cout << " - " << spec << std::endl; + } + } + } + catch (args::Help) + { + std::cout << parser; + return; + } + catch (args::ParseError e) + { + std::cerr << e.what() << std::endl; + std::cerr << parser; + return; + } +} diff --git a/gitlike.cxx b/gitlike.cxx deleted file mode 100644 index aa0e20e..0000000 --- a/gitlike.cxx +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright © 2016 Taylor C. Richberger - * This code is released under the license described in the LICENSE file - */ - -#include -#include -#include -#include - -void Init(const std::string &progname, std::vector::const_iterator beginargs, std::vector::const_iterator endargs); -void Add(const std::string &progname, std::vector::const_iterator beginargs, std::vector::const_iterator endargs); - -using commandtype = std::function::const_iterator, std::vector::const_iterator)>; - -int main(int argc, char **argv) -{ - std::unordered_map map{ - {"init", Init}, - {"add", Add}}; - - const std::vector args(argv + 1, argv + argc); - args::ArgumentParser parser("This is a git-like program", "Valid commands are init and add"); - args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); - parser.Prog(argv[0]); - parser.ProglinePostfix("{command options}"); - args::Flag version(parser, "version", "Show the version of this program", {"version"}); - args::ValueFlag htmlpath(parser, "html-path", "Specify the html path", {"html-path"}); - args::MapPositional command(parser, "command", "Command to execute", map); - command.KickOut(true); - try - { - auto next = parser.ParseArgs(args); - std::cout << std::boolalpha; - std::cout << "Before command options:" << std::endl; - std::cout << "Version called: " << bool{version} << std::endl; - std::cout << "html-path called: " << bool{htmlpath} << ", value: " << args::get(htmlpath) << std::endl; - if (command) - { - args::get(command)(argv[0], next, std::end(args)); - } else - { - std::cout << parser; - } - } - catch (args::Help) - { - std::cout << parser; - return 0; - } - catch (args::Error e) - { - std::cerr << e.what() << std::endl; - std::cerr << parser; - return 1; - } - return 0; -} - -void Init(const std::string &progname, std::vector::const_iterator beginargs, std::vector::const_iterator endargs) -{ - std::cout << "In Init" << std::endl; - args::ArgumentParser parser(""); - parser.Prog(progname + " init"); - args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); - args::ValueFlag templatedir(parser, "template-directory", "directory from which templates will be used", {"template"}); - args::Flag bare(parser, "bare", "create a bare repository", {"bare"}); - args::Flag quiet(parser, "quiet", "be quiet", {'q', "quiet"}); - args::Positional directory(parser, "directory", "The directory to create in", "."); - try - { - parser.ParseArgs(beginargs, endargs); - std::cout << std::boolalpha; - std::cout << "templatedir: " << bool{templatedir} << ", value: " << args::get(templatedir) << std::endl; - std::cout << "bare: " << bool{bare} << std::endl; - std::cout << "quiet: " << bool{quiet} << std::endl; - std::cout << "directory: " << bool{directory} << ", value: " << args::get(directory) << std::endl; - } - catch (args::Help) - { - std::cout << parser; - return; - } - catch (args::ParseError e) - { - std::cerr << e.what() << std::endl; - std::cerr << parser; - return; - } -} - -void Add(const std::string &progname, std::vector::const_iterator beginargs, std::vector::const_iterator endargs) -{ - std::cout << "In Add" << std::endl; - args::ArgumentParser parser(""); - parser.Prog(progname + " add"); - args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"}); - args::Flag dryrun(parser, "dryrun", "dry run", {'n', "dry-run"}); - args::Flag verbose(parser, "verbose", "be verbose", {'v', "verbose"}); - args::Flag refresh(parser, "refresh", "Don't add, only refresh the index", {"refresh"}); - args::PositionalList pathspec(parser, "pathspec", "pathspecs"); - try - { - parser.ParseArgs(beginargs, endargs); - std::cout << std::boolalpha; - std::cout << "dryrun: " << bool{dryrun} << std::endl;; - std::cout << "verbose: " << bool{verbose} << std::endl; - std::cout << "refresh: " << bool{refresh} << std::endl; - std::cout << "pathspec: " << bool{pathspec} << std::endl; - if (pathspec) - { - std::cout << "values: " << std::endl; - for (const auto &spec: args::get(pathspec)) - { - std::cout << " - " << spec << std::endl; - } - } - } - catch (args::Help) - { - std::cout << parser; - return; - } - catch (args::ParseError e) - { - std::cerr << e.what() << std::endl; - std::cerr << parser; - return; - } -} -- cgit v1.2.1