1 // =========================================================================
2 // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
3 // =========================================================================
8 #include <boost/tokenizer.hpp>
9 #include <TinyCon/CompletionConsole.h>
11 // -------------------------------------------------------------------------
12 TinyCon::CompletionConsole::
18 // -------------------------------------------------------------------------
19 TinyCon::CompletionConsole::
20 CompletionConsole( const std::string& prompt )
21 : Superclass( prompt )
25 // -------------------------------------------------------------------------
26 TinyCon::CompletionConsole::
31 // -------------------------------------------------------------------------
32 TinyCon::CompletionConsole::
33 TTrie* TinyCon::CompletionConsole::
34 addCommand( const std::string& cmd )
36 return( this->m_CommandsTrie.insert( cmd ) );
39 // -------------------------------------------------------------------------
40 TinyCon::CompletionConsole::
41 TTrie* TinyCon::CompletionConsole::
42 addCommand( const std::string& cmd, const std::string& opt )
44 TTrie* t = this->m_CommandsTrie.find( cmd ).first;
46 t = this->m_CommandsTrie.insert( cmd );
47 TTrie* s = t->getExtension( );
49 s = t->createExtension( );
54 // -------------------------------------------------------------------------
55 TinyCon::CompletionConsole::
56 TTrie* TinyCon::CompletionConsole::
57 addCommand( const std::string& cmd, Trie* opt )
59 TTrie* t = this->m_CommandsTrie.find( cmd ).first;
61 t = this->m_CommandsTrie.insert( cmd );
62 t->setExtension( opt );
66 // -------------------------------------------------------------------------
67 int TinyCon::CompletionConsole::
68 trigger( const std::string& s )
70 typedef boost::char_separator< char > _TSep;
71 typedef boost::tokenizer< _TSep > _TTok;
73 _TTok tok( s, _TSep( " " ) );
74 std::vector< std::string > tokens;
75 for( _TTok::const_iterator tIt = tok.begin( ); tIt != tok.end( ); ++tIt )
76 tokens.push_back( *tIt );
77 if( tokens.size( ) > 0 )
78 return( this->trigger( tokens ) );
83 // -------------------------------------------------------------------------
84 int TinyCon::CompletionConsole::
87 typedef boost::char_separator< char > _TSep;
88 typedef boost::tokenizer< _TSep > _TTok;
90 if( c == Superclass::TAB )
92 // Get current line and tokenize it
94 line.assign( this->m_Buffer.begin( ), this->m_Buffer.end( ) );
95 _TTok tok( line, _TSep( " " ) );
98 const TTrie* t = &( this->m_CommandsTrie );
99 _TTok::const_iterator tIt = tok.begin( );
101 std::string prefix = "";
102 while( ok && tIt != tok.end( ) )
106 std::pair< const TinyCon::Trie*, std::string > it = t->find( *tIt );
113 t = t->getExtension( );
125 // Analize current command
128 std::vector< std::string > options;
130 if( options.size( ) == 1 )
132 // Delete line from console
133 for( int i = 0; i <= line.size( ) + this->m_Prompt.size( ); ++i )
134 std::cout << "\b \b";
137 line += options[ 0 ] + " ";
139 else if( options.size( ) > 1 )
141 for( const std::string& o: options )
142 std::cout << std::endl << prefix << o;
143 std::cout << std::endl;
144 line += this->_prefix( options );
148 this->setBuffer( line );
149 std::cout << this->m_Prompt << line;
157 // -------------------------------------------------------------------------
158 std::string TinyCon::CompletionConsole::
159 _prefix( const std::vector< std::string >& v ) const
163 std::string prefix = v[ 0 ];
164 for( unsigned long i = 1; i < v.size( ); ++i )
166 const char* a = prefix.c_str( );
167 const char* b = v[ i ].c_str( );
168 std::size_t sa = prefix.size( );
169 std::size_t sb = v[ i ].size( );
172 d = std::distance( b, std::mismatch( b, b + sb, a ).first );
174 d = std::distance( a, std::mismatch( a, a + sa, b ).first );
175 prefix = v[ i ].substr( 0, std::size_t( d ) );