From ac43d482c5c23ecbe7d81836b844a2e5d1c3022d Mon Sep 17 00:00:00 2001 From: k1ll Date: Mon, 18 Jul 2011 18:49:38 +0200 Subject: [PATCH] Basic tab-completition seems to be finished. It's working like requested in the old thread. --- apps/openmw/mwgui/console.cpp | 92 +++++++++++++++++++++++++++++++++++ apps/openmw/mwgui/console.hpp | 2 + 2 files changed, 94 insertions(+) diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index baa1309af..31b1b8fb6 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -171,6 +171,22 @@ namespace MWGui MyGUI::KeyCode key, MyGUI::Char _char) { + if( key == MyGUI::KeyCode::Tab) + { + std::vector matches; + listNames(); + command->setCaption(complete( command->getCaption(), matches )); +#if 0 + int i = 0; + for(std::vector::iterator it=matches.begin(); it < matches.end(); it++,i++ ) + { + printOK( *it ); + if( i == 50 ) + break; + } +#endif + } + if(command_history.empty()) return; // Traverse history with up and down arrows @@ -237,4 +253,80 @@ namespace MWGui command->setCaption(""); } + + std::string Console::complete( std::string input, std::vector &matches ) + { + using namespace std; + string output=input; + string tmp=input; + + /* Does the input string contain things that don't have to be completed? If yes erase them. */ + for(string::reverse_iterator rit=tmp.rbegin(); rit < tmp.rend(); rit++) { + if( *rit == ' ' ) { + if( rit == tmp.rbegin() ) + { + tmp.clear(); + break; + } + tmp.erase(tmp.begin(), (rit).base()); + break; + } + } + /* Erase the input from the output string so we can easily append the completed form later. */ + output.erase(output.end()-tmp.length(), output.end()); + + /* Is there still something in the input string? If not just display all commands and return the unchanged input. */ + if( tmp.length() == 0 ) { + matches=mNames; + return input; + } + + /* Iterate through the vector. */ + for(vector::iterator it=mNames.begin(); it < mNames.end();it++) { + bool string_different=false; + + /* Is the string shorter than the input string? If yes skip it. */ + if( (*it).length() < tmp.length() ) + continue; + + /* Is the beginning of the string different from the input string? If yes skip it. */ + for( string::iterator iter=tmp.begin(), iter2=(*it).begin(); iter < tmp.end();iter++, iter2++) { + if( *iter != *iter2 ) { + string_different=true; + break; + } + } + + if( string_different ) + continue; + + /* The beginning of the string matches the input string, save it for the next test. */ + matches.push_back(*it); + } + + /* There are no matches. Return the unchanged input. */ + if( matches.empty() ) + { + return input; + } + + /* Only one match. We're done. */ + if( matches.size() == 1 ) { + return output.append(matches.front() + string(" ")); + } + + /* Check if all matching strings match further than input. If yes complete to this match. */ + int i = tmp.length(); + + for(string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); iter++, i++) { + for(vector::iterator it=matches.begin(); it < matches.end();it++) { + if( (*it)[i] != *iter ) { + /* Append the longest match to the end of the output string*/ + return output.append(matches.front().substr( 0, i)); + } + } + } + /* All keywords match with the shortest. Append it to the output string and return it. */ + return output.append(matches.front()); + } } diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp index d08ac5887..eaf4299be 100644 --- a/apps/openmw/mwgui/console.hpp +++ b/apps/openmw/mwgui/console.hpp @@ -80,6 +80,8 @@ namespace MWGui MyGUI::Char _char); void acceptCommand(MyGUI::EditPtr _sender); + + std::string complete( std::string input, std::vector &matches ); }; } #endif