]> Creatis software - cpPlugins.git/blob - lib/TinyCon/CompletionConsole.cxx
Moved to version 1.0
[cpPlugins.git] / lib / TinyCon / CompletionConsole.cxx
1 // =========================================================================
2 // @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
3 // =========================================================================
4
5 #include <iostream>
6 #include <iterator>
7 #include <sstream>
8 #include <boost/tokenizer.hpp>
9 #include <TinyCon/CompletionConsole.h>
10
11 // -------------------------------------------------------------------------
12 TinyCon::CompletionConsole::
13 CompletionConsole( )
14   : Superclass( )
15 {
16 }
17
18 // -------------------------------------------------------------------------
19 TinyCon::CompletionConsole::
20 CompletionConsole( const std::string& prompt )
21   : Superclass( prompt )
22 {
23 }
24
25 // -------------------------------------------------------------------------
26 TinyCon::CompletionConsole::
27 ~CompletionConsole( )
28 {
29 }
30
31 // -------------------------------------------------------------------------
32 TinyCon::CompletionConsole::
33 TTrie* TinyCon::CompletionConsole::
34 addCommand( const std::string& cmd )
35 {
36   return( this->m_CommandsTrie.insert( cmd ) );
37 }
38
39 // -------------------------------------------------------------------------
40 TinyCon::CompletionConsole::
41 TTrie* TinyCon::CompletionConsole::
42 addCommand( const std::string& cmd, const std::string& opt )
43 {
44   TTrie* t = this->m_CommandsTrie.find( cmd ).first;
45   if( t == NULL )
46     t = this->m_CommandsTrie.insert( cmd );
47   TTrie* s = t->getExtension( );
48   if( s == NULL )
49     s = t->createExtension( );
50   s->insert( opt );
51   return( s );
52 }
53
54 // -------------------------------------------------------------------------
55 TinyCon::CompletionConsole::
56 TTrie* TinyCon::CompletionConsole::
57 addCommand( const std::string& cmd, Trie* opt )
58 {
59   TTrie* t = this->m_CommandsTrie.find( cmd ).first;
60   if( t == NULL )
61     t = this->m_CommandsTrie.insert( cmd );
62   t->setExtension( opt );
63   return( opt );
64 }
65
66 // -------------------------------------------------------------------------
67 int TinyCon::CompletionConsole::
68 trigger( const std::string& s )
69 {
70   typedef boost::char_separator< char > _TSep;
71   typedef boost::tokenizer< _TSep > _TTok;
72
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 ) );
79   else
80     return( 0 );
81 }
82
83 // -------------------------------------------------------------------------
84 int TinyCon::CompletionConsole::
85 hotkeys( char c )
86 {
87   typedef boost::char_separator< char > _TSep;
88   typedef boost::tokenizer< _TSep > _TTok;
89
90   if( c == Superclass::TAB )
91   {
92     // Get current line and tokenize it
93     std::string line;
94     line.assign( this->m_Buffer.begin( ), this->m_Buffer.end( ) );
95     _TTok tok( line, _TSep( " " ) );
96
97     // Get current trie
98     const TTrie* t = &( this->m_CommandsTrie );
99     _TTok::const_iterator tIt = tok.begin( );
100     bool ok = true;
101     std::string prefix = "";
102     while( ok && tIt != tok.end( ) )
103     {
104       if( t != NULL )
105       {
106         std::pair< const TinyCon::Trie*, std::string > it = t->find( *tIt );
107         t = it.first;
108         prefix = it.second;
109         if( t != NULL )
110         {
111           if( t->IsWord( ) )
112           {
113             t = t->getExtension( );
114             prefix = "";
115           }
116           else
117             ok = false;
118         }
119         else
120           ok = false;
121       } // end if
122       tIt++;
123     } // end for
124
125     // Analize current command
126     if( t != NULL )
127     {
128       std::vector< std::string > options;
129       t->words( options );
130       if( options.size( ) == 1 )
131       {
132         // Delete line from console
133         for( int i = 0; i <= line.size( ) + this->m_Prompt.size( ); ++i )
134           std::cout << "\b \b";
135
136         // Update line
137         line += options[ 0 ] +  " ";
138       }
139       else if( options.size( ) > 1 )
140       {
141         for( const std::string& o: options )
142           std::cout << std::endl << prefix << o;
143         std::cout << std::endl;
144         line += this->_prefix( options );
145       } // end if
146
147       // Show line
148       this->setBuffer( line );
149       std::cout << this->m_Prompt << line;
150     } // end if
151     return( 1 );
152   }
153   else
154     return( 0 );
155 }
156
157 // -------------------------------------------------------------------------
158 std::string TinyCon::CompletionConsole::
159 _prefix( const std::vector< std::string >& v ) const
160 {
161   if( v.size( ) > 0 )
162   {
163     std::string prefix = v[ 0 ];
164     for( unsigned long i = 1; i < v.size( ); ++i )
165     {
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( );
170       ptrdiff_t d;
171       if( sb < sa )
172         d = std::distance( b, std::mismatch( b, b + sb, a ).first );
173       else
174         d = std::distance( a, std::mismatch( a, a + sa, b ).first );
175       prefix = v[ i ].substr( 0, std::size_t( d ) );
176     } // end for
177     return( prefix );
178   }
179   else
180     return( "" );
181 }
182
183 // eof - $RCSfile$