# # # patch "cmd.hh" # from [100b8bb08a126fb827acfd50e104897a4ffd8f97] # to [c160e0cdc96ccd368ee9aca2afac028408db400f] # # patch "cmd_automate.cc" # from [fb7c5ee18a2e6ac46fb93ec49ef21bb1aa6bc81f] # to [d715e6735b4a263881a587911a343aa06b339706] # # patch "commands.cc" # from [e21ce6ddd485cb7886581fe14be6d6b0616d3bf9] # to [bbd6a8914cb1fe58353d476e4f7802bc56971370] # # patch "lua_hooks.cc" # from [57900637d5588e80197752a936229e320993202f] # to [e61801cae30ad803e68f8419729619159719137a] # # patch "tests/invoke_toplevel_group/__driver__.lua" # from [659b589cfaba2f10b2256937403524a911270d43] # to [469031fb8da888896cfbd6e9e8d1e156fe78f082] # ============================================================ --- cmd.hh 100b8bb08a126fb827acfd50e104897a4ffd8f97 +++ cmd.hh c160e0cdc96ccd368ee9aca2afac028408db400f @@ -34,6 +34,7 @@ namespace commands utf8 m_primary_name; names_set m_names; command * m_parent; + bool m_is_group; bool m_hidden; utf8 m_params; utf8 m_abstract; @@ -53,6 +54,7 @@ namespace commands command(std::string const & primary_name, std::string const & other_names, command * parent, + bool is_group, bool hidden, std::string const & params, std::string const & abstract, @@ -69,6 +71,7 @@ namespace commands names_set const & names(void) const; void add_alias(const utf8 &new_name); command * parent(void) const; + bool is_group(void) const; bool hidden(void) const; virtual std::string params(void) const; virtual std::string abstract(void) const; @@ -186,8 +189,8 @@ namespace commands { class cmd_ ## C : public command \ { \ public: \ - cmd_ ## C() : command(name, aliases, parent, hidden, params, \ - abstract, desc, true, \ + cmd_ ## C() : command(name, aliases, parent, false, hidden, \ + params, abstract, desc, true, \ options::options_type() | opts, true) \ {} \ virtual void exec(app_state & app, \ @@ -211,8 +214,8 @@ void commands::cmd_ ## C::exec(app_state class cmd_ ## C : public command \ { \ public: \ - cmd_ ## C() : command(name, aliases, parent, false, "", abstract,\ - desc, true, \ + cmd_ ## C() : command(name, aliases, parent, true, false, "", \ + abstract, desc, true, \ options::options_type(), cmpl) \ {} \ virtual void exec(app_state & app, \ @@ -243,8 +246,8 @@ namespace commands { class cmd_ ## C : public command \ { \ public: \ - cmd_ ## C() : command(name, aliases, parent, false, params, \ - abstract, desc, false, \ + cmd_ ## C() : command(name, aliases, parent, false, false, \ + params, abstract, desc, false, \ options::options_type() | opts, true) \ {} \ virtual void exec(app_state & app, \ ============================================================ --- cmd_automate.cc fb7c5ee18a2e6ac46fb93ec49ef21bb1aa6bc81f +++ cmd_automate.cc d715e6735b4a263881a587911a343aa06b339706 @@ -38,7 +38,7 @@ namespace commands { string const & abstract, string const & desc, options::options_type const & opts) : - command(name, "", CMD_REF(automate), false, params, abstract, + command(name, "", CMD_REF(automate), false, false, params, abstract, desc, true, opts, false) { } ============================================================ --- commands.cc e21ce6ddd485cb7886581fe14be6d6b0616d3bf9 +++ commands.cc bbd6a8914cb1fe58353d476e4f7802bc56971370 @@ -147,6 +147,7 @@ namespace commands { command::command(std::string const & primary_name, std::string const & other_names, command * parent, + bool is_group, bool hidden, std::string const & params, std::string const & abstract, @@ -156,6 +157,7 @@ namespace commands { bool _allow_completion) : m_primary_name(utf8(primary_name)), m_parent(parent), + m_is_group(is_group), m_hidden(hidden), m_params(utf8(params)), m_abstract(utf8(abstract)), @@ -235,6 +237,12 @@ namespace commands { } bool + command::is_group(void) const + { + return m_is_group; + } + + bool command::hidden(void) const { return m_hidden; @@ -743,7 +751,8 @@ namespace commands string visibleid = join_words(vector< utf8 >(ident.begin() + 1, ident.end()))(); - N(!(!cmd->is_leaf() && cmd->parent() == CMD_REF(__root__)), + I(cmd->is_leaf() || cmd->is_group()); + N(!(cmd->is_group() && cmd->parent() == CMD_REF(__root__)), F("command '%s' is invalid; it is a group") % join_words(ident)); N(!(!cmd->is_leaf() && args.empty()), ============================================================ --- lua_hooks.cc 57900637d5588e80197752a936229e320993202f +++ lua_hooks.cc e61801cae30ad803e68f8419729619159719137a @@ -974,7 +974,7 @@ namespace commands { std::string const & desc, lua_State *L_st, std::string const & func_name) : - command(primary_name, "", CMD_REF(user), false, params, + command(primary_name, "", CMD_REF(user), false, false, params, abstract, desc, true, options::options_type() | options::opts::none, true), st(L_st), f_name(func_name) { ============================================================ --- tests/invoke_toplevel_group/__driver__.lua 659b589cfaba2f10b2256937403524a911270d43 +++ tests/invoke_toplevel_group/__driver__.lua 469031fb8da888896cfbd6e9e8d1e156fe78f082 @@ -6,6 +6,11 @@ check(string.find(output, "is invalid; i output = readfile("stderr") check(string.find(output, "is invalid; it is a group") ~= nil) +-- Invoking an empty group fails with an appropriate error message. +check(mtn("user"), 1, "", true) +output = readfile("stderr") +check(string.find(output, "is invalid; it is a group") ~= nil) + -- Command completion does not work on groups. check(mtn("revie"), 1, "", true) output = readfile("stderr")