Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/command/ArgumentCompletionFunctions.cc @ 7234

Last change on this file since 7234 was 7234, checked in by landauf, 14 years ago

the unhide command now also supports auto-completion for the hidden commands

  • Property svn:eol-style set to native
File size: 11.1 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "ArgumentCompletionFunctions.h"
30
31#include <map>
32#include <boost/version.hpp>
33#include <boost/filesystem.hpp>
34
35#include "util/Convert.h"
36#include "util/StringUtils.h"
37#include "core/Identifier.h"
38#include "core/ConfigFileManager.h"
39#include "core/ConfigValueContainer.h"
40#include "CommandExecutor.h"
41#include "ConsoleCommand.h"
42#include "TclThreadManager.h"
43
44// Boost 1.36 has some issues with deprecated functions that have been omitted
45#if (BOOST_VERSION == 103600)
46#  define BOOST_LEAF_FUNCTION filename
47#else
48#  define BOOST_LEAF_FUNCTION leaf
49#endif
50
51namespace orxonox
52{
53    namespace autocompletion
54    {
55        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(fallback)()
56        {
57            return ArgumentCompletionList();
58        }
59
60        namespace detail
61        {
62            bool groupIsVisible(const std::map<std::string, _ConsoleCommand*>& group, bool bOnlyShowHidden)
63            {
64                for (std::map<std::string, _ConsoleCommand*>::const_iterator it_command = group.begin(); it_command != group.end(); ++it_command)
65                    if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden)
66                        return true;
67
68                return false;
69            }
70
71            ArgumentCompletionList _groupsandcommands(bool bOnlyShowHidden)
72            {
73                ArgumentCompletionList groupList;
74
75                const std::map<std::string, std::map<std::string, _ConsoleCommand*> >& commands = _ConsoleCommand::getCommands();
76                for (std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = commands.begin(); it_group != commands.end(); ++it_group)
77                    if (groupIsVisible(it_group->second, bOnlyShowHidden) && it_group->first != "")
78                        groupList.push_back(ArgumentCompletionListElement(it_group->first, getLowercase(it_group->first)));
79
80                std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = commands.find("");
81                if (it_group != commands.end())
82                {
83                    groupList.push_back(ArgumentCompletionListElement("", "", "\n"));
84
85                    for (std::map<std::string, _ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command)
86                        if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden)
87                            groupList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first)));
88                }
89
90                return groupList;
91            }
92
93            ArgumentCompletionList _subcommands(const std::string& fragment, const std::string& group, bool bOnlyShowHidden)
94            {
95                ArgumentCompletionList commandList;
96
97                std::string groupLC = getLowercase(group);
98
99                std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommands().begin();
100                for ( ; it_group != _ConsoleCommand::getCommands().end(); ++it_group)
101                    if (getLowercase(it_group->first) == groupLC)
102                        break;
103
104                if (it_group != _ConsoleCommand::getCommands().end())
105                {
106                    for (std::map<std::string, _ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command)
107                        if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden)
108                            commandList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first)));
109                }
110
111                return commandList;
112            }
113        }
114
115        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(groupsandcommands)()
116        {
117            return detail::_groupsandcommands(false);
118        }
119
120        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(subcommands)(const std::string& fragment, const std::string& group)
121        {
122            return detail::_subcommands(fragment, group, false);
123        }
124
125        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(command)(const std::string& fragment)
126        {
127            CommandEvaluation evaluation = CommandExecutor::evaluate(fragment);
128            const std::string& hint = evaluation.hint();
129
130            if (evaluation.getPossibleArguments().size() > 0)
131            {
132                return evaluation.getPossibleArguments();
133            }
134            else
135            {
136                ArgumentCompletionList list;
137                list.push_back(ArgumentCompletionListElement("", "", hint));
138                return list;
139            }
140        }
141
142        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(hiddencommand)(const std::string& fragment)
143        {
144            SubString tokens(fragment, " ", SubString::WhiteSpaces, false, '\\', true, '"', true, '(', ')', true, '\0');
145
146            if (tokens.size() == 0)
147                return detail::_groupsandcommands(true);
148
149            if (_ConsoleCommand::getCommandLC(getLowercase(tokens[0])))
150                return ARGUMENT_COMPLETION_FUNCTION_CALL(command)(fragment);
151
152            if (tokens.size() == 1)
153            {
154                std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommands().find(tokens[0]);
155                if (it_group != _ConsoleCommand::getCommands().end())
156                    return detail::_subcommands(fragment, tokens[0], true);
157                else
158                    return detail::_groupsandcommands(true);
159            }
160
161            if (_ConsoleCommand::getCommandLC(getLowercase(tokens[0]), getLowercase(tokens[1])))
162                return ARGUMENT_COMPLETION_FUNCTION_CALL(command)(fragment);
163
164            return ArgumentCompletionList();
165        }
166
167        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(files)(const std::string& fragment)
168        {
169            ArgumentCompletionList dirlist;
170            ArgumentCompletionList filelist;
171
172            try
173            {
174                boost::filesystem::path input(fragment);
175                boost::filesystem::path startdirectory(input.branch_path());
176
177                if (!boost::filesystem::exists(startdirectory))
178                {
179                    startdirectory = ".";
180                }
181#ifdef ORXONOX_PLATFORM_WINDOWS
182                else
183                {
184                    const std::string& dir = startdirectory.string();
185                    if (dir.size() > 0 && dir[dir.size() - 1] == ':')
186                        startdirectory = dir + '/';
187                }
188#endif
189
190                boost::filesystem::directory_iterator file(startdirectory);
191                boost::filesystem::directory_iterator end;
192
193                while (file != end)
194                {
195                    if (boost::filesystem::is_directory(*file))
196                        dirlist.push_back(ArgumentCompletionListElement(file->string() + '/', getLowercase(file->string()) + '/', file->BOOST_LEAF_FUNCTION() + '/'));
197                    else
198                        filelist.push_back(ArgumentCompletionListElement(file->string(), getLowercase(file->string()), file->BOOST_LEAF_FUNCTION()));
199                    ++file;
200                }
201            }
202            catch (...) {}
203
204            filelist.insert(filelist.begin(), dirlist.begin(), dirlist.end());
205            return filelist;
206        }
207
208        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingssections)()
209        {
210            ArgumentCompletionList sectionList;
211
212            const std::set<std::string>& names = SettingsConfigFile::getInstance().getSectionNames();
213            for (std::set<std::string>::const_iterator it = names.begin(); it != names.end(); ++it)
214                sectionList.push_back(ArgumentCompletionListElement(*it, getLowercase(*it)));
215
216            return sectionList;
217        }
218
219        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsentries)(const std::string& fragment, const std::string& section)
220        {
221            ArgumentCompletionList entryList;
222            SettingsConfigFile& settings = SettingsConfigFile::getInstance();
223            const std::string& sectionLC = getLowercase(section);
224
225            SettingsConfigFile::ContainerMap::const_iterator upper = settings.getContainerUpperBound(sectionLC);
226            for (SettingsConfigFile::ContainerMap::const_iterator it = settings.getContainerLowerBound(sectionLC); it != upper; ++it)
227                entryList.push_back(ArgumentCompletionListElement(it->second.second->getName(), it->second.first));
228
229            return entryList;
230        }
231
232        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsvalue)(const std::string& fragment, const std::string& entry, const std::string& section)
233        {
234            ArgumentCompletionList oldValue;
235            SettingsConfigFile& settings = SettingsConfigFile::getInstance();
236            const std::string& sectionLC = getLowercase(section);
237            const std::string& entryLC = getLowercase(entry);
238
239            SettingsConfigFile::ContainerMap::const_iterator upper = settings.getContainerUpperBound(sectionLC);
240            for (SettingsConfigFile::ContainerMap::const_iterator it = settings.getContainerLowerBound(sectionLC); it != upper; ++it)
241            {
242                if (it->second.first == entryLC)
243                {
244                    const std::string& valuestring = it->second.second->toString();
245                    oldValue.push_back(ArgumentCompletionListElement(valuestring, getLowercase(valuestring), "Old value: " + valuestring));
246                }
247            }
248
249            return oldValue;
250        }
251
252        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(tclthreads)()
253        {
254            std::list<unsigned int> threadnumbers = TclThreadManager::getInstance().getThreadList();
255            ArgumentCompletionList threads;
256
257            for (std::list<unsigned int>::const_iterator it = threadnumbers.begin(); it != threadnumbers.end(); ++it)
258                threads.push_back(ArgumentCompletionListElement(multi_cast<std::string>(*it)));
259
260            return threads;
261        }
262    }
263}
Note: See TracBrowser for help on using the repository browser.