# # # add_dir "tests/complete_option_names" # # add_file "tests/complete_option_names/__driver__.lua" # content [07f0ef46efdbd23bd3de46a6f0e4e84a4e62933a] # # patch "NEWS" # from [55587ed635c15b26bdf7c17d80ee30e20f5fe971] # to [e10f0e29928a08a4e7add964319d97c38fe07646] # # patch "option.cc" # from [db3f4d9546deed6864d3aa2c66575466d7e0ed47] # to [a20974f64308aca286278180d0c4259673a7b71d] # ============================================================ --- tests/complete_option_names/__driver__.lua 07f0ef46efdbd23bd3de46a6f0e4e84a4e62933a +++ tests/complete_option_names/__driver__.lua 07f0ef46efdbd23bd3de46a6f0e4e84a4e62933a @@ -0,0 +1,27 @@ +mtn_setup() + +-- check the completion of long names and cancel names +check(mtn("version", "--fu"), 0, true, false) +check(qgrep("Changes since base revision", "stdout")) + +-- if recognized correctly, --no-h should override the previously given --hidden +check(mtn("help", "--hidden", "--no-h"), 0, true, false) +check(not qgrep("benchmark_sha1", "stdout")) + +-- ensure that once the option was identified, we print +-- out its full name for diagnostics +check(mtn("version", "--fu=arg"), 1, false, true) +check(qgrep("option 'full' does not take an argument", "stderr")) + +check(mtn("help", "--no-h=arg"), 1, false, true) +check(qgrep("option 'no-hidden' does not take an argument", "stderr")) + +check(mtn("version", "-f"), 1, false, true) +check(qgrep("option 'f' has multiple ambiguous expansions", "stderr")) + +-- ensure that exact option name matches are not matched against +-- other option names which share the same prefix, like e.g. --key and --keydir +check(mtn("--key"), 1, false, true) +check(qgrep("missing argument to option 'key'", "stderr")) +check(not qgrep("option 'key' has multiple ambiguous expansions", "stderr")) + ============================================================ --- NEWS 55587ed635c15b26bdf7c17d80ee30e20f5fe971 +++ NEWS e10f0e29928a08a4e7add964319d97c38fe07646 @@ -168,6 +168,11 @@ Xxx Xxx 99 99:99:99 UTC 2010 --nostd use --no-builtin-rcfile --reallyquiet use --verbosity=-2 + - To aid command line typing, partial option names are tried to + be expanded; if the expansion leads to multiple possibilities, + all matches and an accompanying short description of the + particular expansion are displayed. + - The 'disapprove' command now accepts a revision range in addition to a single revision. ============================================================ --- option.cc db3f4d9546deed6864d3aa2c66575466d7e0ed47 +++ option.cc a20974f64308aca286278180d0c4259673a7b71d @@ -274,7 +274,7 @@ static concrete_option const & } static concrete_option const & -getopt(map const & by_name, string const & name) +getopt(map const & by_name, string & name) { // try to match the option name as a whole first, so if the user // specified "--foo" and we have "--foo" and "--foo-bar", don't @@ -283,7 +283,6 @@ getopt(map cons if (i != by_name.end()) return i->second; - // try to find the option by partial name vector candidates; for (i = by_name.begin(); i != by_name.end(); ++i) @@ -300,6 +299,7 @@ getopt(map cons i = by_name.find(candidates[0]); I(i != by_name.end()); L(FL("expanding option '%s' to '%s'") % name % candidates[0]); + name = candidates[0]; return i->second; } @@ -409,7 +409,7 @@ void concrete_option_set::from_command_l o = getopt(by_name, name); is_cancel = (name == o.cancelname); if ((!o.has_arg || is_cancel) && equals != string::npos) - throw extra_arg(is_cancel ? o.cancelname : o.longname); + throw extra_arg(name); if (o.has_arg && !is_cancel) { @@ -417,7 +417,7 @@ void concrete_option_set::from_command_l { separate_arg = true; if (i+1 == args.size()) - throw missing_arg(o.longname); + throw missing_arg(name); arg = idx(args,i+1); } else @@ -432,7 +432,7 @@ void concrete_option_set::from_command_l is_cancel = (name == o.cancelname); I(!is_cancel); if (!o.has_arg && idx(args,i)().size() != 2) - throw extra_arg(o.shortname); + throw extra_arg(name); if (o.has_arg) { @@ -440,7 +440,7 @@ void concrete_option_set::from_command_l { separate_arg = true; if (i+1 == args.size()) - throw missing_arg(o.shortname); + throw missing_arg(name); arg = idx(args,i+1); } else @@ -511,7 +511,7 @@ void concrete_option_set::from_key_value for (vector >::const_iterator i = keyvals.begin(); i != keyvals.end(); ++i) { - string const & key(i->first); + string key(i->first); arg_type const & value(arg_type(i->second, origin::user)); concrete_option o = getopt(by_name, key);