]> granicus.if.org Git - icinga2/commitdiff
Fix auto-completion for arguments
authorGunnar Beutner <gunnar.beutner@netways.de>
Fri, 10 Oct 2014 08:07:56 +0000 (10:07 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Fri, 10 Oct 2014 08:07:56 +0000 (10:07 +0200)
refs #7246

etc/bash_completion.d/icinga2
icinga-app/icinga.cpp
lib/base/clicommand.cpp
lib/base/clicommand.hpp

index 0af84850ccecbd029fb0426b6c15236579fb87ce..425939210d4c426371f44128e0c6731a5c4c828b 100644 (file)
@@ -3,7 +3,7 @@ _icinga2()
   local cur opts
   opts="${COMP_WORDS[*]}"
   cur="${COMP_WORDS[COMP_CWORD]}"
-  COMPREPLY=($(icinga2 --autocomplete ${COMP_WORDS[*]:1} < /dev/null))
+  COMPREPLY=($(icinga2 --autocomplete $COMP_CWORD ${COMP_WORDS[*]:1} < /dev/null))
   return 0
 }
 
index 771ff466572c8ef4b21411e0a36d4d11543cba59..bc46a8be4f4b27b81bb1d58a34e1668135a660cb 100644 (file)
@@ -47,9 +47,20 @@ int Main(void)
        int argc = Application::GetArgC();
        char **argv = Application::GetArgV();
 
+       bool autocomplete = false;
+       int autoindex = 0;
+
+       if (argc >= 4 && strcmp(argv[1], "--autocomplete") == 0) {
+               autocomplete = true;
+               autoindex = Convert::ToLong(argv[2]);
+               argc -= 3;
+               argv += 3;
+       }
+
        Application::SetStartTime(Utility::GetTime());
 
-       Application::SetResourceLimits();
+       if (!autocomplete)
+               Application::SetResourceLimits();
 
        /* Set thread title. */
        Utility::SetThreadName("Main Thread", false);
@@ -114,12 +125,10 @@ int Main(void)
                ("library,l", po::value<std::vector<std::string> >(), "load a library")
                ("include,I", po::value<std::vector<std::string> >(), "add include search directory")
                ("log-level,x", po::value<std::string>(), "specify the log level for the console log")
-               ("no-stack-rlimit", "used internally, do not specify manually")
-               ("autocomplete", "auto-complete arguments");
+               ("no-stack-rlimit", "used internally, do not specify manually");
        
        String cmdname;
        CLICommand::Ptr command;
-       bool autocomplete;
        po::variables_map vm;
 
        try {
@@ -230,7 +239,7 @@ int Main(void)
                if (!command || vm.count("help")) {
                        if (!command) {
                                std::cout << std::endl;
-                               CLICommand::ShowCommands(argc, argv, NULL, false);
+                               CLICommand::ShowCommands(argc, argv, NULL);
                        }
        
                        std::cout << std::endl
@@ -244,7 +253,7 @@ int Main(void)
        int rc = 1;
 
        if (autocomplete) {
-               CLICommand::ShowCommands(argc, argv, &desc, true);
+               CLICommand::ShowCommands(argc, argv, &desc, true, autoindex);
                rc = 0;
        } else if (command)
                rc = command->Run(vm);
index 01e7186354a059d0a423f8eba16fca5379fcaa0a..3856ac36a6cb0420bc8ab82a1e5ad54d83bb38dd 100644 (file)
@@ -64,12 +64,10 @@ RegisterCLICommandHelper::RegisterCLICommandHelper(const String& name, const CLI
 }
 
 bool CLICommand::ParseCommand(int argc, char **argv, po::options_description& desc, po::variables_map& vm,
-    String& cmdname, CLICommand::Ptr& command, bool& autocomplete)
+    String& cmdname, CLICommand::Ptr& command, bool autocomplete)
 {
        boost::mutex::scoped_lock lock(l_RegistryMutex);
 
-       autocomplete = false;
-       
        typedef std::map<std::vector<String>, CLICommand::Ptr>::value_type CLIKeyValue;
 
        std::vector<String> best_match;
@@ -80,11 +78,6 @@ bool CLICommand::ParseCommand(int argc, char **argv, po::options_description& de
 
                for (int i = 0, k = 1; i < vname.size() && k < argc; i++, k++) {
                        if (strcmp(argv[k], "--no-stack-rlimit") == 0 || strcmp(argv[k], "--autocomplete") == 0) {
-                               if (strcmp(argv[k], "--autocomplete") == 0) {
-                                       autocomplete = true;
-                                       return false;
-                               }
-
                                i--;
                                continue;
                        }
@@ -111,16 +104,20 @@ found_command:
        
        if (command)    
                command->InitParameters(ldesc);
-               
+
        desc.add(ldesc);
-       
+
+       if (autocomplete)
+               return true;
+
        po::store(po::parse_command_line(argc - arg_end, argv + arg_end, desc), vm);
        po::notify(vm);
 
        return true;
 }
 
-void CLICommand::ShowCommands(int argc, char **argv, po::options_description *desc, bool autocomplete)
+void CLICommand::ShowCommands(int argc, char **argv, po::options_description *desc,
+    bool autocomplete, int autoindex)
 {
        boost::mutex::scoped_lock lock(l_RegistryMutex);
 
@@ -156,12 +153,17 @@ void CLICommand::ShowCommands(int argc, char **argv, po::options_description *de
                }
        }
 
-       if (!autocomplete)
+       String aword;
+
+       if (autocomplete) {
+               if (autoindex < argc)
+                       aword = argv[autoindex];
+       } else
                std::cout << "Supported commands: " << std::endl;
-       
+
        BOOST_FOREACH(const CLIKeyValue& kv, l_Registry) {
                const std::vector<String>& vname = kv.first;
+
                if (vname.size() < best_match.size())
                        continue;
  
@@ -178,20 +180,18 @@ void CLICommand::ShowCommands(int argc, char **argv, po::options_description *de
                        continue;
 
                if (autocomplete) {
-                       if (best_match.size() < vname.size()) {
-                               String cname = vname[best_match.size()];
-                               String pname;
-                               
-                               if (arg_begin + best_match.size() + 1 < argc)
-                                       pname = argv[arg_begin + best_match.size() + 1];
-                               
-                               if (cname.Find(pname) == 0)
-                                       std::cout << vname[best_match.size()] << " ";
+                       String cname;
+
+                       if (autoindex - 1 < vname.size()) {
+                               cname = vname[autoindex - 1];
+
+                               if (cname.Find(aword) == 0)
+                                       std::cout << cname << "\n";
                        }
                } else
                        std::cout << "  * " << boost::algorithm::join(vname, " ") << " (" << kv.second->GetShortDescription() << ")" << std::endl;
        }
-       
+
        if (command && autocomplete) {
                po::options_description ldesc("Command options");
                
@@ -202,10 +202,9 @@ void CLICommand::ShowCommands(int argc, char **argv, po::options_description *de
 
                BOOST_FOREACH(const shared_ptr<po::option_description>& odesc, desc->options()) {
                        String cname = "--" + odesc->long_name();
-                       String pname = argv[argc - 1];
-                       
-                       if (cname.Find(pname) == 0)
-                               std::cout << cname << " ";
+
+                       if (cname.Find(aword) == 0)
+                               std::cout << cname << "\n";
                }
        }
 
index ee7d1c6d61c17111afe966088f5344ed31f3f90f..b2f52dd7c515c4e30b320308ef040349361a7b7a 100644 (file)
@@ -49,8 +49,8 @@ public:
        static void Unregister(const std::vector<String>& name);
 
        static bool ParseCommand(int argc, char **argv, boost::program_options::options_description& desc,
-           boost::program_options::variables_map& vm, String& cmdname, CLICommand::Ptr& command, bool& autocomplete);
-       static void ShowCommands(int argc, char **argv, boost::program_options::options_description *desc, bool autocomplete);
+           boost::program_options::variables_map& vm, String& cmdname, CLICommand::Ptr& command, bool autocomplete);
+       static void ShowCommands(int argc, char **argv, boost::program_options::options_description *desc = NULL, bool autocomplete = false, int autoindex = -1);
 };
 
 /**