Changeset 7374 in orxonox.OLD for trunk/src/lib/shell/shell_completion.cc
- Timestamp:
- Apr 26, 2006, 3:28:55 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/shell/shell_completion.cc
r7373 r7374 14 14 */ 15 15 16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ 16 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL 17 17 18 18 #include "shell_completion.h" 19 19 #include "shell_command_class.h" 20 20 21 #include "shell_input.h"22 21 #include "shell_command.h" 23 22 … … 26 25 #include "debug.h" 27 26 28 using namespace std; 29 30 /** 31 * @brief standard constructor 32 */ 33 ShellCompletion::ShellCompletion() 34 { } 35 36 37 /** 38 * @brief standard deconstructor 39 */ 40 ShellCompletion::~ShellCompletion () 41 { } 42 43 44 45 /** 46 * @brief autocompletes the Shell's inputLine 47 * @param input the input to complete. 48 * @returns true, if a result was found, false otherwise 49 */ 50 bool ShellCompletion::autoComplete(std::string& input) 27 namespace OrxShell 51 28 { 52 const char* completionLine; //< the inputLine we complete. 53 54 long classID; //< the classID retrieved from the Class. 55 const std::list<BaseObject*>* objectList; //< the list of Objects stored in classID 56 bool emptyComplete = false; //< if the completion input is empty string. e.g "" 57 long completeType = NullCompletion; //< the Type we'd like to complete. 58 std::string completeString; //< the string to complete. 59 60 61 PRINTF(5)("AutoComplete on input\n"); 62 this->clearCompletionList(); 63 64 // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object 65 if (input[input.size()-1] == ' ') 66 emptyComplete = true; 67 68 // CREATE INPUTS 69 SubString inputSplits(input, SubString::WhiteSpacesWithComma); 70 71 // What String will be completed 72 if (emptyComplete == true) 73 completeString = ""; 74 else 75 completeString = inputSplits.getString(inputSplits.size()-1); 76 77 // CLASS COMPLETION 78 if (inputSplits.size() == 0) 79 { 80 completeType |= ClassCompletion; 81 completeType |= AliasCompletion; 82 } 83 else if (inputSplits.size() == 1 && emptyComplete == false) 84 { 85 completeType |= ClassCompletion; 86 completeType |= AliasCompletion; 87 } 88 89 // OBJECT/FUNCTION COMPLETIONS 90 else if ((inputSplits.size() == 1 && emptyComplete == true) || 91 (inputSplits.size() == 2 && emptyComplete == false)) 92 { 93 classID = ClassList::StringToID(inputSplits.getString(0)); 94 objectList = ClassList::getList((ClassID)classID); 95 if (classID != CL_NULL) 96 completeType |= ObjectCompletion; 97 //if (objectList != NULL && objectList->getSize() == 1) 29 30 /** 31 * @brief standard constructor 32 */ 33 ShellCompletion::ShellCompletion() 34 { } 35 36 37 /** 38 * @brief standard deconstructor 39 */ 40 ShellCompletion::~ShellCompletion () 41 { } 42 43 44 45 /** 46 * @brief autocompletes the Shell's inputLine 47 * @param input the input to complete. 48 * @returns true, if a result was found, false otherwise 49 */ 50 bool ShellCompletion::autoComplete(std::string& input) 51 { 52 const char* completionLine; //< the inputLine we complete. 53 54 long classID; //< the classID retrieved from the Class. 55 const std::list<BaseObject*>* objectList; //< the list of Objects stored in classID 56 bool emptyComplete = false; //< if the completion input is empty string. e.g "" 57 long completeType = NullCompletion; //< the Type we'd like to complete. 58 std::string completeString; //< the string to complete. 59 60 61 PRINTF(5)("AutoComplete on input\n"); 62 this->clearCompletionList(); 63 64 // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object 65 if (input[input.size()-1] == ' ') 66 emptyComplete = true; 67 68 // CREATE INPUTS 69 SubString inputSplits(input, SubString::WhiteSpacesWithComma); 70 71 // What String will be completed 72 if (emptyComplete == true) 73 completeString = ""; 74 else 75 completeString = inputSplits.getString(inputSplits.size()-1); 76 77 // CLASS COMPLETION 78 if (inputSplits.size() == 0) 79 { 80 completeType |= ClassCompletion; 81 completeType |= AliasCompletion; 82 } 83 else if (inputSplits.size() == 1 && emptyComplete == false) 84 { 85 completeType |= ClassCompletion; 86 completeType |= AliasCompletion; 87 } 88 89 // OBJECT/FUNCTION COMPLETIONS 90 else if ((inputSplits.size() == 1 && emptyComplete == true) || 91 (inputSplits.size() == 2 && emptyComplete == false)) 92 { 93 classID = ClassList::StringToID(inputSplits.getString(0)); 94 objectList = ClassList::getList((ClassID)classID); 95 if (classID != CL_NULL) 96 completeType |= ObjectCompletion; 97 //if (objectList != NULL && objectList->getSize() == 1) 98 98 completeType |= FunctionCompletion; 99 } 100 else if ((inputSplits.size() == 2 && emptyComplete == true) || 101 (inputSplits.size() == 3 && emptyComplete == false)) 102 { 103 classID = ClassList::StringToID(inputSplits.getString(0)); 104 if (classID == CL_NULL) 105 return false; 99 } 100 else if ((inputSplits.size() == 2 && emptyComplete == true) || 101 (inputSplits.size() == 3 && emptyComplete == false)) 102 { 103 classID = ClassList::StringToID(inputSplits.getString(0)); 104 if (classID == CL_NULL) 105 return false; 106 else 107 completeType |= FunctionCompletion; 108 } 109 110 if (completeType & ClassCompletion) 111 this->objectComplete(completeString, CL_SHELL_COMMAND_CLASS); 112 if (completeType & ObjectCompletion) 113 this->objectComplete(completeString, classID); 114 if (completeType & FunctionCompletion) 115 this->functionComplete(completeString, inputSplits.getString(0)); 116 if (completeType & AliasCompletion) 117 this->aliasComplete(completeString); 118 119 120 this->generalComplete(input, completeString); 121 return true; 122 } 123 124 /** 125 * @brief autocompletes a className 126 * @param classBegin the Beginning of a String to autoComplete 127 * @return true on success, false otherwise 128 */ 129 bool ShellCompletion::classComplete(const std::string& classBegin) 130 { 131 const std::list<std::string>* clList = ClassList::getClassNames(); 132 if (clList != NULL) 133 { 134 if (!this->addToCompleteList(*clList, classBegin, ClassCompletion)) 135 return false; 136 } 106 137 else 107 completeType |= FunctionCompletion; 108 } 109 110 if (completeType & ClassCompletion) 111 this->objectComplete(completeString, CL_SHELL_COMMAND_CLASS); 112 if (completeType & ObjectCompletion) 113 this->objectComplete(completeString, classID); 114 if (completeType & FunctionCompletion) 115 this->functionComplete(completeString, inputSplits.getString(0)); 116 if (completeType & AliasCompletion) 117 this->aliasComplete(completeString); 118 119 120 this->generalComplete(input, completeString); 121 return true; 138 return false; 139 return true; 140 } 141 142 /** 143 * @brief autocompletes an ObjectName 144 * @param objectBegin the beginning string of a Object 145 * @param classID the ID of the Class to search for. 146 * @return true on success, false otherwise 147 */ 148 bool ShellCompletion::objectComplete(const std::string& objectBegin, long classID) 149 { 150 const std::list<BaseObject*>* boList = ClassList::getList((ClassID)classID); 151 if (boList != NULL) 152 { 153 CompletionType type = ObjectCompletion; 154 if (classID == CL_SHELL_COMMAND_CLASS) 155 type = ClassCompletion; 156 if (!this->addToCompleteList(*boList, objectBegin, type)) 157 return false; 158 } 159 else 160 return false; 161 return true; 162 } 163 164 /** 165 * @brief completes a Function 166 * @param functionBegin the beginning of the function String 167 * @param classID the class' ID to complete the function of 168 */ 169 bool ShellCompletion::functionComplete(const std::string& functionBegin, const std::string& className) 170 { 171 std::list<std::string> fktList; 172 ShellCommandClass::getCommandListOfClass(className, &fktList); 173 //printf("%s\n", boList->firstElement()->getName()); 174 if (!this->addToCompleteList(fktList, functionBegin, FunctionCompletion)) 175 return false; 176 return true; 177 } 178 179 /** 180 * @brief completes an Alias 181 * @param aliasBegin the beginning of the Alias-String to complete 182 * @returns true on succes, false if something went wrong 183 */ 184 bool ShellCompletion::aliasComplete(const std::string& aliasBegin) 185 { 186 std::list<std::string> aliasList; 187 ShellCommandClass::getCommandListOfAlias(&aliasList); 188 //printf("%s\n", boList->firstElement()->getName()); 189 if (!this->addToCompleteList(aliasList, aliasBegin, AliasCompletion)) 190 return false; 191 return true; 192 } 193 194 195 /** 196 * @brief completes the inputline on grounds of an inputList 197 * @param input the Input to complete. 198 * @param begin the String to search in the inputList, and to extend with it. 199 * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::" 200 * @param addBack what should be added at the end of the completion 201 * @param addFront what should be added to the front of one finished completion 202 * @return true if ok, false otherwise 203 */ 204 bool ShellCompletion::generalComplete(std::string& input, 205 const std::string& begin, const std::string& displayAs, 206 const std::string& addBack, const std::string& addFront) 207 { 208 if (completionList.size() == 0) 209 return false; 210 211 CompletionElement addElem = completionList.front(); 212 const std::string& addString = addElem.name; 213 unsigned int addLength = 0; 214 unsigned int inputLenght = begin.size(); 215 216 // Determin the longest Match 217 addLength = addString.size(); 218 219 CompletionType changeType = NullCompletion; 220 std::vector<CompletionElement>::iterator charIT; 221 for (charIT = completionList.begin(); charIT != completionList.end(); charIT++) 222 { 223 if ((*charIT).type != changeType) 224 { 225 if (changeType != NullCompletion) 226 PRINT(0)("\n"); 227 PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type).c_str()); 228 changeType = (*charIT).type; 229 } 230 PRINTF(0)("%s ", (*charIT).name.c_str()); 231 for (unsigned int i = inputLenght; i < addLength; i++) 232 if (addString[i] != (*charIT).name[i]) 233 { 234 addLength = i; 235 // break; 236 } 237 } 238 PRINT(0)("\n"); 239 240 if (addLength >= inputLenght) 241 { 242 std::string adder = addString; 243 adder.resize(addLength); 244 245 input.resize(input.size()-inputLenght); 246 input += adder; 247 248 if (completionList.size() == 1) 249 { 250 if ( addBack != "") 251 input += addBack; 252 input += ' '; 253 } 254 } 255 return true; 256 } 257 258 /** 259 * @brief searches for classes, which beginn with completionBegin 260 * @param inputList the List to parse through 261 * @param completionBegin the beginning string 262 * !! The strings MUST NOT be deleted !! 263 */ 264 bool ShellCompletion::addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, CompletionType type) 265 { 266 unsigned int searchLength = completionBegin.size(); 267 268 std::list<std::string>::const_iterator string; 269 for (string = inputList.begin(); string != inputList.end(); string++) 270 { 271 if ((*string).size() >= searchLength && 272 !nocaseCmp(*string, completionBegin, searchLength)) 273 { 274 printf ("%s\n", (*string).c_str()); 275 CompletionElement newElem; 276 newElem.name = (*string); 277 newElem.type = type; 278 this->completionList.push_back(newElem); 279 } 280 } 281 return true; 282 } 283 284 /** 285 * @brief searches for classes, which beginn with completionBegin 286 * @param inputList the List to parse through 287 * @param completionBegin the beginning string 288 * !! The strings MUST NOT be deleted !! 289 */ 290 bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, CompletionType type) 291 { 292 unsigned int searchLength = completionBegin.size(); 293 294 std::list<BaseObject*>::const_iterator bo; 295 for(bo = inputList.begin(); bo != inputList.end(); bo++) 296 { 297 if ((*bo)->getName() != NULL && 298 strlen((*bo)->getName()) >= searchLength && 299 !nocaseCmp((*bo)->getName(), completionBegin, searchLength)) 300 { 301 CompletionElement newElem; 302 newElem.name = (*bo)->getName(); 303 newElem.type = type; 304 this->completionList.push_back(newElem); 305 } 306 } 307 308 return true; 309 } 310 311 /** 312 * @brief deletes the Completion List. 313 * 314 * This is done at the beginning of each completion-run 315 */ 316 void ShellCompletion::clearCompletionList() 317 { 318 this->completionList.clear(); 319 } 320 321 const std::string& ShellCompletion::typeToString(CompletionType type) 322 { 323 switch (type) 324 { 325 default:// SHELLC_NONE 326 return typeNames[0]; 327 case ClassCompletion: 328 return typeNames[1]; 329 case ObjectCompletion: 330 return typeNames[2]; 331 case FunctionCompletion: 332 return typeNames[3]; 333 case AliasCompletion: 334 return typeNames[4]; 335 } 336 } 337 338 339 const std::string ShellCompletion::typeNames[] = 340 { 341 "error", 342 "class", 343 "object", 344 "function", 345 "alias" 346 }; 347 122 348 } 123 124 /**125 * @brief autocompletes a className126 * @param classBegin the Beginning of a String to autoComplete127 * @return true on success, false otherwise128 */129 bool ShellCompletion::classComplete(const std::string& classBegin)130 {131 const std::list<std::string>* clList = ClassList::getClassNames();132 if (clList != NULL)133 {134 if (!this->addToCompleteList(*clList, classBegin, ClassCompletion))135 return false;136 }137 else138 return false;139 return true;140 }141 142 /**143 * @brief autocompletes an ObjectName144 * @param objectBegin the beginning string of a Object145 * @param classID the ID of the Class to search for.146 * @return true on success, false otherwise147 */148 bool ShellCompletion::objectComplete(const std::string& objectBegin, long classID)149 {150 const std::list<BaseObject*>* boList = ClassList::getList((ClassID)classID);151 if (boList != NULL)152 {153 CompletionType type = ObjectCompletion;154 if (classID == CL_SHELL_COMMAND_CLASS)155 type = ClassCompletion;156 if (!this->addToCompleteList(*boList, objectBegin, type))157 return false;158 }159 else160 return false;161 return true;162 }163 164 /**165 * @brief completes a Function166 * @param functionBegin the beginning of the function String167 * @param classID the class' ID to complete the function of168 */169 bool ShellCompletion::functionComplete(const std::string& functionBegin, const std::string& className)170 {171 std::list<std::string> fktList;172 ShellCommandClass::getCommandListOfClass(className, &fktList);173 //printf("%s\n", boList->firstElement()->getName());174 if (!this->addToCompleteList(fktList, functionBegin, FunctionCompletion))175 return false;176 return true;177 }178 179 /**180 * @brief completes an Alias181 * @param aliasBegin the beginning of the Alias-String to complete182 * @returns true on succes, false if something went wrong183 */184 bool ShellCompletion::aliasComplete(const std::string& aliasBegin)185 {186 std::list<std::string> aliasList;187 ShellCommandClass::getCommandListOfAlias(&aliasList);188 //printf("%s\n", boList->firstElement()->getName());189 if (!this->addToCompleteList(aliasList, aliasBegin, AliasCompletion))190 return false;191 return true;192 }193 194 195 /**196 * @brief completes the inputline on grounds of an inputList197 * @param input the Input to complete.198 * @param begin the String to search in the inputList, and to extend with it.199 * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"200 * @param addBack what should be added at the end of the completion201 * @param addFront what should be added to the front of one finished completion202 * @return true if ok, false otherwise203 */204 bool ShellCompletion::generalComplete(std::string& input,205 const std::string& begin, const std::string& displayAs,206 const std::string& addBack, const std::string& addFront)207 {208 if (completionList.size() == 0)209 return false;210 211 CompletionElement addElem = completionList.front();212 const std::string& addString = addElem.name;213 unsigned int addLength = 0;214 unsigned int inputLenght = begin.size();215 216 // Determin the longest Match217 addLength = addString.size();218 219 CompletionType changeType = NullCompletion;220 std::vector<CompletionElement>::iterator charIT;221 for (charIT = completionList.begin(); charIT != completionList.end(); charIT++)222 {223 if ((*charIT).type != changeType)224 {225 if (changeType != NullCompletion)226 PRINT(0)("\n");227 PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type).c_str());228 changeType = (*charIT).type;229 }230 PRINTF(0)("%s ", (*charIT).name.c_str());231 for (unsigned int i = inputLenght; i < addLength; i++)232 if (addString[i] != (*charIT).name[i])233 {234 addLength = i;235 // break;236 }237 }238 PRINT(0)("\n");239 240 if (addLength >= inputLenght)241 {242 std::string adder = addString;243 adder.resize(addLength);244 245 input.resize(input.size()-inputLenght);246 input += adder;247 248 if (completionList.size() == 1)249 {250 if ( addBack != "")251 input += addBack;252 input += ' ';253 }254 }255 return true;256 }257 258 /**259 * @brief searches for classes, which beginn with completionBegin260 * @param inputList the List to parse through261 * @param completionBegin the beginning string262 * !! The strings MUST NOT be deleted !!263 */264 bool ShellCompletion::addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, CompletionType type)265 {266 unsigned int searchLength = completionBegin.size();267 268 std::list<std::string>::const_iterator string;269 for (string = inputList.begin(); string != inputList.end(); string++)270 {271 if ((*string).size() >= searchLength &&272 !nocaseCmp(*string, completionBegin, searchLength))273 {274 printf ("%s\n", (*string).c_str());275 CompletionElement newElem;276 newElem.name = (*string);277 newElem.type = type;278 this->completionList.push_back(newElem);279 }280 }281 return true;282 }283 284 /**285 * @brief searches for classes, which beginn with completionBegin286 * @param inputList the List to parse through287 * @param completionBegin the beginning string288 * !! The strings MUST NOT be deleted !!289 */290 bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, CompletionType type)291 {292 unsigned int searchLength = completionBegin.size();293 294 std::list<BaseObject*>::const_iterator bo;295 for(bo = inputList.begin(); bo != inputList.end(); bo++)296 {297 if ((*bo)->getName() != NULL &&298 strlen((*bo)->getName()) >= searchLength &&299 !nocaseCmp((*bo)->getName(), completionBegin, searchLength))300 {301 CompletionElement newElem;302 newElem.name = (*bo)->getName();303 newElem.type = type;304 this->completionList.push_back(newElem);305 }306 }307 308 return true;309 }310 311 /**312 * @brief deletes the Completion List.313 *314 * This is done at the beginning of each completion-run315 */316 void ShellCompletion::clearCompletionList()317 {318 this->completionList.clear();319 }320 321 const std::string& ShellCompletion::typeToString(CompletionType type)322 {323 switch (type)324 {325 default:// SHELLC_NONE326 return typeNames[0];327 case ClassCompletion:328 return typeNames[1];329 case ObjectCompletion:330 return typeNames[2];331 case FunctionCompletion:332 return typeNames[3];333 case AliasCompletion:334 return typeNames[4];335 }336 }337 338 339 const std::string ShellCompletion::typeNames[] =340 {341 "error",342 "class",343 "object",344 "function",345 "alias"346 };
Note: See TracChangeset
for help on using the changeset viewer.