X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FTinyCon%2FCompletionConsole.cxx;fp=lib%2FTinyCon%2FCompletionConsole.cxx;h=9c74423cb979a1864352471e738e2c7c625c5895;hb=2e142df11d6f312a2a2b5097b8da73571ed523e8;hp=0000000000000000000000000000000000000000;hpb=61b3659afe961ed248f30e26f9ca8f28fcfafddc;p=cpPlugins.git diff --git a/lib/TinyCon/CompletionConsole.cxx b/lib/TinyCon/CompletionConsole.cxx new file mode 100644 index 0000000..9c74423 --- /dev/null +++ b/lib/TinyCon/CompletionConsole.cxx @@ -0,0 +1,183 @@ +// ========================================================================= +// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co) +// ========================================================================= + +#include +#include +#include +#include +#include + +// ------------------------------------------------------------------------- +TinyCon::CompletionConsole:: +CompletionConsole( ) + : Superclass( ) +{ +} + +// ------------------------------------------------------------------------- +TinyCon::CompletionConsole:: +CompletionConsole( const std::string& prompt ) + : Superclass( prompt ) +{ +} + +// ------------------------------------------------------------------------- +TinyCon::CompletionConsole:: +~CompletionConsole( ) +{ +} + +// ------------------------------------------------------------------------- +TinyCon::CompletionConsole:: +TTrie* TinyCon::CompletionConsole:: +addCommand( const std::string& cmd ) +{ + return( this->m_CommandsTrie.insert( cmd ) ); +} + +// ------------------------------------------------------------------------- +TinyCon::CompletionConsole:: +TTrie* TinyCon::CompletionConsole:: +addCommand( const std::string& cmd, const std::string& opt ) +{ + TTrie* t = this->m_CommandsTrie.find( cmd ).first; + if( t == NULL ) + t = this->m_CommandsTrie.insert( cmd ); + TTrie* s = t->getExtension( ); + if( s == NULL ) + s = t->createExtension( ); + s->insert( opt ); + return( s ); +} + +// ------------------------------------------------------------------------- +TinyCon::CompletionConsole:: +TTrie* TinyCon::CompletionConsole:: +addCommand( const std::string& cmd, Trie* opt ) +{ + TTrie* t = this->m_CommandsTrie.find( cmd ).first; + if( t == NULL ) + t = this->m_CommandsTrie.insert( cmd ); + t->setExtension( opt ); + return( opt ); +} + +// ------------------------------------------------------------------------- +int TinyCon::CompletionConsole:: +trigger( const std::string& s ) +{ + typedef boost::char_separator< char > _TSep; + typedef boost::tokenizer< _TSep > _TTok; + + _TTok tok( s, _TSep( " " ) ); + std::vector< std::string > tokens; + for( _TTok::const_iterator tIt = tok.begin( ); tIt != tok.end( ); ++tIt ) + tokens.push_back( *tIt ); + if( tokens.size( ) > 0 ) + return( this->trigger( tokens ) ); + else + return( 0 ); +} + +// ------------------------------------------------------------------------- +int TinyCon::CompletionConsole:: +hotkeys( char c ) +{ + typedef boost::char_separator< char > _TSep; + typedef boost::tokenizer< _TSep > _TTok; + + if( c == Superclass::TAB ) + { + // Get current line and tokenize it + std::string line; + line.assign( this->m_Buffer.begin( ), this->m_Buffer.end( ) ); + _TTok tok( line, _TSep( " " ) ); + + // Get current trie + const TTrie* t = &( this->m_CommandsTrie ); + _TTok::const_iterator tIt = tok.begin( ); + bool ok = true; + std::string prefix = ""; + while( ok && tIt != tok.end( ) ) + { + if( t != NULL ) + { + std::pair< const TinyCon::Trie*, std::string > it = t->find( *tIt ); + t = it.first; + prefix = it.second; + if( t != NULL ) + { + if( t->IsWord( ) ) + { + t = t->getExtension( ); + prefix = ""; + } + else + ok = false; + } + else + ok = false; + } // end if + tIt++; + } // end for + + // Analize current command + if( t != NULL ) + { + std::vector< std::string > options; + t->words( options ); + if( options.size( ) == 1 ) + { + // Delete line from console + for( int i = 0; i <= line.size( ) + this->m_Prompt.size( ); ++i ) + std::cout << "\b \b"; + + // Update line + line += options[ 0 ] + " "; + } + else if( options.size( ) > 1 ) + { + for( const std::string& o: options ) + std::cout << std::endl << prefix << o; + std::cout << std::endl; + line += this->_prefix( options ); + } // end if + + // Show line + this->setBuffer( line ); + std::cout << this->m_Prompt << line; + } // end if + return( 1 ); + } + else + return( 0 ); +} + +// ------------------------------------------------------------------------- +std::string TinyCon::CompletionConsole:: +_prefix( const std::vector< std::string >& v ) const +{ + if( v.size( ) > 0 ) + { + std::string prefix = v[ 0 ]; + for( unsigned long i = 1; i < v.size( ); ++i ) + { + const char* a = prefix.c_str( ); + const char* b = v[ i ].c_str( ); + std::size_t sa = prefix.size( ); + std::size_t sb = v[ i ].size( ); + ptrdiff_t d; + if( sb < sa ) + d = std::distance( b, std::mismatch( b, b + sb, a ).first ); + else + d = std::distance( a, std::mismatch( a, a + sa, b ).first ); + prefix = v[ i ].substr( 0, std::size_t( d ) ); + } // end for + return( prefix ); + } + else + return( "" ); +} + +// eof - $RCSfile$