]> Creatis software - cpPlugins.git/blobdiff - lib/TinyCon/CompletionConsole.cxx
Moved to version 1.0
[cpPlugins.git] / lib / TinyCon / CompletionConsole.cxx
diff --git a/lib/TinyCon/CompletionConsole.cxx b/lib/TinyCon/CompletionConsole.cxx
new file mode 100644 (file)
index 0000000..9c74423
--- /dev/null
@@ -0,0 +1,183 @@
+// =========================================================================
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// =========================================================================
+
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <boost/tokenizer.hpp>
+#include <TinyCon/CompletionConsole.h>
+
+// -------------------------------------------------------------------------
+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$