Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/shell/shell_completion.cc @ 7410

Last change on this file since 7410 was 7409, checked in by bensch, 20 years ago

orxonox/trunk: first CompletionPlugin works almost :)

File size: 10.0 KB
RevLine 
[4744]1/*
[1853]2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
[1855]10
11   ### File Specific:
[5254]12   main-programmer: Benjamin Grauer
[1855]13   co-programmer: ...
[1853]14*/
15
[7374]16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
[1853]17
[5170]18#include "shell_completion.h"
[5639]19#include "shell_command_class.h"
[7388]20#include "shell_completion_plugin.h"
[1853]21
[5194]22#include "shell_command.h"
[5181]23
[5183]24#include "substring.h"
[5178]25#include "class_list.h"
26#include "debug.h"
27
[7374]28namespace OrxShell
29{
[1853]30
[7374]31  /**
32   * @brief standard constructor
33   */
34  ShellCompletion::ShellCompletion()
35  { }
[1853]36
37
[7374]38  /**
39   * @brief standard deconstructor
40   */
41  ShellCompletion::~ShellCompletion ()
42  { }
[5178]43
44
45
[7374]46  /**
47   * @brief autocompletes the Shell's inputLine
[7406]48   * @param input the input to complete, will most possibly be changed.
[7374]49   * @returns true, if a result was found, false otherwise
50   */
51  bool ShellCompletion::autoComplete(std::string& input)
52  {
[7406]53    long classID = CL_NULL;                          //< the classID retrieved from the Class.
54    const std::list<BaseObject*>* objectList = NULL; //< the list of Objects stored in classID's ClassList
55    bool emptyComplete = false;                      //< if the completion input is empty string. e.g ""
56    long completeType = NullCompletion;              //< the Type we'd like to complete.
57    std::string completeString = "";                 //< the string to complete.
[7408]58    unsigned int parameterBegin = 0;                 //< The SubString-entry, the Parameters begin.
[5183]59
[5190]60
[7374]61    PRINTF(5)("AutoComplete on input\n");
62    this->clearCompletionList();
[5185]63
[7374]64    // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object
[7403]65    if (input.empty() || input[input.size()-1] == ' ')
[7374]66      emptyComplete = true;
[5190]67
[7374]68    // CREATE INPUTS
69    SubString inputSplits(input, SubString::WhiteSpacesWithComma);
[5184]70
[7374]71    // What String will be completed
[7403]72    if (!emptyComplete && inputSplits.size() >= 1)
[7374]73      completeString = inputSplits.getString(inputSplits.size()-1);
[5193]74
[7403]75    // CLASS/ALIAS COMPLETION (on first argument)
76    if (inputSplits.size() == 0 || (!emptyComplete && inputSplits.size() == 1))
[7374]77    {
78      completeType |= ClassCompletion;
79      completeType |= AliasCompletion;
80    }
81
82    // OBJECT/FUNCTION COMPLETIONS
[7403]83    else if ((emptyComplete && inputSplits.size() == 1) ||
84              (!emptyComplete && inputSplits.size() == 2))
[7374]85    {
86      classID = ClassList::StringToID(inputSplits.getString(0));
87      objectList = ClassList::getList((ClassID)classID);
88      if (classID != CL_NULL)
89        completeType |= ObjectCompletion;
90      completeType |= FunctionCompletion;
91    }
[7404]92    // Complete the last Function
[7403]93    else if ((emptyComplete && inputSplits.size() == 2 ) ||
94             (!emptyComplete && inputSplits.size() == 3))
[7374]95    {
[7403]96      if (ClassList::exists(inputSplits[0], inputSplits[1]))
[7374]97        completeType |= FunctionCompletion;
98    }
99
[7408]100    // Looking for ParameterCompletions.
101
[7374]102    if (completeType & ClassCompletion)
103      this->objectComplete(completeString, CL_SHELL_COMMAND_CLASS);
104    if (completeType & ObjectCompletion)
105      this->objectComplete(completeString, classID);
106    if (completeType & FunctionCompletion)
[7409]107      this->commandComplete(completeString, inputSplits[0]);
[7374]108    if (completeType & AliasCompletion)
109      this->aliasComplete(completeString);
110
[7408]111    if (completeType == NullCompletion)
112    {
[7409]113      const ShellCommand* sc = ShellCommand::getCommand(inputSplits[2], inputSplits[0]);
114      if (sc != NULL)
115      {
116        std::vector<std::string> test;
117        sc->getCompletorPlugin(0)->addToCompleteList(test, inputSplits[inputSplits.size()-1]);
118      }
[7408]119    }
[7374]120
[7408]121
[7374]122    this->generalComplete(input, completeString);
123    return true;
[5184]124  }
[7374]125
126  /**
127   * @brief autocompletes an ObjectName
128   * @param objectBegin the beginning string of a Object
129   * @param classID the ID of the Class to search for.
130   * @return true on success, false otherwise
131   */
132  bool ShellCompletion::objectComplete(const std::string& objectBegin, long classID)
[5184]133  {
[7374]134    const std::list<BaseObject*>* boList = ClassList::getList((ClassID)classID);
135    if (boList != NULL)
136    {
137      CompletionType type = ObjectCompletion;
138      if (classID == CL_SHELL_COMMAND_CLASS)
139        type = ClassCompletion;
140      if (!this->addToCompleteList(*boList, objectBegin, type))
141        return false;
142    }
143    else
144      return false;
145    return true;
[5184]146  }
[7374]147
148  /**
[7393]149   * @brief completes a Command
150   * @param commandBegin the beginning of the function String
[7374]151   * @param classID the class' ID to complete the function of
152   */
[7393]153  bool ShellCompletion::commandComplete(const std::string& commandBegin, const std::string& className)
[5194]154  {
[7374]155    std::list<std::string> fktList;
[7386]156    ShellCommandClass::getCommandListOfClass(className, fktList);
[7374]157    //printf("%s\n", boList->firstElement()->getName());
[7393]158    if (!this->addToCompleteList(fktList, commandBegin, FunctionCompletion))
[5194]159      return false;
[7374]160    return true;
[5194]161  }
[5184]162
[7374]163  /**
164   * @brief completes an Alias
165   * @param aliasBegin the beginning of the Alias-String to complete
166   * @returns true on succes, false if something went wrong
167   */
168  bool ShellCompletion::aliasComplete(const std::string& aliasBegin)
[5178]169  {
[7374]170    std::list<std::string> aliasList;
[7389]171    ShellCommandAlias::getCommandListOfAlias(aliasList);
[7374]172    //printf("%s\n", boList->firstElement()->getName());
173    if (!this->addToCompleteList(aliasList, aliasBegin, AliasCompletion))
[5178]174      return false;
[7374]175    return true;
[5178]176  }
177
[7374]178
179  /**
180   * @brief completes the inputline on grounds of an inputList
181   * @param input the Input to complete.
182   * @param begin the String to search in the inputList, and to extend with it.
183   * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"
184   * @param addBack what should be added at the end of the completion
185   * @param addFront what should be added to the front of one finished completion
186   * @return true if ok, false otherwise
187   */
188  bool ShellCompletion::generalComplete(std::string& input,
189                                        const std::string& begin, const std::string& displayAs,
190                                        const std::string& addBack, const std::string& addFront)
[5178]191  {
[7374]192    if (completionList.size() == 0)
[5178]193      return false;
194
[7374]195    CompletionElement addElem = completionList.front();
196    const std::string& addString = addElem.name;
197    unsigned int addLength = 0;
198    unsigned int inputLenght = begin.size();
[5178]199
[7374]200    // Determin the longest Match
201    addLength = addString.size();
[5195]202
[7374]203    CompletionType changeType = NullCompletion;
204    std::vector<CompletionElement>::iterator charIT;
205    for (charIT = completionList.begin(); charIT != completionList.end(); charIT++)
206    {
207      if ((*charIT).type != changeType)
208      {
209        if (changeType != NullCompletion)
210          PRINT(0)("\n");
211        PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type).c_str());
212        changeType = (*charIT).type;
213      }
214      PRINTF(0)("%s ", (*charIT).name.c_str());
215      for (unsigned int i = inputLenght; i < addLength; i++)
216        if (addString[i] != (*charIT).name[i])
217        {
218          addLength = i;
219          //       break;
220        }
221    }
222    PRINT(0)("\n");
[5195]223
[7374]224    if (addLength >= inputLenght)
225    {
226      std::string adder = addString;
227      adder.resize(addLength);
[5178]228
[7374]229      input.resize(input.size()-inputLenght);
230      input += adder;
[5178]231
[7374]232      if (completionList.size() == 1)
233      {
234        if ( addBack != "")
235          input += addBack;
236        input += ' ';
237      }
238    }
239    return true;
240  }
[5779]241
[7374]242  /**
243   * @brief searches for classes, which beginn with completionBegin
244   * @param inputList the List to parse through
245   * @param completionBegin the beginning string
246   * !! The strings MUST NOT be deleted !!
247   */
248  bool ShellCompletion::addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, CompletionType type)
[5178]249  {
[7374]250    unsigned int searchLength = completionBegin.size();
251
252    std::list<std::string>::const_iterator string;
253    for (string = inputList.begin(); string != inputList.end(); string++)
[5245]254    {
[7374]255      if ((*string).size() >= searchLength &&
256          !nocaseCmp(*string, completionBegin, searchLength))
[5185]257      {
[7374]258        CompletionElement newElem;
259        newElem.name = (*string);
260        newElem.type = type;
261        this->completionList.push_back(newElem);
[5185]262      }
[7374]263    }
264    return true;
[5178]265  }
266
[7374]267  /**
268   * @brief searches for classes, which beginn with completionBegin
269   * @param inputList the List to parse through
270   * @param completionBegin the beginning string
271   * !! The strings MUST NOT be deleted !!
272   */
273  bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, CompletionType type)
[5178]274  {
[7374]275    unsigned int searchLength = completionBegin.size();
[5178]276
[7374]277    std::list<BaseObject*>::const_iterator bo;
278    for(bo = inputList.begin(); bo != inputList.end(); bo++)
[5182]279    {
[7374]280      if ((*bo)->getName() != NULL &&
281          strlen((*bo)->getName()) >= searchLength &&
282          !nocaseCmp((*bo)->getName(), completionBegin, searchLength))
283      {
284        CompletionElement newElem;
285        newElem.name = (*bo)->getName();
286        newElem.type = type;
287        this->completionList.push_back(newElem);
288      }
[5182]289    }
[7374]290
291    return true;
[5178]292  }
293
[7374]294  /**
295   * @brief deletes the Completion List.
296   *
297   * This is done at the beginning of each completion-run
298   */
299  void ShellCompletion::clearCompletionList()
[5178]300  {
[7374]301    this->completionList.clear();
[5178]302  }
303
[7374]304  const std::string& ShellCompletion::typeToString(CompletionType type)
[5178]305  {
[7374]306    switch (type)
[5178]307    {
[7374]308      default:// SHELLC_NONE
309        return typeNames[0];
310      case  ClassCompletion:
311        return typeNames[1];
312      case ObjectCompletion:
313        return typeNames[2];
314      case FunctionCompletion:
315        return typeNames[3];
316      case AliasCompletion:
317        return typeNames[4];
[5178]318    }
319  }
320
[5187]321
[7374]322  const std::string ShellCompletion::typeNames[] =
323    {
324      "error",
325      "class",
326      "object",
327      "function",
328      "alias"
329    };
[5245]330
331}
Note: See TracBrowser for help on using the repository browser.